Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
SystemManager.h
Go to the documentation of this file.
1/*
2 Author : Tobias Stein
3 Date : 13th July, 2016
4 File : SystemManager.h
5
6 Manager class for systems
7
8 All Rights Reserved. (c) Copyright 2016.
9*/
10
11#pragma once
12#ifndef ECS__SYSTEM_MANAGER_H__
13#define ECS__SYSTEM_MANAGER_H__
14
15#include "API.h"
16#include "Engine.h"
17
18#include "ISystem.h"
19
21#include "util/FamilyTypeID.h"
22
23
24
25namespace ECS
26{
27 using SystemWorkStateMask = eastl::vector<bool>;
28
29
31 {
32 friend ECSEngine;
33
35
36 private:
37
38 using SystemDependencyMatrix = eastl::vector<eastl::vector<bool>>;
39
40 using SystemRegistry = eastl::unordered_map<u64, ISystem*>;
42
43 using SystemWorkOrder = eastl::vector<ISystem*>;
44
46
48
50
52
53 // This class is not inteeded to be initialized
54 SystemManager(const SystemManager&) = delete;
56
69
70 void PreUpdate(f32 dt_ms);
71 void Update(f32 dt_ms);
72 void PostUpdate(f32 dt_ms);
73 void OnFrameStart();
74 void OnFrameEnd();
75
76 public:
77
79 ~SystemManager() override;
80
81 template<class Predicate>
82 void ForEachSystem(Predicate&& pred)
83 {
84 for (ISystem* system : this->m_SystemWorkOrder)
85 {
86 pred(system);
87 }
88 }
89
107
108 template<class T, class... ARGS>
109 T* AddSystem(ECSEngine& engine, ARGS&&... systemArgs)
110 {
111 const u64 STID = T::STATIC_SYSTEM_TYPE_ID;
112
113
114 // avoid multiple registrations of the same system
115 auto it = this->m_Systems.find(STID);
116 if ((this->m_Systems.find(STID) != this->m_Systems.end()) && (it->second != nullptr))
117 return (T*)it->second;
118
119 T* system = nullptr;
120 void* pSystemMem = this->m_SystemAllocator->allocate(sizeof(T), alignof(T));
121 if (pSystemMem != nullptr)
122 {
123
124 ((T*)pSystemMem)->m_SystemManagerInstance = this;
125
126 // create new system
127 system = new (pSystemMem)T(engine, std::forward<ARGS>(systemArgs)...);
128 this->m_Systems[STID] = system;
129
130 LOG_INFO("System \'{}\' ({} bytes) created.", typeid(T).name(), sizeof(T));
131 }
132 else
133 {
134 LOG_ERROR("Unable to create system \'{}\' ({} bytes).", typeid(T).name(), sizeof(T));
135 assert(true);
136 }
137
138 // resize dependency matrix
139 if (STID + 1 > this->m_SystemDependencyMatrix.size())
140 {
141 this->m_SystemDependencyMatrix.resize(STID + 1);
142 for (size_t i = 0u; i < this->m_SystemDependencyMatrix.size(); ++i)
143 this->m_SystemDependencyMatrix[i].resize(STID + 1);
144 }
145
146 // add to work list
147 this->m_SystemWorkOrder.push_back(system);
148
149 return system;
150 }
151
170
171 template<class System_, class Dependency_>
172 void AddSystemDependency(System_ target, Dependency_ dependency)
173 {
174 const u64 TARGET_ID = target->GetStaticSystemTypeID();
175 const u64 DEPEND_ID = dependency->GetStaticSystemTypeID();
176
177 if (this->m_SystemDependencyMatrix[TARGET_ID][DEPEND_ID] != true)
178 {
179 this->m_SystemDependencyMatrix[TARGET_ID][DEPEND_ID] = true;
180 LOG_INFO("added '{}' as dependency to '{}'", dependency->GetSystemTypeName(), target->GetSystemTypeName());
181 }
182
183 //this->UpdateSystemWorkOrder();
184 }
185
186 template<class Target_, class Dependency_, class... Dependencies>
187 void AddSystemDependency(Target_ target, Dependency_ dependency, Dependencies&&... dependencies)
188 {
189 const u64 TARGET_ID = target->GetStaticSystemTypeID();
190 const u64 DEPEND_ID = dependency->GetStaticSystemTypeID();
191
192 if (this->m_SystemDependencyMatrix[TARGET_ID][DEPEND_ID] != true)
193 {
194 this->m_SystemDependencyMatrix[TARGET_ID][DEPEND_ID] = true;
195 LOG_INFO("added '{}' as dependency to '{}'", dependency->GetSystemTypeName(), target->GetSystemTypeName());
196 }
197
198 this->AddSystemDependency(target, FWD(dependencies)...);
199 }
200
211
212 void UpdateSystemWorkOrder();
213
228
229 template<class T>
230 inline T* GetSystem() const
231 {
232 auto it = this->m_Systems.find(T::STATIC_SYSTEM_TYPE_ID);
233
234 return it != this->m_Systems.end() ? (T*)it->second : nullptr;
235 }
236
237
238 template<class T>
240 {
241 const SystemTypeId STID = T::STATIC_SYSTEM_TYPE_ID;
242
243 // get system
244 auto it = this->m_Systems.find(STID);
245 if (it != this->m_Systems.end())
246 {
247 if (it->second->m_Enabled == true)
248 return;
249
250 // enable system
251 it->second->m_Enabled = true;
252 }
253 else
254 {
255 LOG_WARNING("Trying to enable system [{}], but system is not registered yet.", STID);
256 }
257 }
258
259
260 template<class T>
262 {
263 const SystemTypeId STID = T::STATIC_SYSTEM_TYPE_ID;
264
265 // get system
266 auto it = this->m_Systems.find(STID);
267 if (it != this->m_Systems.end())
268 {
269 if (it->second->m_Enabled == false)
270 return;
271
272 // enable system
273 it->second->m_Enabled = false;
274 }
275 else
276 {
277 LOG_WARNING("Trying to disable system [{}], but system is not registered yet.", STID);
278 }
279 }
280
281 template<class T>
282 void SetSystemUpdateInterval(f32 interval_ms)
283 {
284 const SystemTypeId STID = T::STATIC_SYSTEM_TYPE_ID;
285
286 // get system
287 auto it = this->m_Systems.find(STID);
288 if (it != this->m_Systems.end())
289 {
290 it->second->m_UpdateInterval = interval_ms;
291 }
292 else
293 {
294 LOG_WARNING("Trying to change system's [{}] update interval, but system is not registered yet.", STID);
295 }
296 }
297
298 template<class T>
300 {
301 const SystemTypeId STID = T::STATIC_SYSTEM_TYPE_ID;
302
303 // get system
304 auto it = this->m_Systems.find(STID);
305 if (it != this->m_Systems.end())
306 {
307 SystemPriority oldPriority = it->second->m_Priority;
308
309 if (oldPriority == newPriority)
310 return;
311
312 it->second->m_Priority = newPriority;
313
314 // re-build system work order
315 //this->UpdateSystemWorkOrder();
316 }
317 else
318 {
319 LOG_WARNING("Trying to change system's [{}] priority, but system is not registered yet.", STID);
320 }
321 }
322
335
336 SystemWorkStateMask GetSystemWorkState() const;
337
350
351 void SetSystemWorkState(SystemWorkStateMask mask);
352
353 template<class... ActiveSystems>
354 SystemWorkStateMask GenerateActiveSystemWorkState(ActiveSystems&&... activeSystems)
355 {
356 SystemWorkStateMask mask(this->m_SystemWorkOrder.size(), false);
357
358 eastl::list<ISystem*> AS = { activeSystems... };
359 for (auto s : AS)
360 {
361 for (int i = 0; i < this->m_SystemWorkOrder.size(); ++i)
362 {
363 if (this->m_SystemWorkOrder[i]->GetStaticSystemTypeID() == s->GetStaticSystemTypeID())
364 {
365 mask[i] = true;
366 break;
367 }
368 }
369 }
370
371 return mask;
372 }
373 };
374
375} // namespace ECS
376
377#endif // ECS__SYSTEM_MANAGER_H__
#define LOG_WARNING(format,...)
Definition: LoggerMacro.h:26
#define DECLARE_LOGGER
Definition: LoggerMacro.h:15
#define LOG_INFO(format,...)
Definition: LoggerMacro.h:25
#define LOG_ERROR(format,...)
Definition: LoggerMacro.h:27
#define ECS_API
Definition: Platform.h:16
#define FWD(...)
virtual void * allocate(size_t size, u8 alignment) override
SystemDependencyMatrix m_SystemDependencyMatrix
Definition: SystemManager.h:49
eastl::vector< eastl::vector< bool > > SystemDependencyMatrix
Definition: SystemManager.h:38
T * AddSystem(ECSEngine &engine, ARGS &&... systemArgs)
void AddSystemDependency(Target_ target, Dependency_ dependency, Dependencies &&... dependencies)
SystemAllocator * m_SystemAllocator
Definition: SystemManager.h:45
SystemManager(const SystemManager &)=delete
eastl::unordered_map< u64, ISystem * > SystemRegistry
Definition: SystemManager.h:40
void ForEachSystem(Predicate &&pred)
Definition: SystemManager.h:82
void AddSystemDependency(System_ target, Dependency_ dependency)
eastl::vector< ISystem * > SystemWorkOrder
Definition: SystemManager.h:43
SystemRegistry m_Systems
Definition: SystemManager.h:47
SystemManager & operator=(SystemManager &)=delete
SystemWorkStateMask GenerateActiveSystemWorkState(ActiveSystems &&... activeSystems)
SystemWorkOrder m_SystemWorkOrder
Definition: SystemManager.h:51
void SetSystemUpdateInterval(f32 interval_ms)
void SetSystemPriority(SystemPriority newPriority)
T * GetSystem() const
uint32_t u64
Definition: Platform.h:55
float_t f32
Definition: Platform.h:59
eastl::vector< bool > SystemWorkStateMask
Definition: SystemManager.h:27
TypeID SystemTypeId
Definition: ISystem.h:22
u16 SystemPriority
Definition: ISystem.h:24