aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/bootstrap.cpp3
-rw-r--r--src/engine/user/input.cpp64
-rw-r--r--src/engine/user/input.hpp31
-rw-r--r--src/game/game.cpp23
-rw-r--r--src/game/game.hpp7
-rw-r--r--src/interfaces/input.hpp17
-rw-r--r--src/interfaces/observable.hpp16
8 files changed, 155 insertions, 7 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 385283d..54793b0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -18,6 +18,7 @@ file(GLOB SOURCES
engine/graphics/bounds.cpp
engine/graphics/scene.cpp
engine/graphics/string_matrix.cpp
+ engine/user/input.cpp
randomization/generator.cpp
randomization/seed_generator.cpp
DI/object_type.cpp)
diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp
index 8a8aa25..6b4a954 100644
--- a/src/bootstrap.cpp
+++ b/src/bootstrap.cpp
@@ -4,6 +4,7 @@
#include "interfaces/argument_parser.hpp"
#include "interfaces/bounds.hpp"
#include "interfaces/game.hpp"
+#include "interfaces/input.hpp"
#include "interfaces/matrix.hpp"
#include "interfaces/randomization.hpp"
#include "interfaces/scene.hpp"
@@ -15,6 +16,7 @@
#include "engine/graphics/scene.hpp"
#include "engine/graphics/string_matrix.hpp"
#include "engine/graphics/vector2.hpp"
+#include "engine/user/input.hpp"
#include "game/game.hpp"
#include "randomization/generator.hpp"
#include "randomization/seed_generator.hpp"
@@ -30,6 +32,7 @@ Container bootstrap()
container.bind<IArgumentParser>().to<ArgumentParser>();
container.bind<IGame>().to<Game>();
container.bind<IScene>().to<Scene>();
+ container.bind<IInputHandler>().to<InputHandler>();
container.bind<IRandomNumberGeneratorFactory>().to_factory(
[](const unsigned int &seed)
diff --git a/src/engine/user/input.cpp b/src/engine/user/input.cpp
new file mode 100644
index 0000000..e68f303
--- /dev/null
+++ b/src/engine/user/input.cpp
@@ -0,0 +1,64 @@
+#include "input.hpp"
+
+#include <unistd.h>
+
+void InputHandler::listen() const
+{
+ char character = 0;
+
+ while (read(STDIN_FILENO, &character, 1) == 1)
+ {
+ notify(character);
+ }
+}
+
+void InputHandler::attach(const char &event, Callback callback)
+{
+ if (_key_observers.count(event) == 0)
+ {
+ _key_observers[event] = std::vector<Callback>();
+ }
+
+ _key_observers[event].push_back(callback);
+}
+
+void InputHandler::notify(const char &event) const
+{
+ if (_key_observers.count(event) == 0)
+ {
+ return;
+ }
+
+ for (const auto &observer : _key_observers.at(event))
+ {
+ observer();
+ }
+}
+
+void InputHandler::enter_raw_mode()
+{
+ if (_original_termios == nullptr)
+ {
+ _original_termios = std::make_shared<termios>();
+ }
+
+ tcgetattr(STDIN_FILENO, _original_termios.get());
+
+ auto raw_termios = termios(*_original_termios);
+
+ raw_termios.c_lflag &= static_cast<unsigned int>(~(ECHO | ICANON | ISIG));
+
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw_termios);
+}
+
+void InputHandler::leave_raw_mode()
+{
+ if (_original_termios == nullptr)
+ {
+ return;
+ }
+
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, _original_termios.get());
+
+ _original_termios = nullptr;
+}
diff --git a/src/engine/user/input.hpp b/src/engine/user/input.hpp
new file mode 100644
index 0000000..f48ab86
--- /dev/null
+++ b/src/engine/user/input.hpp
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "DI/auto_wirable.hpp"
+#include "interfaces/input.hpp"
+#include "interfaces/observable.hpp"
+
+#include <memory>
+#include <termios.h>
+#include <unordered_map>
+#include <vector>
+
+class InputHandler : public IInputHandler, public AutoWirable<IInputHandler, InputHandler>
+{
+public:
+ InputHandler() = default;
+
+ void listen() const override;
+
+ void attach(const char &event, Callback callback) override;
+
+ void notify(const char &event) const override;
+
+ void enter_raw_mode() override;
+
+ void leave_raw_mode() override;
+
+private:
+ std::unordered_map<char, std::vector<Callback>> _key_observers;
+
+ std::shared_ptr<termios> _original_termios = nullptr;
+};
diff --git a/src/game/game.cpp b/src/game/game.cpp
index 2c99c6a..2b09470 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -1,15 +1,28 @@
#include "game.hpp"
-#include <chrono>
-#include <thread>
-
-Game::Game(std::shared_ptr<IScene> scene) : _scene(std::move(scene)) {}
+Game::Game(std::shared_ptr<IScene> scene, std::shared_ptr<IInputHandler> input_handler)
+ : _scene(std::move(scene)), _input_handler(std::move(input_handler))
+{
+}
void Game::run()
{
_scene->enter();
- std::this_thread::sleep_for(std::chrono::seconds(3));
+ _input_handler->enter_raw_mode();
+
+ auto scene = _scene;
+ auto input_handler = _input_handler;
+
+ _input_handler->attach('q',
+ [&input_handler, &scene]()
+ {
+ input_handler->leave_raw_mode();
+ scene->leave();
+ exit(EXIT_SUCCESS);
+ });
+
+ _input_handler->listen();
_scene->leave();
}
diff --git a/src/game/game.hpp b/src/game/game.hpp
index e7d91d6..bc37c91 100644
--- a/src/game/game.hpp
+++ b/src/game/game.hpp
@@ -2,17 +2,20 @@
#include "DI/auto_wirable.hpp"
#include "interfaces/game.hpp"
+#include "interfaces/input.hpp"
#include "interfaces/scene.hpp"
#include <memory>
-class Game : public IGame, public AutoWirable<IGame, Game, IScene>
+class Game : public IGame, public AutoWirable<IGame, Game, IScene, IInputHandler>
{
public:
- explicit Game(std::shared_ptr<IScene> scene);
+ explicit Game(std::shared_ptr<IScene> scene,
+ std::shared_ptr<IInputHandler> input_handler);
void run() override;
private:
std::shared_ptr<IScene> _scene;
+ std::shared_ptr<IInputHandler> _input_handler;
};
diff --git a/src/interfaces/input.hpp b/src/interfaces/input.hpp
new file mode 100644
index 0000000..956ec4f
--- /dev/null
+++ b/src/interfaces/input.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include "interfaces/observable.hpp"
+
+class IInputHandler : public IObservable<char>
+{
+public:
+ void listen() const override = 0;
+
+ void attach(const char &event, Callback callback) override = 0;
+
+ void notify(const char &event) const override = 0;
+
+ virtual void enter_raw_mode() = 0;
+
+ virtual void leave_raw_mode() = 0;
+};
diff --git a/src/interfaces/observable.hpp b/src/interfaces/observable.hpp
new file mode 100644
index 0000000..ca8ffda
--- /dev/null
+++ b/src/interfaces/observable.hpp
@@ -0,0 +1,16 @@
+#pragma once
+
+#include <functional>
+
+using Callback = std::function<void()>;
+
+template <typename Event>
+class IObservable
+{
+public:
+ virtual void listen() const = 0;
+
+ virtual void attach(const Event &event, Callback callback) = 0;
+
+ virtual void notify(const Event &event) const = 0;
+};