1 /*
2  *  Copyright (C) 2017-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "games/addons/GameClientSubsystem.h"
12 #include "games/controllers/ControllerTypes.h"
13 #include "games/controllers/types/ControllerTree.h"
14 #include "peripherals/PeripheralTypes.h"
15 #include "utils/Observer.h"
16 
17 #include <map>
18 #include <memory>
19 #include <string>
20 
21 class CCriticalSection;
22 struct game_input_event;
23 
24 namespace KODI
25 {
26 namespace JOYSTICK
27 {
28 class IInputProvider;
29 }
30 
31 namespace GAME
32 {
33 class CGameClient;
34 class CGameClientController;
35 class CGameClientHardware;
36 class CGameClientJoystick;
37 class CGameClientKeyboard;
38 class CGameClientMouse;
39 class CGameClientTopology;
40 class IGameInputCallback;
41 
42 class CGameClientInput : protected CGameClientSubsystem, public Observer
43 {
44 public:
45   CGameClientInput(CGameClient& gameClient,
46                    AddonInstance_Game& addonStruct,
47                    CCriticalSection& clientAccess);
48   ~CGameClientInput() override;
49 
50   void Initialize();
51   void Deinitialize();
52 
53   void Start(IGameInputCallback* input);
54   void Stop();
55 
56   // Input functions
57   bool HasFeature(const std::string& controllerId, const std::string& featureName) const;
58   bool AcceptsInput() const;
59   bool InputEvent(const game_input_event& event);
60 
61   // Topology functions
62   const CControllerTree& GetControllerTree() const;
63   bool SupportsKeyboard() const;
64   bool SupportsMouse() const;
65 
66   // Agent functions
67   bool HasAgent() const;
68 
69   // Keyboard functions
70   bool OpenKeyboard(const ControllerPtr& controller);
71   void CloseKeyboard();
72 
73   // Mouse functions
74   bool OpenMouse(const ControllerPtr& controller);
75   void CloseMouse();
76 
77   // Joystick functions
78   bool OpenJoystick(const std::string& portAddress, const ControllerPtr& controller);
79   void CloseJoystick(const std::string& portAddress);
80 
81   // Hardware input functions
82   void HardwareReset();
83 
84   // Input callbacks
85   bool ReceiveInputEvent(const game_input_event& eventStruct);
86 
87   // Implementation of Observer
88   void Notify(const Observable& obs, const ObservableMessage msg) override;
89 
90 private:
91   using PortAddress = std::string;
92   using JoystickMap = std::map<PortAddress, std::unique_ptr<CGameClientJoystick>>;
93   using PortMap = std::map<JOYSTICK::IInputProvider*, CGameClientJoystick*>;
94 
95   // Private input helpers
96   void LoadTopology();
97   void SetControllerLayouts(const ControllerVector& controllers);
98   void ProcessJoysticks();
99   PortMap MapJoysticks(const PERIPHERALS::PeripheralVector& peripheralJoysticks,
100                        const JoystickMap& gameClientjoysticks) const;
101 
102   // Private callback helpers
103   bool SetRumble(const std::string& portAddress, const std::string& feature, float magnitude);
104 
105   // Helper functions
106   static ControllerVector GetControllers(const CGameClient& gameClient);
107   static void ActivateControllers(CControllerHub& hub);
108 
109   // Input properties
110   IGameInputCallback* m_inputCallback = nullptr;
111   std::unique_ptr<CGameClientTopology> m_topology;
112   using ControllerLayoutMap = std::map<std::string, std::unique_ptr<CGameClientController>>;
113   ControllerLayoutMap m_controllerLayouts;
114   JoystickMap m_joysticks;
115   PortMap m_portMap;
116   std::unique_ptr<CGameClientKeyboard> m_keyboard;
117   std::unique_ptr<CGameClientMouse> m_mouse;
118   std::unique_ptr<CGameClientHardware> m_hardware;
119 };
120 } // namespace GAME
121 } // namespace KODI
122