Improve ScreenInteractive.

This commit is contained in:
ArthurSonzogni 2020-03-23 09:23:57 +01:00
parent a402cb4fbb
commit 9ca8d41afc

View File

@ -25,6 +25,7 @@ static const char* SHOW_CURSOR = "\x1B[?25h";
static const char* DISABLE_LINE_WRAP = "\x1B[7l"; static const char* DISABLE_LINE_WRAP = "\x1B[7l";
static const char* ENABLE_LINE_WRAP = "\x1B[7h"; static const char* ENABLE_LINE_WRAP = "\x1B[7h";
using SignalHandler = void(int);
std::stack<std::function<void()>> on_exit_functions; std::stack<std::function<void()>> on_exit_functions;
void OnExit(int signal) { void OnExit(int signal) {
while (!on_exit_functions.empty()) { while (!on_exit_functions.empty()) {
@ -36,6 +37,11 @@ void OnExit(int signal) {
quick_exit(SIGINT); quick_exit(SIGINT);
} }
auto install_signal_handler = [](int sig, SignalHandler handler) {
auto old_signal_handler = std::signal(sig, handler);
on_exit_functions.push([&]() { std::signal(sig, old_signal_handler); });
};
std::function<void()> on_resize = []{}; std::function<void()> on_resize = []{};
void OnResize(int /* signal */) { void OnResize(int /* signal */) {
on_resize(); on_resize();
@ -87,9 +93,9 @@ void ScreenInteractive::EventLoop(Component* component) {
void ScreenInteractive::Loop(Component* component) { void ScreenInteractive::Loop(Component* component) {
// Install a SIGINT handler and restore the old handler on exit. // Install a SIGINT handler and restore the old handler on exit.
auto old_sigint_handler = std::signal(SIGINT, OnExit); install_signal_handler(SIGINT, OnExit);
on_exit_functions.push( // Handle resize.
[old_sigint_handler]() { std::signal(SIGINT, old_sigint_handler); }); install_signal_handler(SIGWINCH, OnResize);
// Save the old terminal configuration and restore it on exit. // Save the old terminal configuration and restore it on exit.
struct termios terminal_configuration_old; struct termios terminal_configuration_old;
@ -120,11 +126,7 @@ void ScreenInteractive::Loop(Component* component) {
std::cout << std::endl; std::cout << std::endl;
}); });
// Handle resize. // Spawn a thread. It will listen for new characters being typed.
on_resize = [&] { PostEvent(Event::Special({0})); };
auto old_sigwinch_handler = std::signal(SIGWINCH, OnResize);
on_exit_functions.push([&] { std::signal(SIGWINCH, old_sigwinch_handler); });
std::thread read_char([this] { std::thread read_char([this] {
while (!quit_) { while (!quit_) {
auto event = Event::GetEvent([] { return (char)getchar(); }); auto event = Event::GetEvent([] { return (char)getchar(); });
@ -132,6 +134,7 @@ void ScreenInteractive::Loop(Component* component) {
} }
}); });
// The main loop.
while (!quit_) { while (!quit_) {
std::cout << reset_cursor_position << ResetPosition(); std::cout << reset_cursor_position << ResetPosition();
Draw(component); Draw(component);