Olympe Engine 2.0
2D Game Engine with ECS Architecture
Loading...
Searching...
No Matches
InputsManager.h
Go to the documentation of this file.
1#pragma once
5#include "InputDevice.h"
6#include "InputConfigLoader.h"
7#include <unordered_map>
8#include <vector>
9#include "Ecs_Entity.h"
10#include "ECS_Components.h"
11#include "World.h"
12
13// Input context types for context stack (backward compatibility)
14enum class InputContext { Gameplay, UI, Editor };
15
17{
18public:
20 virtual ~InputsManager();
21
23 {
25 return instance;
26 }
27 static InputsManager& Get() { return GetInstance(); }
28
29 void Shutdown()
30 {
34 m_playerBindings.clear();
35 //m_playerObjectIndex.clear();
36 m_keyboardAssigned = false;
37 }
38
39 // Initialize new input system
40 void InitializeInputSystem(const std::string& configPath = "Config/olympe-config.json");
41
42 // Get new input system components (for advanced usage)
45
46 virtual void HandleEvent(const SDL_Event* ev);
47
48 bool IsKeyboardAssigned() const { return m_keyboardAssigned; }
49
51
52 //--------------------------------------------------------------
54 {
55 return static_cast<int>(JoystickManager::Get().GetConnectedJoysticks().size());
56 }
57 //--------------------------------------------------------------
59 {
60 return m_keyboardAssigned ? 1 : 0;
61 }
62 //--------------------------------------------------------------
63 int GetMaxDevices() const
64 {
65 // Max players = number of connected joysticks + 1 (keyboard)
66 return static_cast<int>(GetConnectedJoysticksCount() + GetConnectedKeyboardsCount());
67 }
68 //--------------------------------------------------------------
70 {
71 int count = 0;
73 for (auto jid : joysticks)
74 {
75 bool used = false;
76 for (auto& kv : m_playerBindings)
77 if (kv.second == jid)
78 {
79 used = true; break;
80 }
81 if (!used) ++count;
82 }
83 return count;
84 }
85 //--------------------------------------------------------------
86 // Automatically bind first available controller (joystick or keyboard) to a player
88 {
89 // try to bind first available joystick
91 for (auto jid : joysticks)
92 {
94 return jid;
95 }
96
97 // Failled to bind joystick,
98 SYSTEM_LOG << "No available joystick to bind to player " << playerID << ". Try to bind keyboard\n";
99
100 // try to bind keyboard if no joystick available
102 {
103 SYSTEM_LOG << "Player " << playerID << " bound to keyboard\n";
104 return -1;
105 }
106 else
107 {
108 SYSTEM_LOG << "Failed to bind keyboard to player " << playerID << " keyboard already assigned to playerID :" << GetPlayerForController( SDL_JoystickID(- 1) ) << "\n";
109 return -2;
110 }
111 }
112 ////--------------------------------------------------------------
113 // bool AddPlayerObjectIndex(short playerID, Player* playerPtr)
114 // {
115 // if (m_playerObjectIndex.find(playerID) != m_playerObjectIndex.end()) return false;
116 // m_playerObjectIndex[playerID] = playerPtr;
117 // return true;
118 // }
119 //--------------------------------------------------------------
121 {
122 if (m_playerEntityIndex.find(playerID) != m_playerEntityIndex.end()) return false;
124 return true;
125 }
126 //--------------------------------------------------------------
127 // Bind a controller (joystick id) or keyboard (-1) to a player
129 {
130 // if controller == -1 -> keyboard
131 if (controller == SDL_JoystickID(-1))
132 {
133 if (m_keyboardAssigned) return false;
134 m_keyboardAssigned = true;
136 //m_playerObjectIndex[playerID]->m_ControllerID = controller;
137 //return true;
138 }
139 else
140 {
141 // ensure joystick exists
142 if (!JoystickManager::Get().IsJoystickConnected(controller)) return false;
143 // ensure not already used
144 for (auto& kv : m_playerBindings) if (kv.second == controller) return false;
146 }
147
150 {
151 // Access to entity controllerdata to remove controllerID binding
152 EntityID eID = entityPlayer->second;
155 ctrl.controllerID = controller; // set new controller ID
156 binding.controllerID = controller; // set new controller ID
157
158 SYSTEM_LOG << "Player " << playerID << " bound to joystick " << controller << "\n";
159 return true;
160 }
161 else
162 {
163 SYSTEM_LOG << "Player " << playerID << " bound to joystick " << controller << " but no entity found to update controllerID\n";
164 return true;
165 }
166 }
167 //---------------------------------------------------------------------------------------------
169 {
170 auto it = m_playerBindings.find(playerID);
171 if (it == m_playerBindings.end()) return false;
172 if (it->second == SDL_JoystickID(-1)) m_keyboardAssigned = false;
173 m_playerBindings.erase(it);
174
176 if ( entityPlayer != m_playerEntityIndex.end() )
177 {
178 // Access to entity controllerdata to remove controllerID binding
179 EntityID eID = entityPlayer->second;
182 controller.controllerID = -2; // unbound
183 binding.controllerID = -2; // unbound
184 //m_playerEntityIndex.erase(entityPlayer);
185 }
186 SYSTEM_LOG << "Player " << playerID << " unbound from controller\n";
187 return true;
188 }
189 //--------------------------------------------------------------
190 // Manage disconnected players
198 {
199 auto it = m_playerDisconnected.find(playerID);
200 if (it == m_playerDisconnected.end()) return false;
202 return true;
203 }
205 {
207 }
209 {
210 return static_cast<int>(m_playerDisconnected.size());
211 }
213 {
214 if (m_playerDisconnected.empty()) return -1;
215 return m_playerDisconnected.begin()->first;
216 }
217
218
219 // Query
220 bool IsPlayerBound(short playerID) const { return m_playerBindings.find(playerID) != m_playerBindings.end(); }
222 {
223 auto it = m_playerBindings.find(playerID);
224 if (it == m_playerBindings.end()) return SDL_JoystickID(0);
225 return it->second;
226 }
228 {
229 for (auto &kv : m_playerBindings)
230 {
231 if (kv.second == controller) return kv.first;
232 }
233 return -1;
234 }
235
236 // Input Context Stack
238 void PopContext();
240
241 // Input Entity Cache
244 const std::vector<EntityID>& GetInputEntities() const;
245
246private:
247 std::string name;
248 std::unordered_map<short, SDL_JoystickID> m_playerBindings;
249 std::unordered_map<short, SDL_JoystickID> m_playerDisconnected;
250 //std::unordered_map<short, Player*> m_playerObjectIndex;
251 std::unordered_map<short, EntityID> m_playerEntityIndex;
252 bool m_keyboardAssigned = false;
253 //JoystickManager& joystickmanager = JoystickManager::GetInstance();
254 //KeyboardManager& keyboardmanager = KeyboardManager::GetInstance();
255 //MouseManager& mousemanager = MouseManager::GetInstance();
256 std::ostringstream m_devicesStatus;
257
258 // Context stack for input handling (Gameplay, UI, Editor)
259 std::vector<InputContext> m_contextStack = { InputContext::Gameplay };
260
261 // Cache of entities with input components for optimized iteration
262 std::vector<EntityID> m_inputEntities;
263};
264
Core ECS component definitions.
ComponentTypeID GetComponentTypeID_Static()
Definition ECS_Entity.h:56
std::uint64_t EntityID
Definition ECS_Entity.h:21
InputContext
World and ECS Manager for Olympe Engine.
static InputContextManager & Get()
static InputDeviceManager & Get()
short GetFirstDisconnectedPlayerID() const
void InitializeInputSystem(const std::string &configPath="Config/olympe-config.json")
InputDeviceManager & GetDeviceManager()
std::ostringstream m_devicesStatus
static InputsManager & Get()
void PushContext(InputContext ctx)
std::unordered_map< short, SDL_JoystickID > m_playerBindings
std::unordered_map< short, EntityID > m_playerEntityIndex
InputContextManager & GetContextManager()
static InputsManager & GetInstance()
virtual void HandleEvent(const SDL_Event *ev)
std::unordered_map< short, SDL_JoystickID > m_playerDisconnected
virtual ~InputsManager()
void RegisterInputEntity(EntityID e)
int GetConnectedJoysticksCount() const
InputContext GetActiveContext() const
bool UnbindControllerFromPlayer(short playerID)
int GetAvailableJoystickCount() const
SDL_JoystickID GetPlayerBinding(short playerID) const
int GetConnectedKeyboardsCount() const
short AutoBindControllerToPlayer(short playerID)
string GetDevicesStatusUpdate()
bool IsKeyboardAssigned() const
int GetMaxDevices() const
short GetPlayerForController(SDL_JoystickID controller) const
short GetDisconnectedPlayersCount() const
bool IsPlayerDisconnected(short playerID) const
bool BindControllerToPlayer(short playerID, SDL_JoystickID controller)
void UnregisterInputEntity(EntityID e)
bool AddPlayerEntityIndex(short playerID, EntityID eID)
std::vector< EntityID > m_inputEntities
const std::vector< EntityID > & GetInputEntities() const
bool AddDisconnectedPlayer(short playerID, SDL_JoystickID old_controller)
std::vector< InputContext > m_contextStack
bool RemoveDisconnectedPlayer(short playerID)
bool IsPlayerBound(short playerID) const
std::string name
static JoystickManager & Get()
std::vector< SDL_JoystickID > GetConnectedJoysticks()
static KeyboardManager & Get()
static MouseManager & Get()
static World & Get()
Get singleton instance (short form)
Definition World.h:232
T & GetComponent(EntityID entity)
Definition World.h:438
#define SYSTEM_LOG