Добавлен новый модуль демонстрации объектно-ориентированного подхода к созданию анимации спиннера в консоли

This commit is contained in:
Alexander Zhirov 2025-05-16 01:35:01 +03:00
parent 45f2985d21
commit 16c77dc28d
Signed by: alexander
GPG key ID: C8D8BE544A27C511
6 changed files with 129 additions and 11 deletions

View file

@ -6,13 +6,14 @@
```sh ```sh
d-examples d-examples
├── common Общего назначения ├── common # Общего назначения
│ ├── isexists Проверяет наличие исполняемого файла в директориях,указанных в переменной окружения PATH │ ├── isexists # Проверяет наличие исполняемого файла в директориях,указанных в переменной окружения PATH
│ └── splittext Форматирует массив строк, разбивая их на строки указанной длины │ └── splittext # Форматирует массив строк, разбивая их на строки указанной длины
├── ncurses Использование библиотеки ncurses ├── ncurses # Использование библиотеки ncurses
│ ├── menu Интерактивное консольное меню │ ├── menu # Интерактивное консольное меню
│ └── password Консольное окно для ввода пароля │ └── password # Консольное окно для ввода пароля
└── shell Запуск команд в shell └── shell # Запуск команд в shell
├── pipe Чтение выходных данных на примере ip ├── pipe # Чтение выходных данных на примере ip
└── spinner Эмуляция статуса выполнения процесса ├── spinner # Эмуляция статуса выполнения процесса
└── ospinner # Демонстрирует объектно-ориентированный подход к созданию анимации спиннера в консоли
``` ```

View file

@ -20,6 +20,8 @@ int main(string[] args)
.add(new Command("shell", "Запуск команд в shell") .add(new Command("shell", "Запуск команд в shell")
.add(new Command("pipe", "Чтение выходных данных на примере ip")) .add(new Command("pipe", "Чтение выходных данных на примере ip"))
.add(new Command("spinner", "Эмуляция статуса выполнения процесса")) .add(new Command("spinner", "Эмуляция статуса выполнения процесса"))
.add(new Command("ospinner",
"Демонстрирует объектно-ориентированный подход к созданию анимации спиннера в консоли"))
) )
.parse(args); .parse(args);
@ -34,7 +36,8 @@ int main(string[] args)
}) })
.on("shell", (shell) { shell .on("shell", (shell) { shell
.on("pipe", (pipe) { pipeShell(); }) .on("pipe", (pipe) { pipeShell(); })
.on("spinner", (loading) { spinnerShell(); }); .on("spinner", (spinner) { spinnerShell(); })
.on("ospinner", (ospinner) { oSpinnerShell(); });
}); });
return EXIT_SUCCESS; return EXIT_SUCCESS;

View file

@ -7,3 +7,7 @@
## spinner ## spinner
Функция `spinnerShell` создаёт анимацию спиннера в консоли, используя брайлевские символы для имитации процесса обработки. Устанавливает обработчик сигнала `Ctrl+C` для корректного завершения с восстановлением курсора. Выполняет цикл с задержкой 100 мс, отображая вращающийся символ, и завершает выполнение с выводом "Done!". Использует модули `std.stdio`, `core.thread`, `core.time` и функции C для работы с сигналами и выводом. Функция `spinnerShell` создаёт анимацию спиннера в консоли, используя брайлевские символы для имитации процесса обработки. Устанавливает обработчик сигнала `Ctrl+C` для корректного завершения с восстановлением курсора. Выполняет цикл с задержкой 100 мс, отображая вращающийся символ, и завершает выполнение с выводом "Done!". Использует модули `std.stdio`, `core.thread`, `core.time` и функции C для работы с сигналами и выводом.
## ospinner
Функция `oSpinnerShell` демонстрирует объектно-ориентированный подход к созданию анимации спиннера в консоли. Использует абстрактный класс `Command` для выполнения задач с анимацией спиннера (брайлевские символы). Класс `LongRunningCommand` имитирует длительную задачу (5 секунд). Обработчик `Ctrl+C` завершает выполнение с восстановлением курсора. Анимация отображает имя команды и сообщение, завершаясь выводом "Done!". Использует модули `std.stdio`, `core.thread`, `core.time`, `core.stdc.signal`, `core.stdc.stdio`, `core.stdc.stdlib`.

View file

@ -0,0 +1,109 @@
module examples.shell.ospinner;
import std.stdio;
import core.thread;
import core.time;
import core.stdc.signal : signal, SIGINT;
import core.stdc.stdio : fprintf;
import core.stdc.stdlib : exit;
// Обработчик сигнала Ctrl+C
extern (C) void handleCtrlC(int sig) nothrow @nogc
{
// Используем fprintf для вывода в stderr
fprintf(core.stdc.stdio.stderr, "\033[?25h\r\033[KInterrupted!\n");
exit(0);
}
// Абстрактный базовый класс для команд
private abstract class Command
{
private string message = "Processing..."; // Сообщение для спиннера
private string name = "Default command"; // Наименование команды
private immutable dchar[] spinner = [
'⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'
]; // Символы спиннера
// Абстрактный метод, который должны реализовать наследники
protected abstract void execute();
this(string commandName)
{
name = commandName;
}
// Метод для запуска команды с анимацией спиннера
final void run()
{
ulong i = 0;
bool taskCompleted = false;
// Создаём поток для выполнения команды
auto worker = new Thread({
try
{
execute(); // Выполняем логику команды
}
catch (Exception e)
{
stderr.writefln("Error: %s", e.msg);
}
taskCompleted = true;
});
// Скрываем курсор
write("\033[?25l");
stdout.flush();
// Запускаем задачу
worker.start();
// Цикл анимации спиннера
while (!taskCompleted)
{
writef("\r%s: %s %c", name, message, spinner[i]);
stdout.flush();
i = (i + 1) % spinner.length;
Thread.sleep(dur!("msecs")(100));
}
// Ждём завершения потока
worker.join();
// Восстанавливаем курсор и очищаем строку
writef("\033[?25h\r\033[K%s: Done!\n", name);
}
// Метод для установки пользовательского сообщения
void setMessage(string msg)
{
message = msg;
}
}
// Пример команды с выводом
private class LongRunningCommand : Command
{
this(string commandName)
{
super(commandName);
}
override void execute()
{
Thread.sleep(dur!("seconds")(5)); // Имитация работы
}
}
void oSpinnerShell()
{
// Устанавливаем обработчик для SIGINT (Ctrl+C)
signal(SIGINT, &handleCtrlC);
// Создаём команду
auto cmd = new LongRunningCommand("Test");
cmd.setMessage("Working on task...");
writeln("Running with spinner:");
cmd.run();
}

View file

@ -2,3 +2,4 @@ module examples.shell;
public import examples.shell.pipe; public import examples.shell.pipe;
public import examples.shell.spinner; public import examples.shell.spinner;
public import examples.shell.ospinner;

View file

@ -1,3 +1,3 @@
module examples.version_; module examples.version_;
enum examplesVersion = "0.4.0"; enum examplesVersion = "0.5.0";