diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/bootstrap.cpp | 45 | ||||
-rw-r--r-- | src/commands/toggle_pause.cpp | 22 | ||||
-rw-r--r-- | src/commands/toggle_pause.hpp | 20 | ||||
-rw-r--r-- | src/engine/engine.cpp | 12 | ||||
-rw-r--r-- | src/engine/graphics/scene.cpp | 20 | ||||
-rw-r--r-- | src/engine/graphics/scene.hpp | 6 | ||||
-rw-r--r-- | src/engine/user/input.hpp | 4 | ||||
-rw-r--r-- | src/game/cursor_listener.cpp | 14 | ||||
-rw-r--r-- | src/game/cursor_listener.hpp | 19 | ||||
-rw-r--r-- | src/game/game.cpp | 26 | ||||
-rw-r--r-- | src/game/game.hpp | 21 | ||||
-rw-r--r-- | src/game/generation_tracker.cpp | 18 | ||||
-rw-r--r-- | src/game/generation_tracker.hpp | 22 | ||||
-rw-r--r-- | src/game/status_updater.cpp | 25 | ||||
-rw-r--r-- | src/game/status_updater.hpp | 24 | ||||
-rw-r--r-- | src/game/statusline.cpp | 102 | ||||
-rw-r--r-- | src/game/statusline.hpp | 41 | ||||
-rw-r--r-- | src/interfaces/game.hpp | 6 | ||||
-rw-r--r-- | src/interfaces/generation_tracker.hpp | 18 | ||||
-rw-r--r-- | src/interfaces/scene.hpp | 2 | ||||
-rw-r--r-- | src/interfaces/status_updater.hpp | 19 | ||||
-rw-r--r-- | src/interfaces/statusline.hpp | 27 |
23 files changed, 437 insertions, 81 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c603b37..4aa4a40 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,7 +15,9 @@ file(GLOB SOURCES argument_parser.cpp util/color.cpp game/game.cpp - game/cursor_listener.cpp + game/status_updater.cpp + game/generation_tracker.cpp + game/statusline.cpp engine/engine.cpp engine/data/vector2.cpp engine/data/bounds.cpp @@ -29,6 +31,7 @@ file(GLOB SOURCES commands/insert_cell.cpp commands/move_cursor.cpp commands/quit.cpp + commands/toggle_pause.cpp DI/object_type.cpp) add_executable(${PROJECT_NAME} ${SOURCES}) diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp index 713991d..8dec609 100644 --- a/src/bootstrap.cpp +++ b/src/bootstrap.cpp @@ -5,10 +5,13 @@ #include "interfaces/cursor.hpp" #include "interfaces/engine.hpp" #include "interfaces/game.hpp" +#include "interfaces/generation_tracker.hpp" #include "interfaces/input.hpp" #include "interfaces/matrix.hpp" #include "interfaces/randomization.hpp" #include "interfaces/scene.hpp" +#include "interfaces/status_updater.hpp" +#include "interfaces/statusline.hpp" #include "interfaces/window.hpp" // Implementations @@ -22,6 +25,9 @@ #include "engine/user/cursor.hpp" #include "engine/user/input.hpp" #include "game/game.hpp" +#include "game/generation_tracker.hpp" +#include "game/status_updater.hpp" +#include "game/statusline.hpp" #include "randomization/generator.hpp" #include "randomization/seed_generator.hpp" @@ -42,11 +48,21 @@ Container bootstrap() noexcept container.bind<IWindow>().to<Window>(); container.bind<IGameFactory>().to_factory(normalize_lambda( - [](const std::shared_ptr<IWindow> &window, const std::shared_ptr<IScene> &scene, - const std::shared_ptr<ICursorController> &cursor_controller) + [&container](const std::shared_ptr<IWindow> &window, + const std::shared_ptr<IScene> &scene, + const std::shared_ptr<ICursorController> &cursor_controller) { + auto statusline = + container.get<IStatusLineFactory>()(cursor_controller, window); + + auto generation_tracker = container.get<IGenerationTrackerFactory>()(true); + + auto status_updater = + container.get<IStatusUpdaterFactory>()(statusline, generation_tracker); + return std::dynamic_pointer_cast<IGame>( - std::make_shared<Game>(window, scene, cursor_controller)); + std::make_shared<Game>(window, scene, cursor_controller, statusline, + generation_tracker, status_updater)); })); container.bind<IRandomNumberGeneratorFactory>().to_factory( @@ -79,5 +95,28 @@ Container bootstrap() noexcept cursor_controller, window)); })); + container.bind<IStatusLineFactory>().to_factory( + [](const std::shared_ptr<ICursorController> &cursor_controller, + const std::shared_ptr<IWindow> &window) + { + return std::dynamic_pointer_cast<IStatusLine>( + std::make_shared<StatusLine>(cursor_controller, window)); + }); + + container.bind<IStatusUpdaterFactory>().to_factory( + [](const std::shared_ptr<IStatusLine> &status_line, + const std::shared_ptr<IGenerationTracker> &generation_tracker) + { + return std::dynamic_pointer_cast<IStatusUpdater>( + std::make_shared<StatusUpdater>(status_line, generation_tracker)); + }); + + container.bind<IGenerationTrackerFactory>().to_factory( + [](bool is_paused) + { + return std::dynamic_pointer_cast<IGenerationTracker>( + std::make_shared<GenerationTracker>(is_paused)); + }); + return container; } diff --git a/src/commands/toggle_pause.cpp b/src/commands/toggle_pause.cpp new file mode 100644 index 0000000..8a3f44c --- /dev/null +++ b/src/commands/toggle_pause.cpp @@ -0,0 +1,22 @@ +#include "toggle_pause.hpp" + +#include <fmt/core.h> +#include <utility> + +TogglePauseCommand::TogglePauseCommand( + std::shared_ptr<IGenerationTracker> generation_tracker, + std::shared_ptr<IStatusLine> statusline) noexcept + : _generation_tracker(std::move(generation_tracker)), + _statusline(std::move(statusline)) +{ +} + +void TogglePauseCommand::execute() noexcept +{ + auto onoff = !_generation_tracker->get_is_paused(); + + _generation_tracker->set_is_paused(onoff); + + _statusline->set_status(StatusLineSection::B, + fmt::format("Paused: {}", onoff ? "yes" : "no")); +} diff --git a/src/commands/toggle_pause.hpp b/src/commands/toggle_pause.hpp new file mode 100644 index 0000000..4e05323 --- /dev/null +++ b/src/commands/toggle_pause.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "interfaces/command.hpp" +#include "interfaces/generation_tracker.hpp" +#include "interfaces/statusline.hpp" + +#include <memory> + +class TogglePauseCommand : public ICommand +{ +public: + explicit TogglePauseCommand(std::shared_ptr<IGenerationTracker> generation_tracker, + std::shared_ptr<IStatusLine> statusline) noexcept; + + void execute() noexcept override; + +private: + std::shared_ptr<IGenerationTracker> _generation_tracker; + std::shared_ptr<IStatusLine> _statusline; +}; diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index e463f28..c988c33 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2,6 +2,7 @@ #include "util/function.hpp" +#include <thread> #include <utility> CLIGameEngine::CLIGameEngine(IGameFactory game_factory, ISceneFactory scene_factory, @@ -38,7 +39,16 @@ void CLIGameEngine::start() noexcept _configure_input(game->get_input_config()); - _input_handler->listen(); + std::thread listen_input_thread(normalize_lambda( + [this]() + { + _input_handler->listen(); + })); + + while (true) + { + game->on_update(); + } } void CLIGameEngine::_configure_input( diff --git a/src/engine/graphics/scene.cpp b/src/engine/graphics/scene.cpp index 4e382fe..24c174f 100644 --- a/src/engine/graphics/scene.cpp +++ b/src/engine/graphics/scene.cpp @@ -45,26 +45,6 @@ void Scene::leave() noexcept _is_shown = false; } -void Scene::write_status(const std::string_view &str) noexcept -{ - const auto previous_position = _cursor_controller->where(); - - const auto window_size = _window->size(); - - _cursor_controller->move_to( - Vector2({.x = 2, .y = static_cast<Vector2::Value>(window_size.get_height())}), - true); - - auto background_color = get_background_esc_seq(STATUSBAR_COLOR); - - fmt::print("{}", background_color); - fmt::print(ERASE_ENTIRE_LINE, fmt::arg("esc", ESC)); - fmt::print(fmt::runtime(str.data())); - fmt::print(RESET_ALL_MODES, fmt::arg("esc", ESC)); - - _cursor_controller->move_to(previous_position, true); -} - const std::shared_ptr<IMatrix<std::string_view>> &Scene::get_matrix() const noexcept { return _matrix; diff --git a/src/engine/graphics/scene.hpp b/src/engine/graphics/scene.hpp index 1f1c51c..c4f6d67 100644 --- a/src/engine/graphics/scene.hpp +++ b/src/engine/graphics/scene.hpp @@ -12,10 +12,6 @@ constexpr fmt::string_view ENABLE_ALT_BUFFER = "{esc}[?1049h"; constexpr fmt::string_view DISABLE_ALT_BUFFER = "{esc}[?1049l"; -constexpr fmt::string_view ERASE_ENTIRE_LINE = "{esc}[2K"; - -constexpr uint32_t STATUSBAR_COLOR = 0x1A1A1AU; - class Scene : public IScene { public: @@ -27,8 +23,6 @@ public: void leave() noexcept override; - void write_status(const std::string_view &str) noexcept override; - [[nodiscard]] const std::shared_ptr<IMatrix<std::string_view>> & get_matrix() const noexcept override; diff --git a/src/engine/user/input.hpp b/src/engine/user/input.hpp index 6a9edfd..51f3fcb 100644 --- a/src/engine/user/input.hpp +++ b/src/engine/user/input.hpp @@ -29,7 +29,9 @@ public: void leave_raw_mode() noexcept override; private: - std::array<std::vector<std::shared_ptr<ISubscriber<Context>>>, CHAR_MAX> _subscribers; + std::array<std::vector<std::shared_ptr<ISubscriber<Context>>>, + static_cast<std::size_t>(CHAR_MAX * 2U)> + _subscribers; std::shared_ptr<termios> _original_termios = nullptr; diff --git a/src/game/cursor_listener.cpp b/src/game/cursor_listener.cpp deleted file mode 100644 index c815f08..0000000 --- a/src/game/cursor_listener.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "cursor_listener.hpp" - -#include <fmt/core.h> -#include <utility> - -CursorListener::CursorListener(std::shared_ptr<IScene> scene) noexcept - : _scene(std::move(scene)) -{ -} - -void CursorListener::update(const Vector2 &context) noexcept -{ - _scene->write_status(fmt::format("X: {} Y {}", context.get_x(), context.get_y())); -} diff --git a/src/game/cursor_listener.hpp b/src/game/cursor_listener.hpp deleted file mode 100644 index c74bb3d..0000000 --- a/src/game/cursor_listener.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "interfaces/scene.hpp" -#include "interfaces/subscriber.hpp" - -#include "engine/data/vector2.hpp" - -#include <memory> - -class CursorListener : public ISubscriber<Vector2> -{ -public: - explicit CursorListener(std::shared_ptr<IScene> scene) noexcept; - - void update(const Vector2 &context) noexcept override; - -private: - std::shared_ptr<IScene> _scene; -}; diff --git a/src/game/game.cpp b/src/game/game.cpp index f788d15..6632c08 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -3,22 +3,31 @@ #include "commands/insert_cell.hpp" #include "commands/move_cursor.hpp" #include "commands/quit.hpp" -#include "game/cursor_listener.hpp" +#include "commands/toggle_pause.hpp" #include <fmt/core.h> #include <iostream> +#include <utility> -Game::Game(const std::shared_ptr<IWindow> &window, const std::shared_ptr<IScene> &scene, - const std::shared_ptr<ICursorController> &cursor_controller) noexcept - : _window(window), _scene(scene), _cursor_controller(cursor_controller) +Game::Game(std::shared_ptr<IWindow> window, std::shared_ptr<IScene> scene, + std::shared_ptr<ICursorController> cursor_controller, + std::shared_ptr<IStatusLine> statusline, + std::shared_ptr<IGenerationTracker> generation_tracker, + std::shared_ptr<IStatusUpdater> status_updater) noexcept + : _window(std::move(window)), + _scene(std::move(scene)), + _cursor_controller(std::move(cursor_controller)), + _statusline(std::move(statusline)), + _generation_tracker(std::move(generation_tracker)), + _status_updater(std::move(status_updater)) { } void Game::on_start() noexcept { - auto cursor_listener = std::make_shared<CursorListener>(_scene); + _statusline->initialize_background(); - _cursor_controller->subscribe(CursorEvent::POSITION_CHANGE, cursor_listener); + _cursor_controller->subscribe(CursorEvent::POSITION_CHANGE, _status_updater); const auto window_size = _window->size(); @@ -28,9 +37,11 @@ void Game::on_start() noexcept _cursor_controller->move_to(center_position); - cursor_listener->update(center_position); + _status_updater->update(center_position); } +void Game::on_update() noexcept {} + void Game::on_exit() const noexcept { for (auto row : *_scene->get_matrix()) @@ -51,6 +62,7 @@ Game::get_input_config() const noexcept { return {{'q', std::make_shared<QuitCommand>()}, {'i', std::make_shared<InsertCellCommand>(_cursor_controller, _scene)}, + {'p', std::make_shared<TogglePauseCommand>(_generation_tracker, _statusline)}, {'k', std::make_shared<MoveCursorCommand>(Vector2::up(), _cursor_controller, _window)}, {'j', std::make_shared<MoveCursorCommand>(Vector2::down(), _cursor_controller, diff --git a/src/game/game.hpp b/src/game/game.hpp index 2493a42..5894a01 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -2,7 +2,10 @@ #include "interfaces/cursor.hpp" #include "interfaces/game.hpp" +#include "interfaces/generation_tracker.hpp" #include "interfaces/scene.hpp" +#include "interfaces/status_updater.hpp" +#include "interfaces/statusline.hpp" #include "interfaces/window.hpp" #include <memory> @@ -10,18 +13,26 @@ class Game : public IGame { public: - Game(const std::shared_ptr<IWindow> &window, const std::shared_ptr<IScene> &scene, - const std::shared_ptr<ICursorController> &cursor_controller) noexcept; + Game(std::shared_ptr<IWindow> window, std::shared_ptr<IScene> scene, + std::shared_ptr<ICursorController> cursor_controller, + std::shared_ptr<IStatusLine> statusline, + std::shared_ptr<IGenerationTracker> generation_tracker, + std::shared_ptr<IStatusUpdater> status_updater) noexcept; void on_start() noexcept override; + void on_update() noexcept override; + void on_exit() const noexcept override; [[nodiscard]] std::unordered_map<char, std::shared_ptr<ICommand>> get_input_config() const noexcept override; private: - const std::shared_ptr<IWindow> &_window; - const std::shared_ptr<IScene> &_scene; - const std::shared_ptr<ICursorController> &_cursor_controller; + std::shared_ptr<IWindow> _window; + std::shared_ptr<IScene> _scene; + std::shared_ptr<ICursorController> _cursor_controller; + std::shared_ptr<IStatusLine> _statusline; + std::shared_ptr<IGenerationTracker> _generation_tracker; + std::shared_ptr<IStatusUpdater> _status_updater; }; diff --git a/src/game/generation_tracker.cpp b/src/game/generation_tracker.cpp new file mode 100644 index 0000000..0e137cb --- /dev/null +++ b/src/game/generation_tracker.cpp @@ -0,0 +1,18 @@ +#include "generation_tracker.hpp" + +GenerationTracker::GenerationTracker(bool is_paused) noexcept : _is_paused(is_paused) {} + +uint32_t GenerationTracker::get_current_generation() const noexcept +{ + return _current_generation; +} + +bool GenerationTracker::get_is_paused() const noexcept +{ + return _is_paused; +} + +void GenerationTracker::set_is_paused(bool is_paused) noexcept +{ + _is_paused = is_paused; +} diff --git a/src/game/generation_tracker.hpp b/src/game/generation_tracker.hpp new file mode 100644 index 0000000..0e59751 --- /dev/null +++ b/src/game/generation_tracker.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "interfaces/generation_tracker.hpp" + +#include <cstdint> + +class GenerationTracker : public IGenerationTracker +{ +public: + explicit GenerationTracker(bool is_paused) noexcept; + + [[nodiscard]] uint32_t get_current_generation() const noexcept override; + + [[nodiscard]] bool get_is_paused() const noexcept override; + + void set_is_paused(bool is_paused) noexcept override; + +private: + uint32_t _current_generation = 0U; + + bool _is_paused; +}; diff --git a/src/game/status_updater.cpp b/src/game/status_updater.cpp new file mode 100644 index 0000000..18c535e --- /dev/null +++ b/src/game/status_updater.cpp @@ -0,0 +1,25 @@ +#include "status_updater.hpp" + +#include <fmt/core.h> +#include <utility> + +StatusUpdater::StatusUpdater( + std::shared_ptr<IStatusLine> statusline, + std::shared_ptr<IGenerationTracker> generation_tracker) noexcept + : _statusline(std::move(statusline)), + _generation_tracker(std::move(generation_tracker)) +{ +} + +void StatusUpdater::update(const Vector2 &context) noexcept +{ + _statusline->set_status( + StatusLineSection::A, + fmt::format("X: {} Y {}", context.get_x(), context.get_y())); + + _statusline->set_status( + StatusLineSection::B, + fmt::format("Paused: {} Generation: {}", + _generation_tracker->get_is_paused() ? "yes" : "no", + _generation_tracker->get_current_generation())); +} diff --git a/src/game/status_updater.hpp b/src/game/status_updater.hpp new file mode 100644 index 0000000..3b76d3b --- /dev/null +++ b/src/game/status_updater.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include "interfaces/generation_tracker.hpp" +#include "interfaces/status_updater.hpp" +#include "interfaces/statusline.hpp" +#include "interfaces/subscriber.hpp" + +#include "engine/data/vector2.hpp" + +#include <memory> + +class StatusUpdater : public IStatusUpdater +{ +public: + explicit StatusUpdater( + std::shared_ptr<IStatusLine> statusline, + std::shared_ptr<IGenerationTracker> generation_tracker) noexcept; + + void update(const Vector2 &context) noexcept override; + +private: + std::shared_ptr<IStatusLine> _statusline; + std::shared_ptr<IGenerationTracker> _generation_tracker; +}; diff --git a/src/game/statusline.cpp b/src/game/statusline.cpp new file mode 100644 index 0000000..377fa75 --- /dev/null +++ b/src/game/statusline.cpp @@ -0,0 +1,102 @@ +#include "statusline.hpp" + +#include "engine/escape.hpp" +#include "util/color.hpp" + +#include <iostream> +#include <string> +#include <utility> + +StatusLine::StatusLine(std::shared_ptr<ICursorController> cursor_controller, + std::shared_ptr<IWindow> window) noexcept + : _cursor_controller(std::move(cursor_controller)), _window(std::move(window)) +{ + constexpr uint32_t SECTION_A_LENGTH = 20; + constexpr uint32_t SECTION_B_LENGTH = 15; + + _sections_lengths[StatusLineSection::A] = SECTION_A_LENGTH; + _sections_lengths[StatusLineSection::B] = SECTION_B_LENGTH; +} + +void StatusLine::initialize_background() noexcept +{ + const auto previous_position = _move_to_statusline(0); + + auto background_color = get_background_esc_seq(STATUSBAR_COLOR); + + fmt::print("{}{}", background_color, std::string(_window->size().get_width(), ' ')); + fmt::print(RESET_ALL_MODES, fmt::arg("esc", ESC)); + + _move_back(previous_position); +} + +void StatusLine::set_status(StatusLineSection section, + const std::string_view &str) noexcept +{ + _clear_section(section); + + int32_t section_start = _get_section_start_x(section); + + const auto previous_position = _move_to_statusline(section_start); + + auto background_color = get_background_esc_seq(STATUSBAR_COLOR); + + fmt::print("{}{}", background_color, str); + fmt::print(RESET_ALL_MODES, fmt::arg("esc", ESC)); + + _move_back(previous_position); +} + +Vector2 StatusLine::_move_to_statusline(int32_t x) noexcept +{ + const auto previous_position = _cursor_controller->where(); + + const auto window_size = _window->size(); + + _cursor_controller->hide(); + + auto window_height = static_cast<Vector2::Value>(window_size.get_height()); + + _cursor_controller->move_to(Vector2({.x = x, .y = window_height}), true); + + return previous_position; +} + +void StatusLine::_move_back(Vector2 previous_position) noexcept +{ + _cursor_controller->move_to(previous_position, true); + _cursor_controller->show(); +} + +int32_t StatusLine::_get_section_start_x(StatusLineSection section) const noexcept +{ + int32_t section_start = 0; + + auto section_index = static_cast<int32_t>(section); + + while (section_index > 0) + { + section_start += static_cast<int32_t>( + _sections_lengths.at(StatusLineSection(section_index - 1))); + + section_index--; + } + + return section_start; +} + +void StatusLine::_clear_section(StatusLineSection section) noexcept +{ + auto section_start = _get_section_start_x(section); + + const auto previous_position = _move_to_statusline(section_start); + + auto background_color = get_background_esc_seq(STATUSBAR_COLOR); + + auto section_length = _sections_lengths.at(section); + + fmt::print("{}{}", background_color, std::string(section_length, ' ')); + fmt::print(RESET_ALL_MODES, fmt::arg("esc", ESC)); + + _move_back(previous_position); +} diff --git a/src/game/statusline.hpp b/src/game/statusline.hpp new file mode 100644 index 0000000..7db1e0b --- /dev/null +++ b/src/game/statusline.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "interfaces/cursor.hpp" +#include "interfaces/statusline.hpp" +#include "interfaces/window.hpp" + +#include "engine/data/vector2.hpp" + +#include <cstdint> +#include <fmt/core.h> +#include <memory> +#include <string_view> +#include <unordered_map> + +constexpr uint32_t STATUSBAR_COLOR = 0x1A1A1AU; + +class StatusLine : public IStatusLine +{ +public: + StatusLine(std::shared_ptr<ICursorController> cursor_controller, + std::shared_ptr<IWindow> window) noexcept; + + void initialize_background() noexcept override; + + void set_status(StatusLineSection section, + const std::string_view &str) noexcept override; + +private: + std::unordered_map<StatusLineSection, uint32_t> _sections_lengths; + + std::shared_ptr<ICursorController> _cursor_controller; + std::shared_ptr<IWindow> _window; + + Vector2 _move_to_statusline(int32_t x) noexcept; + + void _move_back(Vector2 previous_position) noexcept; + + int32_t _get_section_start_x(StatusLineSection section) const noexcept; + + void _clear_section(StatusLineSection section) noexcept; +}; diff --git a/src/interfaces/game.hpp b/src/interfaces/game.hpp index c99c01f..6836dbd 100644 --- a/src/interfaces/game.hpp +++ b/src/interfaces/game.hpp @@ -11,9 +11,11 @@ class IGame { public: - virtual ~IGame() = default; + virtual ~IGame() noexcept = default; - virtual void on_start() = 0; + virtual void on_start() noexcept = 0; + + virtual void on_update() noexcept = 0; virtual void on_exit() const noexcept = 0; diff --git a/src/interfaces/generation_tracker.hpp b/src/interfaces/generation_tracker.hpp new file mode 100644 index 0000000..135af00 --- /dev/null +++ b/src/interfaces/generation_tracker.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include <cstdint> +#include <memory> + +class IGenerationTracker +{ +public: + virtual ~IGenerationTracker() noexcept = default; + + [[nodiscard]] virtual uint32_t get_current_generation() const noexcept = 0; + + [[nodiscard]] virtual bool get_is_paused() const noexcept = 0; + + virtual void set_is_paused(bool is_paused) noexcept = 0; +}; + +using IGenerationTrackerFactory = std::shared_ptr<IGenerationTracker> (*)(bool is_paused); diff --git a/src/interfaces/scene.hpp b/src/interfaces/scene.hpp index 0443d41..3b5e037 100644 --- a/src/interfaces/scene.hpp +++ b/src/interfaces/scene.hpp @@ -15,8 +15,6 @@ public: virtual void leave() noexcept = 0; - virtual void write_status(const std::string_view &str) noexcept = 0; - [[nodiscard]] virtual const std::shared_ptr<IMatrix<std::string_view>> & get_matrix() const noexcept = 0; }; diff --git a/src/interfaces/status_updater.hpp b/src/interfaces/status_updater.hpp new file mode 100644 index 0000000..ccfb2db --- /dev/null +++ b/src/interfaces/status_updater.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "interfaces/generation_tracker.hpp" +#include "interfaces/statusline.hpp" +#include "interfaces/subscriber.hpp" + +#include "engine/data/vector2.hpp" + +#include <memory> + +class IStatusUpdater : public ISubscriber<Vector2> +{ +public: + void update(const Vector2 &context) noexcept override = 0; +}; + +using IStatusUpdaterFactory = std::shared_ptr<IStatusUpdater> (*)( + const std::shared_ptr<IStatusLine> &statusline, + const std::shared_ptr<IGenerationTracker> &generation_tracker); diff --git a/src/interfaces/statusline.hpp b/src/interfaces/statusline.hpp new file mode 100644 index 0000000..00da99b --- /dev/null +++ b/src/interfaces/statusline.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include "interfaces/cursor.hpp" +#include "interfaces/window.hpp" + +#include <string_view> + +enum StatusLineSection +{ + A, + B +}; + +class IStatusLine +{ +public: + virtual ~IStatusLine() noexcept = default; + + virtual void initialize_background() noexcept = 0; + + virtual void set_status(StatusLineSection section, + const std::string_view &str) noexcept = 0; +}; + +using IStatusLineFactory = std::shared_ptr<IStatusLine> (*)( + const std::shared_ptr<ICursorController> &cursor_controller, + const std::shared_ptr<IWindow> &window); |