diff options
Diffstat (limited to 'xbmc/games/agents/GameAgentManager.h')
-rw-r--r-- | xbmc/games/agents/GameAgentManager.h | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/xbmc/games/agents/GameAgentManager.h b/xbmc/games/agents/GameAgentManager.h new file mode 100644 index 0000000..901a492 --- /dev/null +++ b/xbmc/games/agents/GameAgentManager.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2017-2022 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/GameTypes.h" +#include "input/keyboard/interfaces/IKeyboardDriverHandler.h" +#include "input/mouse/interfaces/IMouseDriverHandler.h" +#include "peripherals/PeripheralTypes.h" +#include "utils/Observer.h" + +#include <map> +#include <memory> +#include <set> +#include <string> + +class CInputManager; + +namespace PERIPHERALS +{ +class CPeripheral; +class CPeripherals; +} // namespace PERIPHERALS + +namespace KODI +{ +namespace JOYSTICK +{ +class IInputProvider; +} + +namespace GAME +{ +class CGameAgent; +class CGameClient; +class CGameClientJoystick; + +/*! + * \brief Class to manage game-playing agents for a running game client + * + * Currently, port mapping is controller-based and does not take into account + * the human belonging to the controller. In the future, humans and possibly + * bots will be managed here. + * + * To map ports to controllers, a list of controllers is retrieved in + * ProcessJoysticks(). After expired controllers are removed, the port mapping + * occurs in the static function MapJoysticks(). The strategy is to simply + * sort controllers by heuristics and greedily assign to game ports. + */ +class CGameAgentManager : public Observable, + public Observer, + KEYBOARD::IKeyboardDriverHandler, + MOUSE::IMouseDriverHandler +{ +public: + CGameAgentManager(PERIPHERALS::CPeripherals& peripheralManager, CInputManager& inputManager); + + virtual ~CGameAgentManager(); + + // Lifecycle functions + void Start(GameClientPtr gameClient); + void Stop(); + void Refresh(); + + // Implementation of Observer + void Notify(const Observable& obs, const ObservableMessage msg) override; + + // Implementation of IKeyboardDriverHandler + bool OnKeyPress(const CKey& key) override; + void OnKeyRelease(const CKey& key) override {} + + // Implementation of IMouseDriverHandler + bool OnPosition(int x, int y) override; + bool OnButtonPress(MOUSE::BUTTON_ID button) override; + void OnButtonRelease(MOUSE::BUTTON_ID button) override {} + +private: + //! @todo De-duplicate these types + using PortAddress = std::string; + using JoystickMap = std::map<PortAddress, std::shared_ptr<CGameClientJoystick>>; + using PortMap = std::map<JOYSTICK::IInputProvider*, std::shared_ptr<CGameClientJoystick>>; + + using PeripheralLocation = std::string; + using CurrentPortMap = std::map<PortAddress, PeripheralLocation>; + using CurrentPeripheralMap = std::map<PeripheralLocation, PortAddress>; + + using ControllerAddress = std::string; + using PeripheralMap = std::map<ControllerAddress, PERIPHERALS::PeripheralPtr>; + + // Internal interface + void ProcessJoysticks(PERIPHERALS::EventLockHandlePtr& inputHandlingLock); + void ProcessKeyboard(); + void ProcessMouse(); + + // Internal helpers + void UpdateExpiredJoysticks(const PERIPHERALS::PeripheralVector& joysticks, + PERIPHERALS::EventLockHandlePtr& inputHandlingLock); + void UpdateConnectedJoysticks(const PERIPHERALS::PeripheralVector& joysticks, + const PortMap& newPortMap, + PERIPHERALS::EventLockHandlePtr& inputHandlingLock, + std::set<PERIPHERALS::PeripheralPtr>& disconnectedJoysticks); + + // Static functionals + static PortMap MapJoysticks(const PERIPHERALS::PeripheralVector& peripheralJoysticks, + const JoystickMap& gameClientjoysticks, + CurrentPortMap& currentPorts, + CurrentPeripheralMap& currentPeripherals, + int playerLimit); + static void MapJoystick(PERIPHERALS::PeripheralPtr peripheralJoystick, + std::shared_ptr<CGameClientJoystick> gameClientJoystick, + PortMap& result); + static void LogPeripheralMap(const PeripheralMap& peripheralMap, + const std::set<PERIPHERALS::PeripheralPtr>& disconnectedPeripherals); + + // Construction parameters + PERIPHERALS::CPeripherals& m_peripheralManager; + CInputManager& m_inputManager; + + // State parameters + GameClientPtr m_gameClient; + bool m_bHasKeyboard = false; + bool m_bHasMouse = false; + + /*! + * \brief Map of input provider to joystick handler + * + * The input provider is a handle to agent input. + * + * The joystick handler connects to joystick input of the game client. + * + * This property remembers which joysticks are actually being controlled by + * agents. + * + * Not exposed to the game. + */ + PortMap m_portMap; + + /*! + * \brief Map of the current ports to their peripheral + * + * This allows attempt to preserve player numbers. + */ + CurrentPortMap m_currentPorts; + + /*! + * \brief Map of the current peripherals to their port + * + * This allows attempt to preserve player numbers. + */ + CurrentPeripheralMap m_currentPeripherals; + + /*! + * Map of controller address to source peripheral + * + * Source peripherals are not exposed to the game. + */ + PeripheralMap m_peripheralMap; + + /*! + * Collection of disconnected joysticks + * + * Source peripherals are not exposed to the game. + */ + std::set<PERIPHERALS::PeripheralPtr> m_disconnectedPeripherals; +}; +} // namespace GAME +} // namespace KODI |