#include "scene.hpp" #include "engine/escape.hpp" #include "util/color.hpp" #include #include #include #include #include Scene::Scene( IMatrixFactory matrix_factory, std::shared_ptr cursor_controller) noexcept : _matrix(matrix_factory(size() - Bounds({.width = 0U, .height = 1U}))), _cursor_controller(std::move(cursor_controller)), _is_shown(false) { _matrix->fill(' '); } void Scene::enter() noexcept { if (_is_shown || _original_termios != nullptr) { return; } // Enable alternative buffer fmt::print(ENABLE_ALT_BUFFER, fmt::arg("esc", ESC)); std::cout.flush(); // Create a backup of the current terminal state _original_termios = std::make_shared(); tcgetattr(STDIN_FILENO, _original_termios.get()); auto new_termios = termios(*_original_termios); // Set the local mode flags of the new termios structure // // The following flags are disabled: // ECHO - Echoing input characters // ICANON - Canonical mode (line by line input) // ISIG - Generate the corresponding signals for the characters // INTR, QUIT, SUSP and DSUSP new_termios.c_lflag &= static_cast(~(ECHO | ICANON | ISIG)); // Set a new terminal state tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_termios); _is_shown = true; } void Scene::leave() noexcept { if (!_is_shown || _original_termios == nullptr) { return; } // Disable alternative buffer fmt::print(DISABLE_ALT_BUFFER, fmt::arg("esc", ESC)); std::cout.flush(); // Restore the original terminal state tcsetattr(STDIN_FILENO, TCSAFLUSH, _original_termios.get()); _original_termios = nullptr; _is_shown = false; } auto Scene::size() const noexcept -> Bounds { winsize window_size = {}; // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) ioctl(0, TIOCGWINSZ, &window_size); return Bounds({window_size.ws_col, window_size.ws_row}); } auto Scene::get_matrix() const noexcept -> const std::shared_ptr> & { return _matrix; }