]> git.tdb.fi Git - libs/game.git/blobdiff - source/gameview/playerinput.h
Add infrastructure for receiving player input
[libs/game.git] / source / gameview / playerinput.h
diff --git a/source/gameview/playerinput.h b/source/gameview/playerinput.h
new file mode 100644 (file)
index 0000000..16f3c4e
--- /dev/null
@@ -0,0 +1,74 @@
+#ifndef MSP_GAMEVIEW_PLAYERINPUT_H_
+#define MSP_GAMEVIEW_PLAYERINPUT_H_
+
+#include <memory>
+#include <msp/input/bindings.h>
+#include <msp/input/controlscheme.h>
+#include <msp/input/hub.h>
+#include <msp/input/keyboard.h>
+#include <msp/input/mouse.h>
+#include <msp/game/director.h>
+#include "events.h"
+
+namespace Msp::GameView {
+
+class PlayerInput: public NonCopyable
+{
+public:
+       using EventSource = Game::EventSource<Events::PlayerArrived, Events::PlayerDeparted>;
+
+       enum Mode
+       {
+               ONE_LOCAL_PLAYER,
+               LOCAL_MULTIPLAYER
+       };
+
+private:
+       struct Player
+       {
+               Input::Device *device = nullptr;
+               std::unique_ptr<Input::ControlScheme> controls = nullptr;
+       };
+
+       using SchemeFactoryFunc = std::unique_ptr<Input::ControlScheme>();
+
+       EventSource event_source;
+       Input::Keyboard keyboard;
+       Input::Mouse mouse;
+       Input::Hub kbm_hub;
+       std::vector<Input::Bindings *> bindings;
+       SchemeFactoryFunc *scheme_factory = nullptr;
+       std::vector<Player> players;
+       Mode mode = ONE_LOCAL_PLAYER;
+
+public:
+       PlayerInput(Game::Director &, Graphics::Window &);
+
+       template<typename T>
+               requires std::is_base_of_v<Input::ControlScheme, T>
+       void set_control_scheme_type(Mode = ONE_LOCAL_PLAYER);
+
+private:
+       void init_players();
+       void add_player(Input::Device &);
+
+public:
+       void synthesize_initial_events(Game::EventObserver &);
+};
+
+
+template<typename T>
+       requires std::is_base_of_v<Input::ControlScheme, T>
+void PlayerInput::set_control_scheme_type(Mode m)
+{
+       if(scheme_factory)
+               throw std::logic_error("scheme type already set");
+
+       mode = m;
+       scheme_factory = +[]() -> std::unique_ptr<Input::ControlScheme> { return std::make_unique<T>(); };
+       init_players();
+}
+
+} // namespace Msp::GameView
+
+#endif