aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-03-10 19:12:31 +0100
committerHampusM <hampus@hampusmat.com>2022-06-13 17:56:55 +0200
commit38f14606c78c119d452f302f17329455e29a9a6f (patch)
tree03f6dfd9d3576e87260f7cb3bc436ad076b629c5
parent09848ad31af6a1c70d64fccee711e231afb5a77f (diff)
refactor: rename game initializer & move input config
-rw-r--r--src/CMakeLists.txt5
-rw-r--r--src/bootstrap.cpp20
-rw-r--r--src/engine/data/bounds.cpp10
-rw-r--r--src/engine/data/bounds.hpp4
-rw-r--r--src/engine/data/vector2.cpp30
-rw-r--r--src/engine/data/vector2.hpp10
-rw-r--r--src/engine/engine.cpp67
-rw-r--r--src/engine/engine.hpp37
-rw-r--r--src/engine/game_initializer.cpp32
-rw-r--r--src/engine/game_initializer.hpp26
-rw-r--r--src/engine/graphics/window.cpp13
-rw-r--r--src/engine/graphics/window.hpp14
-rw-r--r--src/engine/user/cursor.cpp39
-rw-r--r--src/engine/user/cursor.hpp8
-rw-r--r--src/game/game.cpp13
-rw-r--r--src/game/game.hpp14
-rw-r--r--src/game/input_configurator.cpp41
-rw-r--r--src/game/input_configurator.hpp33
-rw-r--r--src/game_of_life.cpp6
-rw-r--r--src/input_actions.cpp35
-rw-r--r--src/input_actions.hpp21
-rw-r--r--src/interfaces/cursor.hpp10
-rw-r--r--src/interfaces/engine.hpp11
-rw-r--r--src/interfaces/game.hpp2
-rw-r--r--src/interfaces/game_initializer.hpp9
-rw-r--r--src/interfaces/input_configurator.hpp9
-rw-r--r--src/interfaces/scene.hpp5
-rw-r--r--src/interfaces/window.hpp9
28 files changed, 308 insertions, 225 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 304aba1..0ef0c8e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -13,12 +13,13 @@ file(GLOB SOURCES
bootstrap.cpp
conversion.cpp
argument_parser.cpp
+ input_actions.cpp
game/game.cpp
- game/input_configurator.cpp
- engine/game_initializer.cpp
+ engine/engine.cpp
engine/data/vector2.cpp
engine/data/bounds.cpp
engine/graphics/scene.cpp
+ engine/graphics/window.cpp
engine/graphics/string_matrix.cpp
engine/user/input.cpp
engine/user/cursor.cpp
diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp
index 2e64986..8aeba85 100644
--- a/src/bootstrap.cpp
+++ b/src/bootstrap.cpp
@@ -3,25 +3,25 @@
// Interfaces
#include "interfaces/argument_parser.hpp"
#include "interfaces/cursor.hpp"
+#include "interfaces/engine.hpp"
#include "interfaces/game.hpp"
-#include "interfaces/game_initializer.hpp"
#include "interfaces/input.hpp"
-#include "interfaces/input_configurator.hpp"
#include "interfaces/matrix.hpp"
#include "interfaces/randomization.hpp"
#include "interfaces/scene.hpp"
+#include "interfaces/window.hpp"
// Implementations
#include "argument_parser.hpp"
#include "engine/data/bounds.hpp"
#include "engine/data/vector2.hpp"
-#include "engine/game_initializer.hpp"
+#include "engine/engine.hpp"
#include "engine/graphics/scene.hpp"
#include "engine/graphics/string_matrix.hpp"
+#include "engine/graphics/window.hpp"
#include "engine/user/cursor.hpp"
#include "engine/user/input.hpp"
#include "game/game.hpp"
-#include "game/input_configurator.hpp"
#include "randomization/generator.hpp"
#include "randomization/seed_generator.hpp"
@@ -37,11 +37,10 @@ Container bootstrap()
container.bind<IArgumentParser>().to<ArgumentParser>();
container.bind<IGame>().to<Game>();
- container.bind<IScene>().to<Scene>();
container.bind<IInputHandler>().to<InputHandler>();
container.bind<ICursorController>().to<CursorController>();
- container.bind<IGameInitializer>().to<GameInitializer>();
- container.bind<IInputConfigurator>().to<InputConfigurator>();
+ container.bind<ICLIGameEngine>().to<CLIGameEngine>();
+ container.bind<IWindow>().to<Window>();
container.bind<IGameFactory>().to_factory(normalize_lambda(
[&container]()
@@ -70,5 +69,12 @@ Container bootstrap()
std::make_shared<StringMatrix>(bounds));
});
+ container.bind<ISceneFactory>().to_factory(normalize_lambda(
+ [&container]()
+ {
+ return std::dynamic_pointer_cast<IScene>(std::make_shared<Scene>(
+ container.get<IMatrixFactory<std::string_view>>()));
+ }));
+
return container;
}
diff --git a/src/engine/data/bounds.cpp b/src/engine/data/bounds.cpp
index acd98af..41b6dc0 100644
--- a/src/engine/data/bounds.cpp
+++ b/src/engine/data/bounds.cpp
@@ -32,11 +32,21 @@ CoordsValidation Bounds::validate_coords(const Vector2 &coords) const noexcept
return CoordsValidation::X_HIGH;
}
+ if (static_cast<uint32_t>(coords.get_x()) <= 0)
+ {
+ return CoordsValidation::X_LOW;
+ }
+
if (static_cast<uint32_t>(coords.get_y()) >= _height)
{
return CoordsValidation::Y_HIGH;
}
+ if (static_cast<uint32_t>(coords.get_y()) <= 0)
+ {
+ return CoordsValidation::Y_LOW;
+ }
+
return CoordsValidation::VALID;
}
diff --git a/src/engine/data/bounds.hpp b/src/engine/data/bounds.hpp
index b29005e..9b72f59 100644
--- a/src/engine/data/bounds.hpp
+++ b/src/engine/data/bounds.hpp
@@ -8,7 +8,9 @@ enum CoordsValidation
{
VALID,
X_HIGH,
- Y_HIGH
+ X_LOW,
+ Y_HIGH,
+ Y_LOW
};
struct BoundsOptions
diff --git a/src/engine/data/vector2.cpp b/src/engine/data/vector2.cpp
index f91afa8..04cc42e 100644
--- a/src/engine/data/vector2.cpp
+++ b/src/engine/data/vector2.cpp
@@ -24,6 +24,12 @@ void Vector2::set_y(Vector2::Value y) noexcept
_y = y;
}
+Vector2 Vector2::to_direction(const Vector2 &direction,
+ Vector2::Value amount) const noexcept
+{
+ return *this + (direction * Vector2({.x = amount, .y = amount}));
+}
+
const Vector2 &Vector2::operator+=(const Vector2 &vector2) noexcept
{
_x += vector2._x;
@@ -40,6 +46,26 @@ const Vector2 &Vector2::operator-=(const Vector2 &vector2) noexcept
return *this;
}
+Vector2 Vector2::operator+(const Vector2 &vector2) const noexcept
+{
+ auto new_vector2 = Vector2(*this);
+
+ new_vector2._x += vector2._x;
+ new_vector2._y += vector2._y;
+
+ return new_vector2;
+}
+
+Vector2 Vector2::operator*(const Vector2 &vector2) const noexcept
+{
+ auto new_vector2 = Vector2(*this);
+
+ new_vector2._x *= vector2._x;
+ new_vector2._y *= vector2._y;
+
+ return new_vector2;
+}
+
bool Vector2::operator==(const Vector2 &vector2) const noexcept
{
return _x == vector2._x && _y == vector2._y;
@@ -47,12 +73,12 @@ bool Vector2::operator==(const Vector2 &vector2) const noexcept
Vector2 Vector2::up() noexcept
{
- return Vector2({.x = 0, .y = 1});
+ return Vector2({.x = 0, .y = -1});
}
Vector2 Vector2::down() noexcept
{
- return Vector2({.x = 0, .y = -1});
+ return Vector2({.x = 0, .y = 1});
}
Vector2 Vector2::left() noexcept
diff --git a/src/engine/data/vector2.hpp b/src/engine/data/vector2.hpp
index 49e5d85..e835e65 100644
--- a/src/engine/data/vector2.hpp
+++ b/src/engine/data/vector2.hpp
@@ -27,18 +27,24 @@ public:
void set_y(Value y) noexcept;
+ [[nodiscard]] Vector2 to_direction(const Vector2 &direction,
+ Vector2::Value amount) const noexcept;
+
const Vector2 &operator+=(const Vector2 &vector2) noexcept;
const Vector2 &operator-=(const Vector2 &vector2) noexcept;
+ Vector2 operator+(const Vector2 &vector2) const noexcept;
+ Vector2 operator*(const Vector2 &vector2) const noexcept;
+
bool operator==(const Vector2 &vector2) const noexcept;
/**
- * Returns Vector2({.x = 0, .y = 1})
+ * Returns Vector2({.x = 0, .y = -1})
*/
static Vector2 up() noexcept;
/**
- * Returns Vector2({.x = 0, .y = -1})
+ * Returns Vector2({.x = 0, .y = 1})
*/
static Vector2 down() noexcept;
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
new file mode 100644
index 0000000..0227d5c
--- /dev/null
+++ b/src/engine/engine.cpp
@@ -0,0 +1,67 @@
+#include "engine.hpp"
+
+#include "input_actions.hpp"
+
+#include "util/function.hpp"
+
+#include <cstdlib>
+#include <utility>
+
+CLIGameEngine::CLIGameEngine(IGameFactory game_factory, ISceneFactory scene_factory,
+ std::shared_ptr<IInputHandler> input_handler,
+ std::shared_ptr<ICursorController> cursor_controller,
+ std::shared_ptr<IWindow> window) noexcept
+ : _game_factory(game_factory),
+ _scene_factory(scene_factory),
+ _input_handler(std::move(input_handler)),
+ _cursor_controller(std::move(cursor_controller)),
+ _window(std::move(window))
+{
+}
+
+void CLIGameEngine::start() noexcept
+{
+ auto scene = _scene_factory();
+
+ scene->enter();
+ _input_handler->enter_raw_mode();
+
+ const auto window_size = _window->size();
+
+ const auto center_position =
+ Vector2({.x = static_cast<Vector2::Value>(window_size.get_width()) / 2,
+ .y = static_cast<Vector2::Value>(window_size.get_height()) / 2});
+
+ _cursor_controller->move_to(center_position);
+
+ std::atexit(normalize_lambda(
+ [scene, this]()
+ {
+ scene->leave();
+ _input_handler->leave_raw_mode();
+ }));
+
+ const std::unordered_map<char, Callback> input_config = {
+ {'q', InputActions::exit_success},
+ {'k', InputActions::move_cursor(Vector2::up(), _cursor_controller, _window)},
+ {'j', InputActions::move_cursor(Vector2::down(), _cursor_controller, _window)},
+ {'h', InputActions::move_cursor(Vector2::left(), _cursor_controller, _window)},
+ {'l', InputActions::move_cursor(Vector2::right(), _cursor_controller, _window)}};
+
+ _configure_input(input_config);
+
+ _input_handler->listen();
+
+ auto game = _game_factory();
+
+ game->run();
+}
+
+void CLIGameEngine::_configure_input(
+ const std::unordered_map<char, Callback> &input_config)
+{
+ for (const auto &config_pair : input_config)
+ {
+ _input_handler->attach(config_pair.first, config_pair.second);
+ }
+}
diff --git a/src/engine/engine.hpp b/src/engine/engine.hpp
new file mode 100644
index 0000000..504fc28
--- /dev/null
+++ b/src/engine/engine.hpp
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "DI/auto_wirable.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"
+
+#include <memory>
+#include <unordered_map>
+
+class CLIGameEngine
+ : public ICLIGameEngine,
+ public AutoWirable<ICLIGameEngine, CLIGameEngine, IGameFactory, ISceneFactory,
+ IInputHandler, ICursorController, IWindow>
+{
+public:
+ CLIGameEngine(IGameFactory game_factory, ISceneFactory scene_factory,
+ std::shared_ptr<IInputHandler> input_handler,
+ std::shared_ptr<ICursorController> cursor_controller,
+ std::shared_ptr<IWindow> window) noexcept;
+
+ void start() noexcept override;
+
+private:
+ IGameFactory _game_factory;
+ ISceneFactory _scene_factory;
+
+ std::shared_ptr<IInputHandler> _input_handler;
+ std::shared_ptr<ICursorController> _cursor_controller;
+ std::shared_ptr<IWindow> _window;
+
+ void _configure_input(const std::unordered_map<char, Callback> &input_config);
+};
diff --git a/src/engine/game_initializer.cpp b/src/engine/game_initializer.cpp
deleted file mode 100644
index 13d9ba0..0000000
--- a/src/engine/game_initializer.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "game_initializer.hpp"
-
-#include "util/function.hpp"
-
-#include <cstdlib>
-#include <utility>
-
-GameInitializer::GameInitializer(std::shared_ptr<IScene> scene,
- std::shared_ptr<IInputHandler> input_handler,
- IGameFactory game_factory)
- : _scene(std::move(scene)),
- _input_handler(std::move(input_handler)),
- _game_factory(game_factory)
-{
-}
-
-void GameInitializer::initialize()
-{
- _scene->enter();
- _input_handler->enter_raw_mode();
-
- std::atexit(normalize_lambda(
- [this]()
- {
- _scene->leave();
- _input_handler->leave_raw_mode();
- }));
-
- auto game = _game_factory();
-
- game->run(*_scene, *_input_handler);
-}
diff --git a/src/engine/game_initializer.hpp b/src/engine/game_initializer.hpp
deleted file mode 100644
index 2f63e0f..0000000
--- a/src/engine/game_initializer.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#pragma once
-
-#include "DI/auto_wirable.hpp"
-#include "interfaces/game.hpp"
-#include "interfaces/game_initializer.hpp"
-#include "interfaces/input.hpp"
-#include "interfaces/scene.hpp"
-
-#include <memory>
-
-class GameInitializer : public IGameInitializer,
- public AutoWirable<IGameInitializer, GameInitializer, IScene,
- IInputHandler, IGameFactory>
-{
-public:
- GameInitializer(std::shared_ptr<IScene> scene,
- std::shared_ptr<IInputHandler> input_handler,
- IGameFactory game_factory);
-
- void initialize() override;
-
-private:
- std::shared_ptr<IScene> _scene;
- std::shared_ptr<IInputHandler> _input_handler;
- IGameFactory _game_factory;
-};
diff --git a/src/engine/graphics/window.cpp b/src/engine/graphics/window.cpp
new file mode 100644
index 0000000..d6bae0c
--- /dev/null
+++ b/src/engine/graphics/window.cpp
@@ -0,0 +1,13 @@
+#include "window.hpp"
+
+#include <sys/ioctl.h>
+
+Bounds Window::size() const noexcept
+{
+ winsize window_size = {};
+
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
+ ioctl(0, TIOCGWINSZ, &window_size);
+
+ return Bounds({window_size.ws_col, window_size.ws_row});
+}
diff --git a/src/engine/graphics/window.hpp b/src/engine/graphics/window.hpp
new file mode 100644
index 0000000..c9a9c70
--- /dev/null
+++ b/src/engine/graphics/window.hpp
@@ -0,0 +1,14 @@
+#pragma once
+
+#include "DI/auto_wirable.hpp"
+#include "interfaces/window.hpp"
+
+#include "engine/data/bounds.hpp"
+
+class Window : public IWindow, public AutoWirable<IWindow, Window>
+{
+public:
+ Window() noexcept = default;
+
+ [[nodiscard]] Bounds size() const noexcept override;
+};
diff --git a/src/engine/user/cursor.cpp b/src/engine/user/cursor.cpp
index 39fef23..663d56a 100644
--- a/src/engine/user/cursor.cpp
+++ b/src/engine/user/cursor.cpp
@@ -5,32 +5,17 @@
#include <cstdlib>
#include <iostream>
-CursorController::CursorController() : _position(_request_position()) {}
+CursorController::CursorController() : _position({.x = 0, .y = 0}) {}
void CursorController::move(const Vector2 &direction, const uint32_t &amount) noexcept
{
- auto format = direction_format_map.at(direction);
+ auto direction_format = direction_format_map.at(direction);
- fmt::print(fmt::runtime(format.data()), fmt::arg("esc", ESC),
+ fmt::print(fmt::runtime(direction_format.data()), fmt::arg("esc", ESC),
fmt::arg("amount", amount));
std::cout.flush();
- if (direction == Vector2::up())
- {
- _position.set_y(_position.get_y() + static_cast<int>(amount));
- }
- else if (direction == Vector2::down())
- {
- _position.set_y(_position.get_y() - static_cast<int>(amount));
- }
- else if (direction == Vector2::left())
- {
- _position.set_x(_position.get_x() - static_cast<int>(amount));
- }
- else if (direction == Vector2::right())
- {
- _position.set_x(_position.get_x() + static_cast<int>(amount));
- }
+ _position = _position.to_direction(direction, static_cast<Vector2::Value>(amount));
}
void CursorController::move_to(const Vector2 &position) noexcept
@@ -53,13 +38,7 @@ void CursorController::hide()
std::cout.flush();
}
-void CursorController::show()
-{
- fmt::print(CURSOR_VISIBLE, fmt::arg("esc", ESC));
- std::cout.flush();
-}
-
-Vector2 CursorController::_request_position() noexcept
+void CursorController::ensure_position() noexcept
{
fmt::print(REQUEST_CURSOR_POSITION, fmt::arg("esc", ESC));
std::cout.flush();
@@ -69,5 +48,11 @@ Vector2 CursorController::_request_position() noexcept
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg)
scanf("\033[%u;%uR", &vector2_options.y, &vector2_options.x);
- return Vector2(vector2_options);
+ _position = Vector2(vector2_options);
+}
+
+void CursorController::show()
+{
+ fmt::print(CURSOR_VISIBLE, fmt::arg("esc", ESC));
+ std::cout.flush();
}
diff --git a/src/engine/user/cursor.hpp b/src/engine/user/cursor.hpp
index 977bfdf..c591235 100644
--- a/src/engine/user/cursor.hpp
+++ b/src/engine/user/cursor.hpp
@@ -39,14 +39,14 @@ public:
void move_to(const Vector2 &position) noexcept override;
+ [[nodiscard]] Vector2 where() const noexcept override;
+
+ void ensure_position() noexcept override;
+
static void hide();
static void show();
- [[nodiscard]] Vector2 where() const noexcept override;
-
private:
Vector2 _position;
-
- [[nodiscard]] static Vector2 _request_position() noexcept;
};
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 0773f2c..dafa847 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -1,14 +1,3 @@
#include "game.hpp"
-#include <utility>
-
-Game::Game(std::shared_ptr<IInputConfigurator> input_configurator)
- : _input_configurator(std::move(input_configurator))
-{
-}
-
-void Game::run(IScene & /*scene*/, IInputHandler &input_handler)
-{
- _input_configurator->configure(input_handler);
- input_handler.listen();
-}
+void Game::run() {}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index ea8145a..2111026 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -2,19 +2,11 @@
#include "DI/auto_wirable.hpp"
#include "interfaces/game.hpp"
-#include "interfaces/input.hpp"
-#include "interfaces/input_configurator.hpp"
-#include "interfaces/scene.hpp"
-#include <memory>
-
-class Game : public IGame, public AutoWirable<IGame, Game, IInputConfigurator>
+class Game : public IGame, public AutoWirable<IGame, Game>
{
public:
- explicit Game(std::shared_ptr<IInputConfigurator> input_configurator);
-
- void run(IScene &scene, IInputHandler &input_handler) override;
+ Game() = default;
-private:
- std::shared_ptr<IInputConfigurator> _input_configurator;
+ void run() override;
};
diff --git a/src/game/input_configurator.cpp b/src/game/input_configurator.cpp
deleted file mode 100644
index 76e5b66..0000000
--- a/src/game/input_configurator.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "input_configurator.hpp"
-
-namespace InputActions
-{
-
-void exit_success()
-{
- exit(EXIT_SUCCESS);
-}
-
-auto move_cursor(const Vector2 &direction, ICursorController &cursor_controller)
-{
- return [direction, &cursor_controller]()
- {
- cursor_controller.move(direction, 1U);
- };
-}
-
-} // namespace InputActions
-
-InputConfigurator::InputConfigurator(std::shared_ptr<ICursorController> cursor_controller)
- : _cursor_controller(std::move(cursor_controller))
-{
-}
-
-void InputConfigurator::configure(IInputHandler &input_handler)
-{
- input_handler.attach('q', InputActions::exit_success);
-
- input_handler.attach('k',
- InputActions::move_cursor(Vector2::up(), *_cursor_controller));
-
- input_handler.attach('j',
- InputActions::move_cursor(Vector2::down(), *_cursor_controller));
-
- input_handler.attach('h',
- InputActions::move_cursor(Vector2::left(), *_cursor_controller));
-
- input_handler.attach(
- 'l', InputActions::move_cursor(Vector2::right(), *_cursor_controller));
-}
diff --git a/src/game/input_configurator.hpp b/src/game/input_configurator.hpp
deleted file mode 100644
index fa501c7..0000000
--- a/src/game/input_configurator.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include "DI/auto_wirable.hpp"
-#include "interfaces/cursor.hpp"
-#include "interfaces/input.hpp"
-#include "interfaces/input_configurator.hpp"
-
-#include "engine/data/vector2.hpp"
-
-#include <array>
-#include <memory>
-
-namespace InputActions
-{
-
-auto move_cursor(const Vector2 &direction, ICursorController &cursor_controller);
-
-void exit_success();
-
-} // namespace InputActions
-
-class InputConfigurator
- : public IInputConfigurator,
- public AutoWirable<IInputConfigurator, InputConfigurator, ICursorController>
-{
-public:
- explicit InputConfigurator(std::shared_ptr<ICursorController> cursor_controller);
-
- void configure(IInputHandler &input_handler) override;
-
-private:
- std::shared_ptr<ICursorController> _cursor_controller;
-};
diff --git a/src/game_of_life.cpp b/src/game_of_life.cpp
index 98e6b65..37e241c 100644
--- a/src/game_of_life.cpp
+++ b/src/game_of_life.cpp
@@ -1,6 +1,6 @@
#include "bootstrap.hpp"
#include "interfaces/argument_parser.hpp"
-#include "interfaces/game_initializer.hpp"
+#include "interfaces/engine.hpp"
#include "interfaces/randomization.hpp"
#include <getopt.h>
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
random_number_generator_factory(seed_generator_factory()->random_seed());
}
- auto game_initializer = container.get<IGameInitializer>();
+ auto engine = container.get<ICLIGameEngine>();
- game_initializer->initialize();
+ engine->start();
}
diff --git a/src/input_actions.cpp b/src/input_actions.cpp
new file mode 100644
index 0000000..854dc62
--- /dev/null
+++ b/src/input_actions.cpp
@@ -0,0 +1,35 @@
+#include "input_actions.hpp"
+
+#include <fmt/core.h>
+
+namespace InputActions
+{
+
+void exit_success()
+{
+ exit(EXIT_SUCCESS);
+}
+
+Callback move_cursor(const Vector2 &direction,
+ const std::shared_ptr<ICursorController> &cursor_controller,
+ const std::shared_ptr<IWindow> &window)
+{
+ return [direction, cursor_controller, 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);
+ };
+}
+
+} // namespace InputActions
diff --git a/src/input_actions.hpp b/src/input_actions.hpp
new file mode 100644
index 0000000..8283d78
--- /dev/null
+++ b/src/input_actions.hpp
@@ -0,0 +1,21 @@
+#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
+{
+
+Callback move_cursor(const Vector2 &direction,
+ const std::shared_ptr<ICursorController> &cursor_controller,
+ const std::shared_ptr<IWindow> &window);
+
+void exit_success();
+
+} // namespace InputActions
diff --git a/src/interfaces/cursor.hpp b/src/interfaces/cursor.hpp
index adab524..77c5096 100644
--- a/src/interfaces/cursor.hpp
+++ b/src/interfaces/cursor.hpp
@@ -2,16 +2,22 @@
#include "engine/data/vector2.hpp"
+#include <memory>
+
class ICursorController
{
public:
+ virtual ~ICursorController() noexcept = default;
+
virtual void move(const Vector2 &direction, const uint32_t &amount) noexcept = 0;
virtual void move_to(const Vector2 &position) noexcept = 0;
[[nodiscard]] virtual Vector2 where() const noexcept = 0;
- static void hide();
+ virtual void ensure_position() noexcept = 0;
+
+ static void hide() noexcept;
- static void show();
+ static void show() noexcept;
};
diff --git a/src/interfaces/engine.hpp b/src/interfaces/engine.hpp
new file mode 100644
index 0000000..498ff41
--- /dev/null
+++ b/src/interfaces/engine.hpp
@@ -0,0 +1,11 @@
+#pragma once
+
+#include "interfaces/observable.hpp"
+
+#include <unordered_map>
+
+class ICLIGameEngine
+{
+public:
+ virtual void start() noexcept = 0;
+};
diff --git a/src/interfaces/game.hpp b/src/interfaces/game.hpp
index 85c20e5..338a8a3 100644
--- a/src/interfaces/game.hpp
+++ b/src/interfaces/game.hpp
@@ -10,7 +10,7 @@ class IGame
public:
virtual ~IGame() = default;
- virtual void run(IScene &scene, IInputHandler &input_handler) = 0;
+ virtual void run() = 0;
};
using IGameFactory = std::shared_ptr<IGame> (*)();
diff --git a/src/interfaces/game_initializer.hpp b/src/interfaces/game_initializer.hpp
deleted file mode 100644
index 5dea2e9..0000000
--- a/src/interfaces/game_initializer.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include "interfaces/game.hpp"
-
-class IGameInitializer
-{
-public:
- virtual void initialize() = 0;
-};
diff --git a/src/interfaces/input_configurator.hpp b/src/interfaces/input_configurator.hpp
deleted file mode 100644
index 2bfe51e..0000000
--- a/src/interfaces/input_configurator.hpp
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-
-#include "interfaces/input.hpp"
-
-class IInputConfigurator
-{
-public:
- virtual void configure(IInputHandler &input_handler) = 0;
-};
diff --git a/src/interfaces/scene.hpp b/src/interfaces/scene.hpp
index 39110a2..ca494cb 100644
--- a/src/interfaces/scene.hpp
+++ b/src/interfaces/scene.hpp
@@ -1,8 +1,9 @@
#pragma once
+#include "interfaces/cursor.hpp"
#include "interfaces/matrix.hpp"
+#include "interfaces/window.hpp"
-#include <functional>
#include <memory>
#include <string_view>
@@ -15,3 +16,5 @@ public:
virtual void leave() = 0;
};
+
+using ISceneFactory = std::shared_ptr<IScene> (*)();
diff --git a/src/interfaces/window.hpp b/src/interfaces/window.hpp
new file mode 100644
index 0000000..5da9aff
--- /dev/null
+++ b/src/interfaces/window.hpp
@@ -0,0 +1,9 @@
+#pragma once
+
+#include "engine/data/bounds.hpp"
+
+class IWindow
+{
+public:
+ [[nodiscard]] virtual Bounds size() const noexcept = 0;
+};