diff options
author | HampusM <hampus@hampusmat.com> | 2022-05-02 22:36:21 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-06-13 17:56:58 +0200 |
commit | fb080f6fb911b1831c176a06259e384772541dd5 (patch) | |
tree | e18140e700cd974f84a5630f41fcb0b496b7e772 /src/game | |
parent | 40d02748924aa7c48b04cf948204d8dacdfbbc74 (diff) |
refactor: seperate statusline related concerns
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/game.cpp | 101 | ||||
-rw-r--r-- | src/game/game.hpp | 11 | ||||
-rw-r--r-- | src/game/status_manager.cpp | 43 | ||||
-rw-r--r-- | src/game/status_manager.hpp | 32 | ||||
-rw-r--r-- | src/game/status_updater.cpp | 30 | ||||
-rw-r--r-- | src/game/status_updater.hpp | 25 | ||||
-rw-r--r-- | src/game/statusline.cpp | 55 | ||||
-rw-r--r-- | src/game/statusline.hpp | 14 | ||||
-rw-r--r-- | src/game/statusline_subscriber_adapter.hpp | 30 | ||||
-rw-r--r-- | src/game/statusline_subscriber_adapter.tpp | 31 |
10 files changed, 259 insertions, 113 deletions
diff --git a/src/game/game.cpp b/src/game/game.cpp index 1a69e2e..02a0f65 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -15,14 +15,19 @@ Game::Game( std::shared_ptr<ICursorController> cursor_controller, std::shared_ptr<IStatusLine> statusline, std::shared_ptr<IGenerationTracker> generation_tracker, - std::shared_ptr<IStatusUpdater> status_updater + std::shared_ptr<IStatusManager> status_manager, + IStatusLineSubscriberAdapterFactory<Vector2> + vector2_statusline_subscriber_adapter_factory ) 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)) + _status_manager(std::move(status_manager)), + _vector2_statusline_subscriber_adapter_factory( + vector2_statusline_subscriber_adapter_factory + ) { } @@ -30,7 +35,22 @@ void Game::on_start() noexcept { _statusline->initialize_background(); - _cursor_controller->subscribe(CursorEvent::POSITION_CHANGE, _status_updater); + _status_manager->set_section_title(StatusLineSection::A, ""); + _status_manager->set_section_title(StatusLineSection::B, "X: "); + _status_manager->set_section_title(StatusLineSection::C, "Y: "); + _status_manager->set_section_title(StatusLineSection::D, "Paused: "); + _status_manager->set_section_title(StatusLineSection::E, "Generation: "); + + std::shared_ptr<ISubscriber<Vector2>> vector2_statusline_subscriber_adapter = + _vector2_statusline_subscriber_adapter_factory( + _status_manager, + { StatusLineSection::B, StatusLineSection::C } + ); + + _cursor_controller->subscribe( + CursorEvent::POSITION_CHANGE, + vector2_statusline_subscriber_adapter + ); const auto window_size = _window->size(); @@ -40,7 +60,22 @@ void Game::on_start() noexcept _cursor_controller->move_to(center_position); - _status_updater->update(center_position); + _status_manager->set_section_body( + StatusLineSection::B, + fmt::format("{}", center_position.get_x()) + ); + + _status_manager->set_section_body( + StatusLineSection::C, + fmt::format("{}", center_position.get_y()) + ); + + _status_manager->set_section_body( + StatusLineSection::D, + _generation_tracker->get_is_paused() ? "yes" : "no" + ); + + _status_manager->set_section_body(StatusLineSection::E, "0"); } void Game::on_update() noexcept {} @@ -63,32 +98,34 @@ void Game::on_exit() const noexcept auto Game::get_input_config() const noexcept -> std::unordered_map<char, std::shared_ptr<ICommand>> { - 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, - _window - ) }, - { 'h', - std::make_shared<MoveCursorCommand>( - Vector2::left(), - _cursor_controller, - _window - ) }, - { 'l', - std::make_shared<MoveCursorCommand>( - Vector2::right(), - _cursor_controller, - _window - ) } }; + return { + { 'q', std::make_shared<QuitCommand>() }, + { 'i', std::make_shared<InsertCellCommand>(_cursor_controller, _scene) }, + { 'p', + std::make_shared<TogglePauseCommand>(_generation_tracker, _status_manager) }, + { 'k', + std::make_shared<MoveCursorCommand>( + Vector2::up(), + _cursor_controller, + _window + ) }, + { 'j', + std::make_shared<MoveCursorCommand>( + Vector2::down(), + _cursor_controller, + _window + ) }, + { 'h', + std::make_shared<MoveCursorCommand>( + Vector2::left(), + _cursor_controller, + _window + ) }, + { 'l', + std::make_shared<MoveCursorCommand>( + Vector2::right(), + _cursor_controller, + _window + ) } + }; } diff --git a/src/game/game.hpp b/src/game/game.hpp index 9f08158..9689215 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -4,8 +4,9 @@ #include "interfaces/game.hpp" #include "interfaces/generation_tracker.hpp" #include "interfaces/scene.hpp" -#include "interfaces/status_updater.hpp" +#include "interfaces/status_manager.hpp" #include "interfaces/statusline.hpp" +#include "interfaces/statusline_subscriber_adapter.hpp" #include "interfaces/window.hpp" #include <memory> @@ -19,7 +20,9 @@ public: std::shared_ptr<ICursorController> cursor_controller, std::shared_ptr<IStatusLine> statusline, std::shared_ptr<IGenerationTracker> generation_tracker, - std::shared_ptr<IStatusUpdater> status_updater + std::shared_ptr<IStatusManager> status_manager, + IStatusLineSubscriberAdapterFactory<Vector2> + vector2_statusline_subscriber_adapter_factory ) noexcept; void on_start() noexcept override; @@ -37,5 +40,7 @@ private: std::shared_ptr<ICursorController> _cursor_controller; std::shared_ptr<IStatusLine> _statusline; std::shared_ptr<IGenerationTracker> _generation_tracker; - std::shared_ptr<IStatusUpdater> _status_updater; + std::shared_ptr<IStatusManager> _status_manager; + IStatusLineSubscriberAdapterFactory<Vector2> + _vector2_statusline_subscriber_adapter_factory; }; diff --git a/src/game/status_manager.cpp b/src/game/status_manager.cpp new file mode 100644 index 0000000..727452c --- /dev/null +++ b/src/game/status_manager.cpp @@ -0,0 +1,43 @@ +#include "status_manager.hpp" + +#include <fmt/core.h> + +#include <utility> + +StatusManager::StatusManager(std::shared_ptr<IStatusLine> statusline) noexcept + : _statusline(std::move(statusline)) + +{ + _statusline->set_section_length(StatusLineSection::A, 5U); + _statusline->set_section_length(StatusLineSection::B, 15U); + _statusline->set_section_length(StatusLineSection::C, 15U); + _statusline->set_section_length(StatusLineSection::D, 20U); + _statusline->set_section_length(StatusLineSection::E, 15U); + _statusline->set_section_length(StatusLineSection::F, 15U); +} + +void StatusManager::set_section_title( + const StatusLineSection §ion, + const std::string_view &title +) noexcept +{ + if (_title_lengths.count(section) != 0) + { + fmt::print(stderr, "Error: can't set statusbar section title more than once"); + return; + } + + _statusline->set_status(section, title); + + _title_lengths[section] = title.length(); +} + +void StatusManager::set_section_body( + const StatusLineSection §ion, + const std::string_view &body +) noexcept +{ + auto section_title_length = _title_lengths[section]; + + _statusline->set_status(section, body, section_title_length + 1); +} diff --git a/src/game/status_manager.hpp b/src/game/status_manager.hpp new file mode 100644 index 0000000..62b5bc7 --- /dev/null +++ b/src/game/status_manager.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "interfaces/generation_tracker.hpp" +#include "interfaces/status_manager.hpp" +#include "interfaces/statusline.hpp" +#include "interfaces/subscriber.hpp" + +#include "engine/data/vector2.hpp" + +#include <memory> +#include <unordered_map> + +class StatusManager : public IStatusManager +{ +public: + explicit StatusManager(std::shared_ptr<IStatusLine> statusline) noexcept; + + void set_section_title( + const StatusLineSection §ion, + const std::string_view &title + ) noexcept override; + + void set_section_body( + const StatusLineSection §ion, + const std::string_view &body + ) noexcept override; + +private: + std::shared_ptr<IStatusLine> _statusline; + + std::unordered_map<StatusLineSection, std::size_t> _title_lengths; +}; diff --git a/src/game/status_updater.cpp b/src/game/status_updater.cpp deleted file mode 100644 index 1cfd1d2..0000000 --- a/src/game/status_updater.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#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 deleted file mode 100644 index 0fd38a7..0000000 --- a/src/game/status_updater.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#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 index d764d60..58a317b 100644 --- a/src/game/statusline.cpp +++ b/src/game/statusline.cpp @@ -3,9 +3,13 @@ #include "engine/escape.hpp" #include "util/color.hpp" +#include <algorithm> #include <iostream> +#include <numeric> +#include <ranges> #include <string> #include <utility> +#include <vector> StatusLine::StatusLine( std::shared_ptr<ICursorController> cursor_controller, @@ -13,11 +17,6 @@ StatusLine::StatusLine( ) noexcept : _cursor_controller(std::move(cursor_controller)), _window(std::move(window)) { - constexpr uint32_t SECTION_A_LENGTH = 20; - constexpr uint32_t SECTION_B_LENGTH = 30; - - _sections_lengths[StatusLineSection::A] = SECTION_A_LENGTH; - _sections_lengths[StatusLineSection::B] = SECTION_B_LENGTH; } void StatusLine::initialize_background() noexcept @@ -33,23 +32,27 @@ void StatusLine::initialize_background() noexcept } void StatusLine::set_status( - StatusLineSection section, - const std::string_view &statusline_str + const StatusLineSection §ion, + const std::string_view &status, + std::size_t start ) noexcept { - _clear_section(section); + _clear_section(section, start); - int32_t section_start = _get_section_start_x(section); + auto section_start = _get_section_start_x(section); - const auto previous_position = _move_to_statusline(section_start); + const auto previous_position = + _move_to_statusline(section_start + static_cast<int32_t>(start)); auto background_color = get_background_esc_seq(STATUSBAR_COLOR); auto section_length = _sections_lengths[section]; - auto status = statusline_str.length() > section_length - ? statusline_str.substr(0, section_length) - : statusline_str; + /* + auto status = status.length() > section_length + ? status_str.substr(0, section_length) + : status_str; + */ fmt::print("{}{}", background_color, status); fmt::print(RESET_ALL_MODES, fmt::arg("esc", ESC)); @@ -57,6 +60,14 @@ void StatusLine::set_status( _move_back(previous_position); } +void StatusLine::set_section_length( + const StatusLineSection §ion, + uint32_t length +) noexcept +{ + _sections_lengths[section] = length; +} + auto StatusLine::_move_to_statusline(int32_t x) noexcept -> Vector2 { const auto previous_position = _cursor_controller->where(); @@ -78,7 +89,8 @@ void StatusLine::_move_back(Vector2 previous_position) noexcept _cursor_controller->show(); } -auto StatusLine::_get_section_start_x(StatusLineSection section) const noexcept -> int32_t +auto StatusLine::_get_section_start_x(const StatusLineSection §ion) const noexcept + -> int32_t { int32_t section_start = 0; @@ -96,17 +108,24 @@ auto StatusLine::_get_section_start_x(StatusLineSection section) const noexcept return section_start; } -void StatusLine::_clear_section(StatusLineSection section) noexcept +void StatusLine::_clear_section( + const StatusLineSection §ion, + std::size_t start +) noexcept { auto section_start = _get_section_start_x(section); - const auto previous_position = _move_to_statusline(section_start); + auto start_int32 = static_cast<int32_t>(start); + + const auto previous_position = _move_to_statusline(section_start + start_int32); auto background_color = get_background_esc_seq(STATUSBAR_COLOR); - auto section_length = _sections_lengths.at(section); + auto section_length = _sections_lengths[section]; + + auto start_uint32 = static_cast<uint32_t>(start); - fmt::print("{}{}", background_color, std::string(section_length, ' ')); + fmt::print("{}{}", background_color, std::string(section_length - start_uint32, ' ')); 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 index 66ce2c4..7883051 100644 --- a/src/game/statusline.hpp +++ b/src/game/statusline.hpp @@ -25,10 +25,14 @@ public: void initialize_background() noexcept override; void set_status( - StatusLineSection section, - const std::string_view &status_str + const StatusLineSection §ion, + const std::string_view &status, + std::size_t start ) noexcept override; + void set_section_length(const StatusLineSection §ion, uint32_t length) noexcept + override; + private: std::unordered_map<StatusLineSection, uint32_t> _sections_lengths; @@ -39,8 +43,8 @@ private: void _move_back(Vector2 previous_position) noexcept; - [[nodiscard]] auto _get_section_start_x(StatusLineSection section) const noexcept - -> int32_t; + [[nodiscard]] auto _get_section_start_x(const StatusLineSection §ion + ) const noexcept -> int32_t; - void _clear_section(StatusLineSection section) noexcept; + void _clear_section(const StatusLineSection §ion, std::size_t start) noexcept; }; diff --git a/src/game/statusline_subscriber_adapter.hpp b/src/game/statusline_subscriber_adapter.hpp new file mode 100644 index 0000000..d53ae04 --- /dev/null +++ b/src/game/statusline_subscriber_adapter.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "interfaces/statusline.hpp" +#include "interfaces/statusline_subscriber_adapter.hpp" +#include "interfaces/subscriber.hpp" + +#include <memory> +#include <string> +#include <vector> + +template <typename Context> +class StatusLineSubscriberAdapter : public ISubscriber<Context> +{ +public: + StatusLineSubscriberAdapter( + std::shared_ptr<IStatusManager> status_manager, + std::string (*format_func)(std::size_t section_index, const Context &context), + const std::vector<StatusLineSection> §ions + ) noexcept; + + void update(const Context &context) noexcept override; + +private: + std::shared_ptr<IStatusManager> _status_manager; + + std::string (*_format_func)(std::size_t section_index, const Context &context); + std::vector<StatusLineSection> _sections; +}; + +#include "statusline_subscriber_adapter.tpp" diff --git a/src/game/statusline_subscriber_adapter.tpp b/src/game/statusline_subscriber_adapter.tpp new file mode 100644 index 0000000..1de459c --- /dev/null +++ b/src/game/statusline_subscriber_adapter.tpp @@ -0,0 +1,31 @@ +#pragma once + +#include "statusline_subscriber_adapter.hpp" + +#include <utility> + +template <typename Context> +StatusLineSubscriberAdapter<Context>::StatusLineSubscriberAdapter( + std::shared_ptr<IStatusManager> status_manager, + std::string (*format_func)(std::size_t section_index, const Context &context), + const std::vector<StatusLineSection> §ions + +) noexcept + : _status_manager(std::move(status_manager)), + _format_func(format_func), + _sections(sections) +{ +} + +template <typename Context> +void StatusLineSubscriberAdapter<Context>::update(const Context &context) noexcept +{ + for (std::size_t index = 0; const auto §ion : _sections) + { + auto status = _format_func(index, context); + + _status_manager->set_section_body(_sections[index], status); + + index++; + } +} |