From 38f14606c78c119d452f302f17329455e29a9a6f Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 10 Mar 2022 19:12:31 +0100 Subject: refactor: rename game initializer & move input config --- src/engine/data/bounds.cpp | 10 ++++++ src/engine/data/bounds.hpp | 4 ++- src/engine/data/vector2.cpp | 30 ++++++++++++++++-- src/engine/data/vector2.hpp | 10 ++++-- src/engine/engine.cpp | 67 +++++++++++++++++++++++++++++++++++++++++ src/engine/engine.hpp | 37 +++++++++++++++++++++++ src/engine/game_initializer.cpp | 32 -------------------- src/engine/game_initializer.hpp | 26 ---------------- src/engine/graphics/window.cpp | 13 ++++++++ src/engine/graphics/window.hpp | 14 +++++++++ src/engine/user/cursor.cpp | 39 ++++++++---------------- src/engine/user/cursor.hpp | 8 ++--- 12 files changed, 196 insertions(+), 94 deletions(-) create mode 100644 src/engine/engine.cpp create mode 100644 src/engine/engine.hpp delete mode 100644 src/engine/game_initializer.cpp delete mode 100644 src/engine/game_initializer.hpp create mode 100644 src/engine/graphics/window.cpp create mode 100644 src/engine/graphics/window.hpp (limited to 'src/engine') 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(coords.get_x()) <= 0) + { + return CoordsValidation::X_LOW; + } + if (static_cast(coords.get_y()) >= _height) { return CoordsValidation::Y_HIGH; } + if (static_cast(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 +#include + +CLIGameEngine::CLIGameEngine(IGameFactory game_factory, ISceneFactory scene_factory, + std::shared_ptr input_handler, + std::shared_ptr cursor_controller, + std::shared_ptr 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(window_size.get_width()) / 2, + .y = static_cast(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 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 &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 +#include + +class CLIGameEngine + : public ICLIGameEngine, + public AutoWirable +{ +public: + CLIGameEngine(IGameFactory game_factory, ISceneFactory scene_factory, + std::shared_ptr input_handler, + std::shared_ptr cursor_controller, + std::shared_ptr window) noexcept; + + void start() noexcept override; + +private: + IGameFactory _game_factory; + ISceneFactory _scene_factory; + + std::shared_ptr _input_handler; + std::shared_ptr _cursor_controller; + std::shared_ptr _window; + + void _configure_input(const std::unordered_map &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 -#include - -GameInitializer::GameInitializer(std::shared_ptr scene, - std::shared_ptr 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 - -class GameInitializer : public IGameInitializer, - public AutoWirable -{ -public: - GameInitializer(std::shared_ptr scene, - std::shared_ptr input_handler, - IGameFactory game_factory); - - void initialize() override; - -private: - std::shared_ptr _scene; - std::shared_ptr _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 + +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 +{ +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 #include -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(amount)); - } - else if (direction == Vector2::down()) - { - _position.set_y(_position.get_y() - static_cast(amount)); - } - else if (direction == Vector2::left()) - { - _position.set_x(_position.get_x() - static_cast(amount)); - } - else if (direction == Vector2::right()) - { - _position.set_x(_position.get_x() + static_cast(amount)); - } + _position = _position.to_direction(direction, static_cast(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; }; -- cgit v1.2.3-18-g5258