#include <msp/gl/windowview.h>
#include <msp/graphics/display.h>
#include <msp/graphics/window.h>
+#include "playerinput.h"
#include "presenter.h"
namespace Msp::GameView {
Msp::Game::Director director;
GL::WindowView gl_view;
Presenter presenter;
+ PlayerInput player_input;
public:
Application();
gl_device(window),
director(resources),
gl_view(window),
- presenter(director, gl_view)
+ presenter(director, gl_view),
+ player_input(director, window)
{
window.signal_close.connect(sigc::bind(sigc::mem_fun(this, &Application::exit), 0));
}
--- /dev/null
+#ifndef MSP_GAMEVIEW_EVENTS_H_
+#define MSP_GAMEVIEW_EVENTS_H_
+
+#include <msp/input/controlscheme.h>
+
+namespace Msp::GameView {
+namespace Events {
+
+struct PlayerArrived
+{
+ Input::ControlScheme &controls;
+};
+
+struct PlayerDeparted
+{
+ Input::ControlScheme &controls;
+};
+
+} // namespace Events
+} // namespace Msp::GameView
+
+#endif
--- /dev/null
+#include "playerinput.h"
+#include <msp/input/bindings.h>
+
+using namespace std;
+
+namespace Msp::GameView {
+
+PlayerInput::PlayerInput(Game::Director &director, Graphics::Window &wnd):
+ event_source(director.get_event_bus()),
+ keyboard(wnd),
+ mouse(wnd)
+{
+ kbm_hub.attach(keyboard);
+ kbm_hub.attach(mouse);
+
+ bindings = director.get_resources().get_all<Input::Bindings>();
+}
+
+void PlayerInput::init_players()
+{
+ add_player(kbm_hub);
+}
+
+void PlayerInput::add_player(Input::Device &dev)
+{
+ Player &player = players.emplace_back(&dev, scheme_factory());
+ for(Input::Bindings *b: bindings)
+ if(b->is_compatible(dev))
+ {
+ b->apply_to(*player.controls, dev);
+ break;
+ }
+ event_source.emit<Events::PlayerArrived>(ref(*player.controls));
+}
+
+void PlayerInput::synthesize_initial_events(Game::EventObserver &observer)
+{
+ for(const Player &p: players)
+ event_source.emit_to<Events::PlayerArrived>(observer, ref(*p.controls));
+}
+
+} // namespace Msp::GameView
--- /dev/null
+#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
--- /dev/null
+#include "resources.h"
+#include <msp/input/bindings.h>
+
+namespace Msp::GameView {
+
+Resources::Resources()
+{
+ add_type<Input::Bindings>().suffix(".binds");
+}
+
+} // namespace Msp::GameView
--- /dev/null
+#ifndef MSP_GAMEVIEW_RESOURCES_H_
+#define MSP_GAMEVIEW_RESOURCES_H_
+
+#include <msp/gl/resources.h>
+
+namespace Msp::GameView {
+
+class Resources: public GL::Resources
+{
+public:
+ Resources();
+};
+
+} // namespace Msp::GameView
+
+#endif