diff options
author | HampusM <hampus@hampusmat.com> | 2022-03-03 19:41:23 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-06-13 17:56:54 +0200 |
commit | 93123e97251fc791c1cac193d675cce9a1ac2de6 (patch) | |
tree | 4486453695d6f715e767bd91bcee89c92f54f7ba /src | |
parent | 70b21e90d7be4d892b7d17440d64630e7ee1a575 (diff) |
feat: add moving cursor
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/bootstrap.cpp | 2 | ||||
-rw-r--r-- | src/engine/escape.hpp | 5 | ||||
-rw-r--r-- | src/engine/graphics/scene.cpp | 26 | ||||
-rw-r--r-- | src/engine/graphics/scene.hpp | 2 | ||||
-rw-r--r-- | src/engine/user/cursor.cpp | 43 | ||||
-rw-r--r-- | src/engine/user/cursor.hpp | 45 | ||||
-rw-r--r-- | src/engine/user/cursor.tpp | 31 | ||||
-rw-r--r-- | src/game/game.cpp | 35 | ||||
-rw-r--r-- | src/game/game.hpp | 9 | ||||
-rw-r--r-- | src/interfaces/direction.hpp | 13 |
11 files changed, 183 insertions, 29 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ce32a1..13d0ce4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -19,6 +19,7 @@ file(GLOB SOURCES engine/graphics/scene.cpp engine/graphics/string_matrix.cpp engine/user/input.cpp + engine/user/cursor.cpp randomization/generator.cpp randomization/seed_generator.cpp DI/object_type.cpp) diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp index 6b4a954..bd2cbbd 100644 --- a/src/bootstrap.cpp +++ b/src/bootstrap.cpp @@ -16,6 +16,7 @@ #include "engine/graphics/scene.hpp" #include "engine/graphics/string_matrix.hpp" #include "engine/graphics/vector2.hpp" +#include "engine/user/cursor.hpp" #include "engine/user/input.hpp" #include "game/game.hpp" #include "randomization/generator.hpp" @@ -33,6 +34,7 @@ Container bootstrap() container.bind<IGame>().to<Game>(); container.bind<IScene>().to<Scene>(); container.bind<IInputHandler>().to<InputHandler>(); + container.bind<CursorController>().to<CursorController>(); container.bind<IRandomNumberGeneratorFactory>().to_factory( [](const unsigned int &seed) diff --git a/src/engine/escape.hpp b/src/engine/escape.hpp new file mode 100644 index 0000000..53a7c98 --- /dev/null +++ b/src/engine/escape.hpp @@ -0,0 +1,5 @@ +#pragma once + +#include <fmt/core.h> + +constexpr fmt::string_view ESC = "\x1B"; diff --git a/src/engine/graphics/scene.cpp b/src/engine/graphics/scene.cpp index 3f63807..a8e7b88 100644 --- a/src/engine/graphics/scene.cpp +++ b/src/engine/graphics/scene.cpp @@ -1,10 +1,12 @@ #include "scene.hpp" +#include "engine/escape.hpp" + #include <fmt/core.h> #include <iostream> Scene::Scene(IMatrixFactory<std::string_view> matrix_factory) - : _is_shown(false), _matrix_factory(std::move(matrix_factory)) + : _is_shown(false), _matrix_factory(matrix_factory) { } @@ -33,25 +35,3 @@ void Scene::leave() _is_shown = false; } - -/* -void do_in_statusbar(const std::function<void()> &routine) -{ - const auto prev_pos = Cursor::where(); - - const auto window_size = Window::size(); - - Cursor::hide(); - - Cursor::move_to(Vector2({1, window_size.height()})); - - std::cout << fmt::format(EscapeSequences::ERASE_LINE, fmt::arg("esc", ESC)); - std::cout.flush(); - - routine(); - - Cursor::move_to(prev_pos); - - Cursor::show(); -} -*/ diff --git a/src/engine/graphics/scene.hpp b/src/engine/graphics/scene.hpp index b26ac05..c4c217f 100644 --- a/src/engine/graphics/scene.hpp +++ b/src/engine/graphics/scene.hpp @@ -7,8 +7,6 @@ #include <fmt/core.h> #include <string_view> -constexpr fmt::string_view ESC = "\x1B"; - constexpr fmt::string_view ENABLE_ALT_BUFFER = "{esc}[?1049h"; constexpr fmt::string_view DISABLE_ALT_BUFFER = "{esc}[?1049l"; diff --git a/src/engine/user/cursor.cpp b/src/engine/user/cursor.cpp new file mode 100644 index 0000000..9d6e28c --- /dev/null +++ b/src/engine/user/cursor.cpp @@ -0,0 +1,43 @@ +#include "cursor.hpp" + +#include "engine/escape.hpp" + +#include <cstdlib> +#include <iostream> + +CursorController::CursorController(IVector2Factory vector2_factory) + : _vector2_factory(vector2_factory) +{ +} + +void CursorController::move_to(const IVector2 &pos) +{ + fmt::print(MOVE_CURSOR_TO, fmt::arg("esc", ESC), fmt::arg("row", pos.y()), + fmt::arg("column", pos.x())); + std::cout.flush(); +} + +std::shared_ptr<IVector2> CursorController::where() +{ + fmt::print(REQUEST_CURSOR_POSITION, fmt::arg("esc", ESC)); + std::cout.flush(); + + IVector2Options vector2_options = {}; + + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-vararg) + scanf("\033[%u;%uR", &vector2_options.y, &vector2_options.x); + + return _vector2_factory(vector2_options); +} + +void CursorController::hide() +{ + fmt::print(CURSOR_INVISIBLE, fmt::arg("esc", ESC)); + std::cout.flush(); +} + +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 new file mode 100644 index 0000000..0317dc5 --- /dev/null +++ b/src/engine/user/cursor.hpp @@ -0,0 +1,45 @@ +#pragma once + +#include "DI/auto_wirable.hpp" +#include "interfaces/direction.hpp" +#include "interfaces/vector2.hpp" + +#include "fmt/core.h" +#include <array> +#include <memory> +#include <unordered_map> + +constexpr std::string_view MOVE_CURSOR_UP = "{esc}[{amount}A"; +constexpr std::string_view MOVE_CURSOR_DOWN = "{esc}[{amount}B"; +constexpr std::string_view MOVE_CURSOR_LEFT = "{esc}[{amount}D"; +constexpr std::string_view MOVE_CURSOR_RIGHT = "{esc}[{amount}C"; + +constexpr fmt::string_view MOVE_CURSOR_TO = "{esc}[{row};{column}H"; + +constexpr fmt::string_view REQUEST_CURSOR_POSITION = "{esc}[6n"; + +constexpr fmt::string_view CURSOR_VISIBLE = "{esc}[?25h"; +constexpr fmt::string_view CURSOR_INVISIBLE = "{esc}[?25l"; + +class CursorController + : public AutoWirable<CursorController, CursorController, IVector2Factory> +{ +public: + explicit CursorController(IVector2Factory vector2_factory); + + template <Direction::value_type direction> + constexpr void move(const unsigned int &amount) const; + + static void move_to(const IVector2 &pos); + + static void hide(); + + static void show(); + + [[nodiscard]] std::shared_ptr<IVector2> where(); + +private: + IVector2Factory _vector2_factory; +}; + +#include "cursor.tpp" diff --git a/src/engine/user/cursor.tpp b/src/engine/user/cursor.tpp new file mode 100644 index 0000000..224418e --- /dev/null +++ b/src/engine/user/cursor.tpp @@ -0,0 +1,31 @@ +#pragma once + +#include "cursor.hpp" + +#include "engine/escape.hpp" + +#include <iostream> + +constexpr auto get_direction_format_map() +{ + std::array<std::string_view, 4> direction_format_map; + + direction_format_map[Direction::UP] = MOVE_CURSOR_UP; + direction_format_map[Direction::DOWN] = MOVE_CURSOR_DOWN; + direction_format_map[Direction::LEFT] = MOVE_CURSOR_LEFT; + direction_format_map[Direction::RIGHT] = MOVE_CURSOR_RIGHT; + + return direction_format_map; +} + +template <Direction::value_type direction> +constexpr void CursorController::move(const unsigned int &amount) const +{ + constexpr auto direction_format_map = get_direction_format_map(); + + constexpr auto format = direction_format_map[direction]; + + fmt::vprint(format, + fmt::make_format_args(fmt::arg("esc", ESC), fmt::arg("amount", amount))); + std::cout.flush(); +} diff --git a/src/game/game.cpp b/src/game/game.cpp index 2b09470..ee3a2b8 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -1,7 +1,12 @@ #include "game.hpp" -Game::Game(std::shared_ptr<IScene> scene, std::shared_ptr<IInputHandler> input_handler) - : _scene(std::move(scene)), _input_handler(std::move(input_handler)) +#include <utility> + +Game::Game(std::shared_ptr<IScene> scene, std::shared_ptr<IInputHandler> input_handler, + std::shared_ptr<CursorController> cursor_controller) + : _scene(std::move(scene)), + _input_handler(std::move(input_handler)), + _cursor_controller(std::move(cursor_controller)) { } @@ -22,6 +27,32 @@ void Game::run() exit(EXIT_SUCCESS); }); + auto cursor_controller = _cursor_controller; + + _input_handler->attach('k', + [&cursor_controller]() + { + cursor_controller->move<Direction::UP>(1U); + }); + + _input_handler->attach('j', + [&cursor_controller]() + { + cursor_controller->move<Direction::DOWN>(1U); + }); + + _input_handler->attach('h', + [&cursor_controller]() + { + cursor_controller->move<Direction::LEFT>(1U); + }); + + _input_handler->attach('l', + [&cursor_controller]() + { + cursor_controller->move<Direction::RIGHT>(1U); + }); + _input_handler->listen(); _scene->leave(); diff --git a/src/game/game.hpp b/src/game/game.hpp index bc37c91..dd0d3c8 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -5,17 +5,22 @@ #include "interfaces/input.hpp" #include "interfaces/scene.hpp" +#include "engine/user/cursor.hpp" + #include <memory> -class Game : public IGame, public AutoWirable<IGame, Game, IScene, IInputHandler> +class Game : public IGame, + public AutoWirable<IGame, Game, IScene, IInputHandler, CursorController> { public: explicit Game(std::shared_ptr<IScene> scene, - std::shared_ptr<IInputHandler> input_handler); + std::shared_ptr<IInputHandler> input_handler, + std::shared_ptr<CursorController> cursor_controller); void run() override; private: std::shared_ptr<IScene> _scene; std::shared_ptr<IInputHandler> _input_handler; + std::shared_ptr<CursorController> _cursor_controller; }; diff --git a/src/interfaces/direction.hpp b/src/interfaces/direction.hpp new file mode 100644 index 0000000..233f17d --- /dev/null +++ b/src/interfaces/direction.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include <cstddef> + +struct Direction +{ + using value_type = std::size_t; + + static constexpr value_type UP = 0U; + static constexpr value_type DOWN = 1U; + static constexpr value_type LEFT = 2U; + static constexpr value_type RIGHT = 3U; +}; |