Cogs.Core
Engine.h
1#pragma once
2
3#include "Context.h"
4#include "MemoryContext.h"
5
6#include "Services/TaskManager.h"
7
8#include "Foundation/Memory/Allocator.h"
9
10#include <atomic>
11#include <vector>
12
14namespace Cogs
15{
16 class IGraphicsDevice;
17
19 namespace Core
20 {
21 class Context;
22 class ComponentSystemBase;
23 class IResourceManager;
24 class IValueTypeManager;
25
26 typedef void NeedsUpdateCallback(void* data);
27
30 {
43 enum ESystemPriority : int32_t
44 {
56 PreView = 190,
58 View = 200,
62 LightView = 205,
66 PostView = 210,
70 Geometry = 1000,
76 Rendering = 10000,
77 };
78 };
79
87 class COGSCORE_DLL_API Engine
88 {
89 public:
107 Engine(Context * context);
108
110 Engine(const Engine & other) = delete;
111
126 ~Engine();
127
129 Engine & operator=(const Engine & other) = delete;
130
142 void update();
143
144 /* Wrappers for calling client-provided callbacks.
145
146 On web, client-provided callbacks must be called from the main thread. These wrappers handle
147 this by proxying the call to the main-thread if called on a worker thread.
148
149 On desktop and single-thread web, these wrappers just directly calls the callbacks.
150 */
151
152#if defined(EMSCRIPTEN) && !defined(COGS_SINGLETHREADED)
153 void invokeCallback(void(*callback)(void*), void* data);
154
155 void invokeComponentNotifyCallback(const ComponentModel::Component& component, int notification, const void* data, size_t dataSize);
156
157 void invokeResourceLoadCallback(int resourceType, ResourceId id, int code);
158#else
160 void invokeCallback(void(*callback)(void*), void* data) { if (callback) { callback(data); } }
161
163 void invokeComponentNotifyCallback(const ComponentModel::Component& component, int notification, const void* data, size_t dataSize) {
164 if (context->callbacks.componentNotifyCallback) {
165 context->callbacks.componentNotifyCallback(context, component.getTypeId(), component.getContainer()->getId(), notification, data, dataSize);
166 }
167 }
168
170 void invokeResourceLoadCallback(int resourceType, ResourceId id, int code) {
171 if (context->callbacks.resourceLoadCallback) {
172 context->callbacks.resourceLoadCallback(context, resourceType, id, code);
173 }
174 }
175#endif
176
180 inline bool needsUpdate() const
181 {
182 return updateRequested;
183 }
184
191 inline void triggerUpdate()
192 {
193 bool wasRequested = updateRequested.exchange(true);
194 if ((wasRequested == false) && needsUpdateCallback) {
195 invokeCallback(needsUpdateCallback, needsUpdateData);
196 }
197 }
198
203 inline void setDirty()
204 {
205 if (!updateRequested) setDirtyState();
206 }
207
211 inline uint32_t getLastDirtyFrame() { return lastDirtyFrame; }
212
214 void setNeedsUpdateCallback(NeedsUpdateCallback* callback, void* data) { needsUpdateCallback = callback; needsUpdateData = data; }
215
230 void updateSystems();
231
250 void registerSystem(ComponentSystemBase * system, int priority, bool registerInStore = true);
251
263 template<typename SystemType>
264 SystemType * registerSystem(int priority, SystemType ** storage, uint32_t capacity, bool registerInStore = true)
265 {
266 auto system = Memory::create<SystemType>(
267 context->memory->baseAllocator,
268 context->memory->componentAllocator,
269 capacity);
270
271 if (storage) {
272 *storage = system;
273 }
274
275 registerSystem(system, priority, registerInStore);
276
277 return system;
278 }
279
288 void addResourceManager(std::unique_ptr<IResourceManager> && resourceManager);
289
290 IValueTypeManager* getResourceManagerByValueType(int valueType);
291
295 void initializeResources();
296
300 void clearResources();
301
302 void runTaskInMainThread(std::function<void()>&& task);
303
304 void preRender();
305 void render();
306 void postRender();
307
308 void swapResources();
309
313 bool workParallel() const { return workParallelValue; }
314
315 bool isReady() const { return ready; }
316
317 void checkAndUpdateResources();
318
319 void setEditor(class IEditor * editor);
320 class IEditor * getEditor() const { return editor.get(); }
321
322 private:
323
324
325 void setDirtyState();
326
327 Context * context = nullptr;
328
329 NeedsUpdateCallback* needsUpdateCallback = nullptr;
330 void* needsUpdateData = nullptr;
331
332 std::vector<std::string> resourceManifest;
333
334 std::unique_ptr<class IEditor> editor;
335
337 {
338 enum ESystemFlags
339 {
340 None = 0x0002,
341 Changed = 0x0001,
342 };
343 };
344
345 uint32_t systemFlags = SystemFlags::None;
346
347 uint32_t lastDirtyFrame = 0;
348 std::atomic_bool updateRequested = true;
349
350 // Multi pass initialization of graphics device, needed for WebGPU, waiting for
351 // Async adapter request
352 bool initializing_device = false;
353 bool ready = false;
354 bool firstInit = true;
355 bool workParallelValue = true;
356
357 std::vector<std::unique_ptr<IResourceManager>> resourceManagers;
358
359 std::unique_ptr<struct EngineData> data;
360 };
361 }
362}
Base class for Component instances.
Definition: Component.h:143
class Entity * getContainer() const
Get the container currently owning this component instance.
Definition: Component.h:151
constexpr Reflection::TypeId getTypeId() const
Get the Reflection::TypeId of the component.
Definition: Component.h:380
constexpr size_t getId() const noexcept
Get the unique identifier of this entity.
Definition: Entity.h:113
Base class for component systems.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
std::unique_ptr< struct MemoryContext > memory
Memory and allocation info.
Definition: Context.h:171
The engine owns all the systems and resource managers, and is responsible for executing different sta...
Definition: Engine.h:88
SystemType * registerSystem(int priority, SystemType **storage, uint32_t capacity, bool registerInStore=true)
Utility function for instantiating a system of the given template type and assigning ownership to the...
Definition: Engine.h:264
void invokeResourceLoadCallback(int resourceType, ResourceId id, int code)
Invoke the resourceLoadCallback if it exists, proxied from emscripten worker threads.
Definition: Engine.h:170
void setNeedsUpdateCallback(NeedsUpdateCallback *callback, void *data)
Invoked when update state goes from clean to dirty.
Definition: Engine.h:214
void setDirty()
Triggers an engine update and updates last dirty frame to the current frame.
Definition: Engine.h:203
uint32_t getLastDirtyFrame()
Get the current frame at the last time setDirty was called.
Definition: Engine.h:211
void invokeCallback(void(*callback)(void *), void *data)
Generic callback invoke wrapper for callbacks with just a data-wrapper, proxied from emscripten worke...
Definition: Engine.h:160
void triggerUpdate()
Triggers an engine update.
Definition: Engine.h:191
Engine & operator=(const Engine &other)=delete
Disable copy assignment of engine instances.
bool workParallel() const
True if it is worthwhile to parallelize work.
Definition: Engine.h:313
bool needsUpdate() const
Gets if the engine is in need of an update.
Definition: Engine.h:180
Engine(const Engine &other)=delete
Disable copying engine instances.
void invokeComponentNotifyCallback(const ComponentModel::Component &component, int notification, const void *data, size_t dataSize)
Invoke the componentNotifyCallback if it exists, proxied from emscripten worker threads.
Definition: Engine.h:163
Contains all Cogs related functionality.
Definition: FieldSetter.h:23
Contains system priority enumeration.
Definition: Engine.h:30
ESystemPriority
Defines priority values for systems.
Definition: Engine.h:44
@ DispatchViewDependent
Quickly dispatch view dependent async tasks before serial view dependent tasks.
Definition: Engine.h:64
@ PreTransform
Run before transformations are updated.
Definition: Engine.h:50
@ Transform
Run at the time of transformations.
Definition: Engine.h:52
@ PostGeometry
Run after geometry updates are performed, e.g to perform calculations on vertex data.
Definition: Engine.h:72
@ PreView
Run after transformations, but before view data is updated.
Definition: Engine.h:56
@ DynamicComponents
Run at the same time as the dynamic components.
Definition: Engine.h:48
@ PreRendering
Run before rendering is performed.
Definition: Engine.h:74
@ PostView
Run after view data has been updated. Anything after this is appropriate for geometry depending on e....
Definition: Engine.h:66
@ PreDynamicComponents
Run before the dynamic components.
Definition: Engine.h:46
@ View
Run at the time view data is updated.
Definition: Engine.h:58
@ LightView
Run at the time light views are updated.
Definition: Engine.h:62
@ Geometry
Run at the time geometry data is updated.
Definition: Engine.h:70
@ PreLightView
Run after view, but before the time light views are updated.
Definition: Engine.h:60
@ PostTransform
Run immediately after transformations are updated.
Definition: Engine.h:54
@ Rendering
Run at the time rendering is performed.
Definition: Engine.h:76
@ PreGeometry
Run before geometry updates are performed.
Definition: Engine.h:68