diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/bootstrap.cpp | 3 | ||||
-rw-r--r-- | src/engine/game_initializer.cpp | 11 | ||||
-rw-r--r-- | src/game/game.cpp | 41 | ||||
-rw-r--r-- | src/game/game.hpp | 9 | ||||
-rw-r--r-- | src/game/input_configurator.cpp | 33 | ||||
-rw-r--r-- | src/game/input_configurator.hpp | 36 | ||||
-rw-r--r-- | src/game/input_configurator.tpp | 17 | ||||
-rw-r--r-- | src/interfaces/input_configurator.hpp | 9 | ||||
-rw-r--r-- | src/util/function.hpp | 11 | ||||
-rw-r--r-- | src/util/function.tpp | 75 |
11 files changed, 203 insertions, 43 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3351c07..e9b8fee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ file(GLOB SOURCES conversion.cpp argument_parser.cpp game/game.cpp + game/input_configurator.cpp engine/game_initializer.cpp engine/graphics/vector2.cpp engine/graphics/bounds.cpp diff --git a/src/bootstrap.cpp b/src/bootstrap.cpp index abee66e..343f01b 100644 --- a/src/bootstrap.cpp +++ b/src/bootstrap.cpp @@ -6,6 +6,7 @@ #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" @@ -21,6 +22,7 @@ #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" @@ -38,6 +40,7 @@ Container bootstrap() container.bind<IInputHandler>().to<InputHandler>(); container.bind<CursorController>().to<CursorController>(); container.bind<IGameInitializer>().to<GameInitializer>(); + container.bind<IInputConfigurator>().to<InputConfigurator>(); container.bind<IRandomNumberGeneratorFactory>().to_factory( [](const unsigned int &seed) diff --git a/src/engine/game_initializer.cpp b/src/engine/game_initializer.cpp index 9430999..52e109a 100644 --- a/src/engine/game_initializer.cpp +++ b/src/engine/game_initializer.cpp @@ -1,5 +1,8 @@ #include "game_initializer.hpp" +#include "util/function.hpp" + +#include <cstdlib> #include <utility> GameInitializer::GameInitializer(std::shared_ptr<IScene> scene, @@ -14,8 +17,14 @@ GameInitializer::GameInitializer(std::shared_ptr<IScene> scene, void GameInitializer::initialize() { _scene->enter(); - _input_handler->enter_raw_mode(); + std::atexit(normalize_lambda( + [this]() + { + _scene->leave(); + _input_handler->leave_raw_mode(); + })); + _game->run(*_scene, *_input_handler); } diff --git a/src/game/game.cpp b/src/game/game.cpp index 559f9a0..0773f2c 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -2,46 +2,13 @@ #include <utility> -Game::Game(std::shared_ptr<CursorController> cursor_controller) - : _cursor_controller(std::move(cursor_controller)) +Game::Game(std::shared_ptr<IInputConfigurator> input_configurator) + : _input_configurator(std::move(input_configurator)) { } -void Game::run(IScene &scene, IInputHandler &input_handler) +void Game::run(IScene & /*scene*/, IInputHandler &input_handler) { - input_handler.attach('q', - [&input_handler, &scene]() - { - input_handler.leave_raw_mode(); - scene.leave(); - 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_configurator->configure(input_handler); input_handler.listen(); } diff --git a/src/game/game.hpp b/src/game/game.hpp index c52399d..ea8145a 100644 --- a/src/game/game.hpp +++ b/src/game/game.hpp @@ -3,19 +3,18 @@ #include "DI/auto_wirable.hpp" #include "interfaces/game.hpp" #include "interfaces/input.hpp" +#include "interfaces/input_configurator.hpp" #include "interfaces/scene.hpp" -#include "engine/user/cursor.hpp" - #include <memory> -class Game : public IGame, public AutoWirable<IGame, Game, CursorController> +class Game : public IGame, public AutoWirable<IGame, Game, IInputConfigurator> { public: - explicit Game(std::shared_ptr<CursorController> cursor_controller); + explicit Game(std::shared_ptr<IInputConfigurator> input_configurator); void run(IScene &scene, IInputHandler &input_handler) override; private: - std::shared_ptr<CursorController> _cursor_controller; + std::shared_ptr<IInputConfigurator> _input_configurator; }; diff --git a/src/game/input_configurator.cpp b/src/game/input_configurator.cpp new file mode 100644 index 0000000..4daee21 --- /dev/null +++ b/src/game/input_configurator.cpp @@ -0,0 +1,33 @@ +#include "input_configurator.hpp" + +namespace InputActions +{ + +void exit_success() +{ + exit(EXIT_SUCCESS); +} + +} // namespace InputActions + +InputConfigurator::InputConfigurator(std::shared_ptr<CursorController> 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<Direction::UP>(*_cursor_controller)); + + input_handler.attach('j', + InputActions::move_cursor<Direction::DOWN>(*_cursor_controller)); + + input_handler.attach('h', + InputActions::move_cursor<Direction::LEFT>(*_cursor_controller)); + + input_handler.attach( + 'l', InputActions::move_cursor<Direction::RIGHT>(*_cursor_controller)); +} diff --git a/src/game/input_configurator.hpp b/src/game/input_configurator.hpp new file mode 100644 index 0000000..217c21e --- /dev/null +++ b/src/game/input_configurator.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "DI/auto_wirable.hpp" +#include "interfaces/direction.hpp" +#include "interfaces/input.hpp" +#include "interfaces/input_configurator.hpp" + +#include "engine/user/cursor.hpp" + +#include <array> +#include <memory> + +namespace InputActions +{ + +template <Direction::value_type direction> +auto move_cursor(CursorController cursor_controller); + +void exit_success(); + +} // namespace InputActions + +class InputConfigurator + : public IInputConfigurator, + public AutoWirable<IInputConfigurator, InputConfigurator, CursorController> +{ +public: + explicit InputConfigurator(std::shared_ptr<CursorController> cursor_controller); + + void configure(IInputHandler &input_handler) override; + +private: + std::shared_ptr<CursorController> _cursor_controller; +}; + +#include "input_configurator.tpp" diff --git a/src/game/input_configurator.tpp b/src/game/input_configurator.tpp new file mode 100644 index 0000000..f3c9482 --- /dev/null +++ b/src/game/input_configurator.tpp @@ -0,0 +1,17 @@ +#pragma once + +#include "input_configurator.hpp" + +namespace InputActions +{ + +template <Direction::value_type direction> +auto move_cursor(CursorController cursor_controller) +{ + return [cursor_controller]() + { + cursor_controller.move<direction>(1U); + }; +} + +} // namespace InputActions diff --git a/src/interfaces/input_configurator.hpp b/src/interfaces/input_configurator.hpp new file mode 100644 index 0000000..2bfe51e --- /dev/null +++ b/src/interfaces/input_configurator.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include "interfaces/input.hpp" + +class IInputConfigurator +{ +public: + virtual void configure(IInputHandler &input_handler) = 0; +}; diff --git a/src/util/function.hpp b/src/util/function.hpp new file mode 100644 index 0000000..13f5356 --- /dev/null +++ b/src/util/function.hpp @@ -0,0 +1,11 @@ +#pragma once + +template <typename> +struct Signature +{ +}; + +template <typename Function> +constexpr auto normalize_lambda(Function &&func) noexcept; + +#include "function.tpp" diff --git a/src/util/function.tpp b/src/util/function.tpp new file mode 100644 index 0000000..6ff939b --- /dev/null +++ b/src/util/function.tpp @@ -0,0 +1,75 @@ +#pragma once + +#include "function.hpp" + +#include <utility> + +template <typename> +struct remove_cv_seq; + +template <typename Return, typename... Args> +struct remove_cv_seq<Return(Args...)> +{ + using type = Return(Args...); +}; + +template <typename Return, typename... Args> +struct remove_cv_seq<Return(Args...) const> +{ + using type = Return(Args...); +}; + +template <typename Return, typename... Args> +struct remove_cv_seq<Return(Args...) &> +{ + using type = Return(Args...); +}; + +template <typename Function> +constexpr inline auto extract_signature(Function * /*unused*/) noexcept +{ + return Signature<typename remove_cv_seq<Function>::type>(); +} + +template <typename Class, typename Function> +constexpr inline auto extract_signature(Function Class::* /*unused*/) noexcept +{ + return Signature<typename remove_cv_seq<Function>::type>(); +} + +template <typename Function> +constexpr inline auto extract_signature(Function const & /*unused*/) noexcept + -> decltype(&Function::operator(), extract_signature(&Function::operator())) +{ + return extract_signature(&Function::operator()); +} + +template <typename Function, typename Return, typename... Args> +inline auto get_normalized_lambda(Function &&func, + Signature<Return(Args...)> /*unused*/) noexcept +{ + // Static copy of func. This will make it accessible for the lambda without using a + // lamda capture + static auto static_func = Function(std::forward<Function>(func)); + + return +[](Args... args) noexcept( + noexcept(std::declval<Function>()(std::forward<Args>(args)...))) -> Return + { + return static_func(std::forward<Args>(args)...); + }; +} + +/** + * Normalizes the type signature of a lambda function. + * + * This will make a lambda with captures passable to other functions. + * + * @param func A lambda function + * @returns The lambda function normalized. + */ +template <typename Function> +constexpr auto normalize_lambda(Function &&func) noexcept +{ + return get_normalized_lambda(std::forward<Function>(func), + extract_signature(std::forward<Function>(func))); +} |