summaryrefslogtreecommitdiffstats
path: root/xbmc/games/addons/input/GameClientInput.h
blob: be7e71c9b96bbcc61a7624b396d8b858173f0649 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 *  Copyright (C) 2017-2018 Team Kodi
 *  This file is part of Kodi - https://kodi.tv
 *
 *  SPDX-License-Identifier: GPL-2.0-or-later
 *  See LICENSES/README.md for more information.
 */

#pragma once

#include "games/addons/GameClientSubsystem.h"
#include "games/controllers/ControllerTypes.h"
#include "games/controllers/types/ControllerTree.h"
#include "peripherals/PeripheralTypes.h"
#include "utils/Observer.h"

#include <map>
#include <memory>
#include <string>

class CCriticalSection;
struct game_input_event;

namespace KODI
{
namespace JOYSTICK
{
class IInputProvider;
}

namespace GAME
{
class CGameClient;
class CGameClientController;
class CGameClientHardware;
class CGameClientJoystick;
class CGameClientKeyboard;
class CGameClientMouse;
class CGameClientTopology;
class CPortManager;
class IGameInputCallback;

class CGameClientInput : protected CGameClientSubsystem, public Observable
{
public:
  //! @todo de-duplicate
  using PortAddress = std::string;
  using JoystickMap = std::map<PortAddress, std::shared_ptr<CGameClientJoystick>>;

  CGameClientInput(CGameClient& gameClient,
                   AddonInstance_Game& addonStruct,
                   CCriticalSection& clientAccess);
  ~CGameClientInput() override;

  void Initialize();
  void Deinitialize();

  void Start(IGameInputCallback* input);
  void Stop();

  // Input functions
  bool HasFeature(const std::string& controllerId, const std::string& featureName) const;
  bool AcceptsInput() const;
  bool InputEvent(const game_input_event& event);

  // Topology functions
  const CControllerTree& GetDefaultControllerTree() const;
  const CControllerTree& GetActiveControllerTree() const;
  bool SupportsKeyboard() const;
  bool SupportsMouse() const;
  int GetPlayerLimit() const;
  bool ConnectController(const std::string& portAddress, const ControllerPtr& controller);
  bool DisconnectController(const std::string& portAddress);
  void SavePorts();
  void ResetPorts();

  // Joystick functions
  const JoystickMap& GetJoystickMap() const { return m_joysticks; }
  void CloseJoysticks(PERIPHERALS::EventLockHandlePtr& inputHandlingLock);

  // Keyboard functions
  bool OpenKeyboard(const ControllerPtr& controller, const PERIPHERALS::PeripheralPtr& keyboard);
  bool IsKeyboardOpen() const;
  void CloseKeyboard();

  // Mouse functions
  bool OpenMouse(const ControllerPtr& controller, const PERIPHERALS::PeripheralPtr& mouse);
  bool IsMouseOpen() const;
  void CloseMouse();

  // Agent functions
  bool HasAgent() const;

  // Hardware input functions
  void HardwareReset();

  // Input callbacks
  bool ReceiveInputEvent(const game_input_event& eventStruct);

private:
  // Private input helpers
  void LoadTopology();
  void SetControllerLayouts(const ControllerVector& controllers);
  bool OpenJoystick(const std::string& portAddress, const ControllerPtr& controller);
  void CloseJoysticks(const CPortNode& port, PERIPHERALS::EventLockHandlePtr& inputHandlingLock);
  void CloseJoystick(const std::string& portAddress,
                     PERIPHERALS::EventLockHandlePtr& inputHandlingLock);

  // Private callback helpers
  bool SetRumble(const std::string& portAddress, const std::string& feature, float magnitude);

  // Helper functions
  static ControllerVector GetControllers(const CGameClient& gameClient);
  static void ActivateControllers(CControllerHub& hub);

  // Input properties
  IGameInputCallback* m_inputCallback = nullptr;
  std::unique_ptr<CGameClientTopology> m_topology;
  using ControllerLayoutMap = std::map<std::string, std::unique_ptr<CGameClientController>>;
  ControllerLayoutMap m_controllerLayouts;

  /*!
   * \brief Map of port address to joystick handler
   *
   * The port address is a string that identifies the adress of the port.
   *
   * The joystick handler connects to joystick input of the game client.
   *
   * This property is always populated with the default joystick configuration
   * (i.e. all ports are connected to the first controller they accept).
   */
  JoystickMap m_joysticks;

  // TODO: Guard with a mutex
  std::unique_ptr<CPortManager> m_portManager;

  /*!
   * \brief Keyboard handler
   *
   * This connects to the keyboard input of the game client.
   */
  std::unique_ptr<CGameClientKeyboard> m_keyboard;

  /*!
   * \brief Mouse handler
   *
   * This connects to the mouse input of the game client.
   */
  std::unique_ptr<CGameClientMouse> m_mouse;

  /*!
   * \brief Hardware input handler
   *
   * This connects to input from game console hardware belonging to the game
   * client.
   */
  std::unique_ptr<CGameClientHardware> m_hardware;
};
} // namespace GAME
} // namespace KODI