aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-03-20 20:37:43 +0100
committerHampusM <hampus@hampusmat.com>2022-06-13 17:56:57 +0200
commit1972939ebde39a3e90a50b021b2322d028f344de (patch)
tree9ee0a7c78f082bec084189906f28dc679a20d339
parente6644d6b235005de9ba1b9884472fa5f5d8d6074 (diff)
refactor: move updating status from the move cursor command
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/commands/move_cursor.cpp15
-rw-r--r--src/commands/move_cursor.hpp3
-rw-r--r--src/engine/graphics/scene.cpp5
-rw-r--r--src/engine/user/cursor.cpp36
-rw-r--r--src/engine/user/cursor.hpp9
-rw-r--r--src/game/cursor_listener.cpp18
-rw-r--r--src/game/cursor_listener.hpp19
-rw-r--r--src/game/game.cpp15
-rw-r--r--src/interfaces/command.hpp2
-rw-r--r--src/interfaces/cursor.hpp25
-rw-r--r--src/interfaces/subscriber.hpp2
12 files changed, 121 insertions, 29 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1a52ae8..c603b37 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -15,6 +15,7 @@ file(GLOB SOURCES
argument_parser.cpp
util/color.cpp
game/game.cpp
+ game/cursor_listener.cpp
engine/engine.cpp
engine/data/vector2.cpp
engine/data/bounds.cpp
diff --git a/src/commands/move_cursor.cpp b/src/commands/move_cursor.cpp
index 8dd7db7..1d2b4e8 100644
--- a/src/commands/move_cursor.cpp
+++ b/src/commands/move_cursor.cpp
@@ -1,16 +1,9 @@
#include "move_cursor.hpp"
-#include "strings.hpp"
-
-#include <fmt/core.h>
-
MoveCursorCommand::MoveCursorCommand(
const Vector2 &direction, const std::shared_ptr<ICursorController> &cursor_controller,
- const std::shared_ptr<IScene> &scene, const std::shared_ptr<IWindow> &window) noexcept
- : _direction(direction),
- _cursor_controller(cursor_controller),
- _scene(scene),
- _window(window)
+ const std::shared_ptr<IWindow> &window) noexcept
+ : _direction(direction), _cursor_controller(cursor_controller), _window(window)
{
}
@@ -30,8 +23,4 @@ void MoveCursorCommand::execute() noexcept
}
_cursor_controller->move_to(new_position);
-
- _scene->write_status(fmt::format(STATUS_BAR_COORDINATES,
- fmt::arg("x", new_position.get_x()),
- fmt::arg("y", new_position.get_y())));
}
diff --git a/src/commands/move_cursor.hpp b/src/commands/move_cursor.hpp
index 14a87e0..ff4723d 100644
--- a/src/commands/move_cursor.hpp
+++ b/src/commands/move_cursor.hpp
@@ -2,7 +2,6 @@
#include "interfaces/command.hpp"
#include "interfaces/cursor.hpp"
-#include "interfaces/scene.hpp"
#include "interfaces/window.hpp"
#include "engine/data/vector2.hpp"
@@ -14,7 +13,6 @@ class MoveCursorCommand : public ICommand
public:
MoveCursorCommand(const Vector2 &direction,
const std::shared_ptr<ICursorController> &cursor_controller,
- const std::shared_ptr<IScene> &scene,
const std::shared_ptr<IWindow> &window) noexcept;
void execute() noexcept override;
@@ -22,6 +20,5 @@ public:
private:
Vector2 _direction;
const std::shared_ptr<ICursorController> &_cursor_controller;
- const std::shared_ptr<IScene> &_scene;
const std::shared_ptr<IWindow> &_window;
};
diff --git a/src/engine/graphics/scene.cpp b/src/engine/graphics/scene.cpp
index 476b966..4e382fe 100644
--- a/src/engine/graphics/scene.cpp
+++ b/src/engine/graphics/scene.cpp
@@ -52,7 +52,8 @@ void Scene::write_status(const std::string_view &str) noexcept
const auto window_size = _window->size();
_cursor_controller->move_to(
- Vector2({.x = 2, .y = static_cast<Vector2::Value>(window_size.get_height())}));
+ Vector2({.x = 2, .y = static_cast<Vector2::Value>(window_size.get_height())}),
+ true);
auto background_color = get_background_esc_seq(STATUSBAR_COLOR);
@@ -61,7 +62,7 @@ void Scene::write_status(const std::string_view &str) noexcept
fmt::print(fmt::runtime(str.data()));
fmt::print(RESET_ALL_MODES, fmt::arg("esc", ESC));
- _cursor_controller->move_to(previous_position);
+ _cursor_controller->move_to(previous_position, true);
}
const std::shared_ptr<IMatrix<std::string_view>> &Scene::get_matrix() const noexcept
diff --git a/src/engine/user/cursor.cpp b/src/engine/user/cursor.cpp
index b02a9bc..2a72663 100644
--- a/src/engine/user/cursor.cpp
+++ b/src/engine/user/cursor.cpp
@@ -16,15 +16,22 @@ void CursorController::move(const Vector2 &direction, const uint32_t &amount) no
std::cout.flush();
_position = _position.to_direction(direction, static_cast<Vector2::Value>(amount));
+
+ notify_subscribers(CursorEvent::POSITION_CHANGE, _position);
}
-void CursorController::move_to(const Vector2 &position) noexcept
+void CursorController::move_to(const Vector2 &position, bool silent) noexcept
{
fmt::print(MOVE_CURSOR_TO, fmt::arg("esc", ESC), fmt::arg("row", position.get_y()),
fmt::arg("column", position.get_x()));
std::cout.flush();
_position = position;
+
+ if (!silent)
+ {
+ notify_subscribers(CursorEvent::POSITION_CHANGE, position);
+ }
}
Vector2 CursorController::where() const noexcept
@@ -43,6 +50,8 @@ void CursorController::ensure_position() noexcept
scanf("\033[%u;%uR", &vector2_options.y, &vector2_options.x);
_position = Vector2(vector2_options);
+
+ notify_subscribers(CursorEvent::POSITION_CHANGE, _position);
}
void CursorController::hide() noexcept
@@ -56,3 +65,28 @@ void CursorController::show() noexcept
fmt::print(CURSOR_VISIBLE, fmt::arg("esc", ESC));
std::cout.flush();
}
+
+void CursorController::subscribe(const Event &event,
+ const Subscriber &subscriber) noexcept
+{
+ if (_subscribers.count(event) == 0)
+ {
+ _subscribers.insert({event, std::vector<Subscriber>()});
+ }
+
+ _subscribers.at(event).push_back(subscriber);
+}
+
+void CursorController::notify_subscribers(const Event &event,
+ const Context &context) const noexcept
+{
+ if (_subscribers.count(event) == 0)
+ {
+ return;
+ }
+
+ for (const auto &subscriber : _subscribers.at(event))
+ {
+ subscriber->update(context);
+ }
+}
diff --git a/src/engine/user/cursor.hpp b/src/engine/user/cursor.hpp
index 713ee31..3ba8a40 100644
--- a/src/engine/user/cursor.hpp
+++ b/src/engine/user/cursor.hpp
@@ -37,7 +37,7 @@ public:
void move(const Vector2 &direction, const uint32_t &amount) noexcept override;
- void move_to(const Vector2 &position) noexcept override;
+ void move_to(const Vector2 &position, bool silent) noexcept override;
[[nodiscard]] Vector2 where() const noexcept override;
@@ -47,6 +47,13 @@ public:
static void show() noexcept;
+ void subscribe(const Event &event, const Subscriber &subscriber) noexcept override;
+
+ void notify_subscribers(const Event &event,
+ const Context &context) const noexcept override;
+
private:
Vector2 _position;
+
+ std::unordered_map<CursorEvent, std::vector<Subscriber>> _subscribers;
};
diff --git a/src/game/cursor_listener.cpp b/src/game/cursor_listener.cpp
new file mode 100644
index 0000000..c13ce44
--- /dev/null
+++ b/src/game/cursor_listener.cpp
@@ -0,0 +1,18 @@
+#include "cursor_listener.hpp"
+
+#include "strings.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(STATUS_BAR_COORDINATES,
+ fmt::arg("x", context.get_x()),
+ fmt::arg("y", context.get_y())));
+}
diff --git a/src/game/cursor_listener.hpp b/src/game/cursor_listener.hpp
new file mode 100644
index 0000000..c74bb3d
--- /dev/null
+++ b/src/game/cursor_listener.hpp
@@ -0,0 +1,19 @@
+#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 5df3935..055e212 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -3,6 +3,7 @@
#include "commands/insert_cell.hpp"
#include "commands/move_cursor.hpp"
#include "commands/quit.hpp"
+#include "game/cursor_listener.hpp"
#include "strings.hpp"
#include <fmt/core.h>
@@ -16,6 +17,10 @@ Game::Game(const std::shared_ptr<IWindow> &window, const std::shared_ptr<IScene>
void Game::on_start() noexcept
{
+ auto cursor_listener = std::make_shared<CursorListener>(_scene);
+
+ _cursor_controller->subscribe(CursorEvent::POSITION_CHANGE, cursor_listener);
+
const auto window_size = _window->size();
const auto center_position =
@@ -50,11 +55,11 @@ Game::get_input_config() const noexcept
return {{'q', std::make_shared<QuitCommand>()},
{'i', std::make_shared<InsertCellCommand>(_cursor_controller, _scene)},
{'k', std::make_shared<MoveCursorCommand>(Vector2::up(), _cursor_controller,
- _scene, _window)},
+ _window)},
{'j', std::make_shared<MoveCursorCommand>(Vector2::down(), _cursor_controller,
- _scene, _window)},
+ _window)},
{'h', std::make_shared<MoveCursorCommand>(Vector2::left(), _cursor_controller,
- _scene, _window)},
- {'l', std::make_shared<MoveCursorCommand>(
- Vector2::right(), _cursor_controller, _scene, _window)}};
+ _window)},
+ {'l', std::make_shared<MoveCursorCommand>(Vector2::right(),
+ _cursor_controller, _window)}};
}
diff --git a/src/interfaces/command.hpp b/src/interfaces/command.hpp
index 62d7a59..6220af1 100644
--- a/src/interfaces/command.hpp
+++ b/src/interfaces/command.hpp
@@ -7,7 +7,7 @@
class ICommand : public ISubscriber<std::nullptr_t>
{
public:
- virtual ~ICommand() = default;
+ ~ICommand() override = default;
virtual void execute() noexcept = 0;
diff --git a/src/interfaces/cursor.hpp b/src/interfaces/cursor.hpp
index 77c5096..ec2f60c 100644
--- a/src/interfaces/cursor.hpp
+++ b/src/interfaces/cursor.hpp
@@ -1,17 +1,30 @@
#pragma once
+#include "interfaces/publisher.hpp"
+#include "interfaces/subscriber.hpp"
+
#include "engine/data/vector2.hpp"
#include <memory>
-class ICursorController
+enum CursorEvent
+{
+ POSITION_CHANGE
+};
+
+class ICursorController : public IPublisher<CursorEvent, Vector2>
{
public:
- virtual ~ICursorController() noexcept = default;
+ using Event = CursorEvent;
+ using Context = Vector2;
+ using Subscriber = std::shared_ptr<ISubscriber<Context>>;
+
+ ~ICursorController() noexcept override = default;
virtual void move(const Vector2 &direction, const uint32_t &amount) noexcept = 0;
- virtual void move_to(const Vector2 &position) noexcept = 0;
+ // NOLINTNEXTLINE(google-default-arguments)
+ virtual void move_to(const Vector2 &position, bool silent = false) noexcept = 0;
[[nodiscard]] virtual Vector2 where() const noexcept = 0;
@@ -20,4 +33,10 @@ public:
static void hide() noexcept;
static void show() noexcept;
+
+ void subscribe(const Event &event,
+ const Subscriber &subscriber) noexcept override = 0;
+
+ void notify_subscribers(const Event &event,
+ const Context &context) const noexcept override = 0;
};
diff --git a/src/interfaces/subscriber.hpp b/src/interfaces/subscriber.hpp
index 17d87ef..6641be7 100644
--- a/src/interfaces/subscriber.hpp
+++ b/src/interfaces/subscriber.hpp
@@ -4,5 +4,7 @@ template <typename Context>
class ISubscriber
{
public:
+ virtual ~ISubscriber() = default;
+
virtual void update(const Context &context) noexcept = 0;
};