aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/commands/insert_cell.cpp24
-rw-r--r--src/commands/insert_cell.hpp20
-rw-r--r--src/commands/move_cursor.cpp37
-rw-r--r--src/commands/move_cursor.hpp27
-rw-r--r--src/commands/quit.cpp8
-rw-r--r--src/commands/quit.hpp9
-rw-r--r--src/engine/engine.cpp37
-rw-r--r--src/engine/engine.hpp6
-rw-r--r--src/engine/user/input.cpp26
-rw-r--r--src/engine/user/input.hpp13
-rw-r--r--src/game/game.cpp20
-rw-r--r--src/game/game.hpp11
-rw-r--r--src/input_actions.cpp42
-rw-r--r--src/input_actions.hpp22
-rw-r--r--src/interfaces/command.hpp9
-rw-r--r--src/interfaces/game.hpp11
-rw-r--r--src/interfaces/input.hpp8
-rw-r--r--src/interfaces/observable.hpp8
19 files changed, 223 insertions, 119 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3ad9b06..1a52ae8 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,7 +13,6 @@ file(GLOB SOURCES
bootstrap.cpp
conversion.cpp
argument_parser.cpp
- input_actions.cpp
util/color.cpp
game/game.cpp
engine/engine.cpp
@@ -26,6 +25,9 @@ file(GLOB SOURCES
engine/user/cursor.cpp
randomization/generator.cpp
randomization/seed_generator.cpp
+ commands/insert_cell.cpp
+ commands/move_cursor.cpp
+ commands/quit.cpp
DI/object_type.cpp)
add_executable(${PROJECT_NAME} ${SOURCES})
diff --git a/src/commands/insert_cell.cpp b/src/commands/insert_cell.cpp
new file mode 100644
index 0000000..86a5a52
--- /dev/null
+++ b/src/commands/insert_cell.cpp
@@ -0,0 +1,24 @@
+#include "insert_cell.hpp"
+
+#include <iostream>
+
+InsertCellCommand::InsertCellCommand(
+ const std::shared_ptr<ICursorController> &cursor_controller,
+ const std::shared_ptr<IScene> &scene) noexcept
+ : _cursor_controller(cursor_controller), _scene(scene)
+{
+}
+
+void InsertCellCommand::execute() noexcept
+{
+ const auto position = _cursor_controller->where();
+
+ std::cout.put('x');
+ std::cout.flush();
+
+ _cursor_controller->move_to(position);
+
+ auto matrix = _scene->get_matrix();
+
+ matrix->set(position - Vector2({.x = 0U, .y = 1U}), "#");
+}
diff --git a/src/commands/insert_cell.hpp b/src/commands/insert_cell.hpp
new file mode 100644
index 0000000..cf04203
--- /dev/null
+++ b/src/commands/insert_cell.hpp
@@ -0,0 +1,20 @@
+#pragma once
+
+#include "interfaces/command.hpp"
+#include "interfaces/cursor.hpp"
+#include "interfaces/scene.hpp"
+
+#include <memory>
+
+class InsertCellCommand : public ICommand
+{
+public:
+ InsertCellCommand(const std::shared_ptr<ICursorController> &cursor_controller,
+ const std::shared_ptr<IScene> &scene) noexcept;
+
+ void execute() noexcept override;
+
+private:
+ const std::shared_ptr<ICursorController> &_cursor_controller;
+ const std::shared_ptr<IScene> &_scene;
+};
diff --git a/src/commands/move_cursor.cpp b/src/commands/move_cursor.cpp
new file mode 100644
index 0000000..8dd7db7
--- /dev/null
+++ b/src/commands/move_cursor.cpp
@@ -0,0 +1,37 @@
+#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)
+
+{
+}
+
+void MoveCursorCommand::execute() noexcept
+{
+ constexpr int32_t amount = 1;
+
+ const auto new_position =
+ _cursor_controller->where().to_direction(_direction, amount);
+
+ const auto window_size = _window->size();
+
+ if (window_size.validate_coords(new_position) != CoordsValidation::VALID)
+ {
+ return;
+ }
+
+ _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
new file mode 100644
index 0000000..14a87e0
--- /dev/null
+++ b/src/commands/move_cursor.hpp
@@ -0,0 +1,27 @@
+#pragma once
+
+#include "interfaces/command.hpp"
+#include "interfaces/cursor.hpp"
+#include "interfaces/scene.hpp"
+#include "interfaces/window.hpp"
+
+#include "engine/data/vector2.hpp"
+
+#include <memory>
+
+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;
+
+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/commands/quit.cpp b/src/commands/quit.cpp
new file mode 100644
index 0000000..c2a68e7
--- /dev/null
+++ b/src/commands/quit.cpp
@@ -0,0 +1,8 @@
+#include "quit.hpp"
+
+#include <cstdlib>
+
+void QuitCommand::execute() noexcept
+{
+ exit(EXIT_SUCCESS);
+}
diff --git a/src/commands/quit.hpp b/src/commands/quit.hpp
new file mode 100644
index 0000000..cb1aefd
--- /dev/null
+++ b/src/commands/quit.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "interfaces/command.hpp"
+
+class QuitCommand : public ICommand
+{
+public:
+ void execute() noexcept override;
+};
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index afa5924..b2add9c 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -1,6 +1,5 @@
#include "engine.hpp"
-#include "input_actions.hpp"
#include "strings.hpp"
#include "util/function.hpp"
@@ -58,45 +57,23 @@ void CLIGameEngine::start() noexcept
std::cout.flush();
}));
- const std::unordered_map<char, Callback> input_config = {
- {'q', InputActions::exit_success},
- {'i',
- [this, scene]()
- {
- const auto position = _cursor_controller->where();
-
- std::cout.put('x');
- std::cout.flush();
-
- _cursor_controller->move_to(position);
-
- auto matrix = scene->get_matrix();
-
- matrix->set(position - Vector2({.x = 0U, .y = 1U}), "#");
- }},
- {'k',
- InputActions::move_cursor(Vector2::up(), _cursor_controller, scene, _window)},
- {'j',
- InputActions::move_cursor(Vector2::down(), _cursor_controller, scene, _window)},
- {'h',
- InputActions::move_cursor(Vector2::left(), _cursor_controller, scene, _window)},
- {'l', InputActions::move_cursor(Vector2::right(), _cursor_controller, scene,
- _window)}};
+ auto game = _game_factory();
- _configure_input(input_config);
+ _configure_input(game->get_input_config(_window, scene, _cursor_controller));
_input_handler->listen();
- auto game = _game_factory();
-
game->run();
}
void CLIGameEngine::_configure_input(
- const std::unordered_map<char, Callback> &input_config) noexcept
+ const std::unordered_map<char, std::shared_ptr<ICommand>> &input_config) noexcept
{
for (const auto &config_pair : input_config)
{
- _input_handler->attach(config_pair.first, config_pair.second);
+ auto key = config_pair.first;
+ auto command = config_pair.second;
+
+ _input_handler->attach(key, command);
}
}
diff --git a/src/engine/engine.hpp b/src/engine/engine.hpp
index 42cc297..32afa56 100644
--- a/src/engine/engine.hpp
+++ b/src/engine/engine.hpp
@@ -1,11 +1,11 @@
#pragma once
#include "DI/auto_wirable.hpp"
+#include "interfaces/command.hpp"
#include "interfaces/cursor.hpp"
#include "interfaces/engine.hpp"
#include "interfaces/game.hpp"
#include "interfaces/input.hpp"
-#include "interfaces/observable.hpp"
#include "interfaces/scene.hpp"
#include "interfaces/window.hpp"
@@ -33,6 +33,6 @@ private:
std::shared_ptr<ICursorController> _cursor_controller;
std::shared_ptr<IWindow> _window;
- void
- _configure_input(const std::unordered_map<char, Callback> &input_config) noexcept;
+ void _configure_input(
+ const std::unordered_map<char, std::shared_ptr<ICommand>> &input_config) noexcept;
};
diff --git a/src/engine/user/input.cpp b/src/engine/user/input.cpp
index 62aef67..f1685fd 100644
--- a/src/engine/user/input.cpp
+++ b/src/engine/user/input.cpp
@@ -12,26 +12,21 @@ void InputHandler::listen() const noexcept
}
}
-void InputHandler::attach(const char &event, Callback callback) noexcept
+void InputHandler::attach(const char &key,
+ const std::shared_ptr<ICommand> &command) noexcept
{
- if (_key_observers.count(event) == 0)
- {
- _key_observers[event] = std::vector<Callback>();
- }
+ auto key_index = _key_as_index(key);
- _key_observers[event].push_back(callback);
+ _key_commands.at(key_index).push_back(command);
}
-void InputHandler::notify(const char &event) const noexcept
+void InputHandler::notify(const char &key) const noexcept
{
- if (_key_observers.count(event) == 0)
- {
- return;
- }
+ auto key_index = _key_as_index(key);
- for (const auto &observer : _key_observers.at(event))
+ for (const auto &command : _key_commands.at(key_index))
{
- observer();
+ command->execute();
}
}
@@ -62,3 +57,8 @@ void InputHandler::leave_raw_mode() noexcept
_original_termios = nullptr;
}
+
+InputHandler::_KeyCommandsSizeType InputHandler::_key_as_index(const char &key) noexcept
+{
+ return static_cast<_KeyCommandsSizeType>(static_cast<uint8_t>(key));
+}
diff --git a/src/engine/user/input.hpp b/src/engine/user/input.hpp
index 3dd7fa9..d2aa447 100644
--- a/src/engine/user/input.hpp
+++ b/src/engine/user/input.hpp
@@ -1,9 +1,11 @@
#pragma once
#include "DI/auto_wirable.hpp"
+#include "interfaces/command.hpp"
#include "interfaces/input.hpp"
#include "interfaces/observable.hpp"
+#include <limits>
#include <memory>
#include <termios.h>
#include <unordered_map>
@@ -16,16 +18,21 @@ public:
void listen() const noexcept override;
- void attach(const char &event, Callback callback) noexcept override;
+ void attach(const char &key,
+ const std::shared_ptr<ICommand> &command) noexcept override;
- void notify(const char &event) const noexcept override;
+ void notify(const char &key) const noexcept override;
void enter_raw_mode() noexcept override;
void leave_raw_mode() noexcept override;
private:
- std::unordered_map<char, std::vector<Callback>> _key_observers;
+ std::array<std::vector<std::shared_ptr<ICommand>>, CHAR_MAX> _key_commands;
std::shared_ptr<termios> _original_termios = nullptr;
+
+ using _KeyCommandsSizeType = decltype(_key_commands)::size_type;
+
+ static _KeyCommandsSizeType _key_as_index(const char &key) noexcept;
};
diff --git a/src/game/game.cpp b/src/game/game.cpp
index d7e9056..45e6a79 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -1,3 +1,23 @@
#include "game.hpp"
+#include "commands/insert_cell.hpp"
+#include "commands/move_cursor.hpp"
+#include "commands/quit.hpp"
+
void Game::run() noexcept {}
+
+std::unordered_map<char, std::shared_ptr<ICommand>> Game::get_input_config(
+ const std::shared_ptr<IWindow> &window, const std::shared_ptr<IScene> &scene,
+ const std::shared_ptr<ICursorController> &cursor_controller) 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)},
+ {'j', std::make_shared<MoveCursorCommand>(Vector2::down(), cursor_controller,
+ scene, window)},
+ {'h', std::make_shared<MoveCursorCommand>(Vector2::left(), cursor_controller,
+ scene, window)},
+ {'l', std::make_shared<MoveCursorCommand>(Vector2::right(), cursor_controller,
+ scene, window)}};
+}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index 110b1c8..9ec5b41 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -1,7 +1,12 @@
#pragma once
#include "DI/auto_wirable.hpp"
+#include "interfaces/cursor.hpp"
#include "interfaces/game.hpp"
+#include "interfaces/scene.hpp"
+#include "interfaces/window.hpp"
+
+#include <memory>
class Game : public IGame, public AutoWirable<IGame, Game>
{
@@ -9,4 +14,10 @@ public:
Game() noexcept = default;
void run() noexcept override;
+
+ [[nodiscard]] std::unordered_map<char, std::shared_ptr<ICommand>>
+ get_input_config(const std::shared_ptr<IWindow> &window,
+ const std::shared_ptr<IScene> &scene,
+ const std::shared_ptr<ICursorController> &cursor_controller)
+ const noexcept override;
};
diff --git a/src/input_actions.cpp b/src/input_actions.cpp
deleted file mode 100644
index fa41bdd..0000000
--- a/src/input_actions.cpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#include "input_actions.hpp"
-
-#include "strings.hpp"
-
-#include <fmt/core.h>
-
-namespace InputActions
-{
-
-void exit_success() noexcept
-{
- exit(EXIT_SUCCESS);
-}
-
-Callback move_cursor(const Vector2 &direction,
- const std::shared_ptr<ICursorController> &cursor_controller,
- const std::shared_ptr<IScene> &scene,
- const std::shared_ptr<IWindow> &window) noexcept
-{
- return [direction, cursor_controller, scene, window]()
- {
- constexpr int32_t amount = 1;
-
- const auto new_position =
- cursor_controller->where().to_direction(direction, amount);
-
- const auto window_size = window->size();
-
- if (window_size.validate_coords(new_position) != CoordsValidation::VALID)
- {
- return;
- }
-
- 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())));
- };
-}
-
-} // namespace InputActions
diff --git a/src/input_actions.hpp b/src/input_actions.hpp
deleted file mode 100644
index b9c33c1..0000000
--- a/src/input_actions.hpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#pragma once
-
-#include "interfaces/cursor.hpp"
-#include "interfaces/observable.hpp"
-#include "interfaces/scene.hpp"
-#include "interfaces/window.hpp"
-
-#include "engine/data/vector2.hpp"
-
-#include <memory>
-
-namespace InputActions
-{
-
-void exit_success() noexcept;
-
-Callback move_cursor(const Vector2 &direction,
- const std::shared_ptr<ICursorController> &cursor_controller,
- const std::shared_ptr<IScene> &scene,
- const std::shared_ptr<IWindow> &window) noexcept;
-
-} // namespace InputActions
diff --git a/src/interfaces/command.hpp b/src/interfaces/command.hpp
new file mode 100644
index 0000000..245bdd6
--- /dev/null
+++ b/src/interfaces/command.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+class ICommand
+{
+public:
+ virtual ~ICommand() = default;
+
+ virtual void execute() noexcept = 0;
+};
diff --git a/src/interfaces/game.hpp b/src/interfaces/game.hpp
index 3f9d735..cfff8c5 100644
--- a/src/interfaces/game.hpp
+++ b/src/interfaces/game.hpp
@@ -1,6 +1,12 @@
#pragma once
+#include "interfaces/command.hpp"
+#include "interfaces/cursor.hpp"
+#include "interfaces/scene.hpp"
+#include "interfaces/window.hpp"
+
#include <memory>
+#include <unordered_map>
class IGame
{
@@ -8,6 +14,11 @@ public:
virtual ~IGame() = default;
virtual void run() = 0;
+
+ [[nodiscard]] virtual std::unordered_map<char, std::shared_ptr<ICommand>>
+ get_input_config(
+ const std::shared_ptr<IWindow> &window, const std::shared_ptr<IScene> &scene,
+ const std::shared_ptr<ICursorController> &cursor_controller) const noexcept = 0;
};
using IGameFactory = std::shared_ptr<IGame> (*)();
diff --git a/src/interfaces/input.hpp b/src/interfaces/input.hpp
index b243a16..82ad57c 100644
--- a/src/interfaces/input.hpp
+++ b/src/interfaces/input.hpp
@@ -1,7 +1,10 @@
#pragma once
+#include "interfaces/command.hpp"
#include "interfaces/observable.hpp"
+#include <memory>
+
class IInputHandler : public IObservable<char>
{
public:
@@ -9,9 +12,10 @@ public:
void listen() const noexcept override = 0;
- void attach(const char &event, Callback callback) noexcept override = 0;
+ void attach(const char &key,
+ const std::shared_ptr<ICommand> &command) noexcept override = 0;
- void notify(const char &event) const noexcept override = 0;
+ void notify(const char &key) const noexcept override = 0;
virtual void enter_raw_mode() noexcept = 0;
diff --git a/src/interfaces/observable.hpp b/src/interfaces/observable.hpp
index 1777b7d..21fed76 100644
--- a/src/interfaces/observable.hpp
+++ b/src/interfaces/observable.hpp
@@ -1,8 +1,9 @@
#pragma once
-#include <functional>
+#include "interfaces/command.hpp"
-using Callback = std::function<void()>;
+#include <functional>
+#include <memory>
template <typename Event>
class IObservable
@@ -12,7 +13,8 @@ public:
virtual void listen() const noexcept = 0;
- virtual void attach(const Event &event, Callback callback) noexcept = 0;
+ virtual void attach(const char &event,
+ const std::shared_ptr<ICommand> &command) noexcept = 0;
virtual void notify(const Event &event) const noexcept = 0;
};