Добавлен новый модуль демонстрации объектно-ориентированного подхода к созданию анимации спиннера в консоли
This commit is contained in:
parent
45f2985d21
commit
16c77dc28d
6 changed files with 129 additions and 11 deletions
19
README.md
19
README.md
|
@ -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 # Демонстрирует объектно-ориентированный подход к созданию анимации спиннера в консоли
|
||||||
```
|
```
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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`.
|
||||||
|
|
109
source/examples/shell/ospinner.d
Normal file
109
source/examples/shell/ospinner.d
Normal 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();
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module examples.version_;
|
module examples.version_;
|
||||||
|
|
||||||
enum examplesVersion = "0.4.0";
|
enum examplesVersion = "0.5.0";
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue