]> git.tdb.fi Git - libs/game.git/blob - source/gameview/playerinput.h
Add infrastructure for receiving player input
[libs/game.git] / source / gameview / playerinput.h
1 #ifndef MSP_GAMEVIEW_PLAYERINPUT_H_
2 #define MSP_GAMEVIEW_PLAYERINPUT_H_
3
4 #include <memory>
5 #include <msp/input/bindings.h>
6 #include <msp/input/controlscheme.h>
7 #include <msp/input/hub.h>
8 #include <msp/input/keyboard.h>
9 #include <msp/input/mouse.h>
10 #include <msp/game/director.h>
11 #include "events.h"
12
13 namespace Msp::GameView {
14
15 class PlayerInput: public NonCopyable
16 {
17 public:
18         using EventSource = Game::EventSource<Events::PlayerArrived, Events::PlayerDeparted>;
19
20         enum Mode
21         {
22                 ONE_LOCAL_PLAYER,
23                 LOCAL_MULTIPLAYER
24         };
25
26 private:
27         struct Player
28         {
29                 Input::Device *device = nullptr;
30                 std::unique_ptr<Input::ControlScheme> controls = nullptr;
31         };
32
33         using SchemeFactoryFunc = std::unique_ptr<Input::ControlScheme>();
34
35         EventSource event_source;
36         Input::Keyboard keyboard;
37         Input::Mouse mouse;
38         Input::Hub kbm_hub;
39         std::vector<Input::Bindings *> bindings;
40         SchemeFactoryFunc *scheme_factory = nullptr;
41         std::vector<Player> players;
42         Mode mode = ONE_LOCAL_PLAYER;
43
44 public:
45         PlayerInput(Game::Director &, Graphics::Window &);
46
47         template<typename T>
48                 requires std::is_base_of_v<Input::ControlScheme, T>
49         void set_control_scheme_type(Mode = ONE_LOCAL_PLAYER);
50
51 private:
52         void init_players();
53         void add_player(Input::Device &);
54
55 public:
56         void synthesize_initial_events(Game::EventObserver &);
57 };
58
59
60 template<typename T>
61         requires std::is_base_of_v<Input::ControlScheme, T>
62 void PlayerInput::set_control_scheme_type(Mode m)
63 {
64         if(scheme_factory)
65                 throw std::logic_error("scheme type already set");
66
67         mode = m;
68         scheme_factory = +[]() -> std::unique_ptr<Input::ControlScheme> { return std::make_unique<T>(); };
69         init_players();
70 }
71
72 } // namespace Msp::GameView
73
74 #endif