summaryrefslogtreecommitdiffstats
path: root/xbmc/games/agents/GameAgentManager.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/games/agents/GameAgentManager.h')
-rw-r--r--xbmc/games/agents/GameAgentManager.h171
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