aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-03-03 19:41:23 +0100
committerHampusM <hampus@hampusmat.com>2022-06-13 17:56:54 +0200
commit93123e97251fc791c1cac193d675cce9a1ac2de6 (patch)
tree4486453695d6f715e767bd91bcee89c92f54f7ba
parent70b21e90d7be4d892b7d17440d64630e7ee1a575 (diff)
feat: add moving cursor
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/bootstrap.cpp2
-rw-r--r--src/engine/escape.hpp5
-rw-r--r--src/engine/graphics/scene.cpp26
-rw-r--r--src/engine/graphics/scene.hpp2
-rw-r--r--src/engine/user/cursor.cpp43
-rw-r--r--src/engine/user/cursor.hpp45
-rw-r--r--src/engine/user/cursor.tpp31
-rw-r--r--src/game/game.cpp35
-rw-r--r--src/game/game.hpp9
-rw-r--r--src/interfaces/direction.hpp13
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;
+};