Cogs.Core
Bridge.cpp
1#include "Bridge.h"
2
3#include "Context.h"
4#include "ViewContext.h"
5#include "Scene.h"
6#include "MemoryContext.h"
7#include "Engine.h"
8#include "EntityStore.h"
9#include "ExtensionRegistry.h"
10#include "Renderer/Renderer.h"
11
12#include "RenderFunctions.h"
13#include "ResourceFunctions.h"
14
15#include "Renderer/CustomRenderer/ImguiRenderer.h"
16#include "Renderer/InspectorGui/InspectorGuiRenderer.h"
17
18#include "Resources/ResourceStore.h"
19#include "Resources/Texture.h"
20
21#include "Components/Core/SceneComponent.h"
22#include "Components/Core/TransformComponent.h"
23#include "Systems/Core/DynamicComponentSystem.h"
24#include "Systems/Core/TransformSystem.h"
25
26#include "Services/Variables.h"
27#include "Utilities/Parsing.h"
28
29#include "Input/InputManager.h"
30#include "Input/InputDeviceType.h"
31
32#include "Serialization/AssetReader.h"
33#include "Serialization/AssetWriter.h"
34#include "Serialization/ModelWriter.h"
35
36#include "Rendering/IGraphicsDevice.h"
37
38#include "Foundation/Platform/WindowData.h"
39#include "Foundation/Logging/Logger.h"
40#include "Foundation/Logging/RedirectedLogger.h"
41
42using namespace Cogs::Core;
43
44namespace
45{
46 const Cogs::Logging::Log logger = Cogs::Logging::getLogger("Bridge");
47 Cogs::Logging::RedirectedLogger* redirectedLogger = nullptr;
48
49 void entityError(const char* method, const EntityId entityId)
50 {
51 LOG_ERROR(logger, "%s: Invalid entity id %zd.", method, size_t(entityId));
52 }
53}
54
55EntityId getNoInternalIdValue()
56{
57 return NoEntity;
58}
59
60void initializeStatic()
61{
63}
64
65void cleanupStatic()
66{
68}
69
70
71BridgeContext* createContext(const char ** variables, const int count) {
72 return new Context(variables, count);
73}
74
75CogsBool initializeContext(BridgeContext* ctx, BridgeView* defaultView, CogsBool initializeEngine) {
76 Context* context = static_cast<Context*>(ctx);
77 ViewContext* view = static_cast<ViewContext*>(defaultView);
78 context->setDefaultView(view);
79
80 if (!context->createDevice()){
81 return false;
82 }
83 if (initializeEngine) {
84 // TODO: have an initialization function in Context that calls into the engine instead of the other way around.
85 context->engine->checkAndUpdateResources();
86 }
87 return true;
88}
89
90CogsBool updateContext(BridgeContext * ctx)
91{
92 auto context = static_cast<Context *>(ctx);
93
94 context->engine->update();
95
96 return context->engine->needsUpdate();
97}
98
99void destroyContext(BridgeContext * ctx)
100{
101 auto context = static_cast<Context *>(ctx);
102
103 auto device = context->device;
104
105 if (device) {
106 //NOTE: Ensure the device is currently enabled while destroying the context. This is necessary due to
107 // OpenGL based devices being bound in the current thread, so we want to free graphics resources from
108 // the device they were actually made on.
109 device->beginFrame();
110 }
111
112 delete context;
113}
114
115BridgeView* createView(BridgeContext* ctx, void* windowData) {
116 Context* context = static_cast<Context*>(ctx);
117 return context->createView(static_cast<Cogs::WindowData*>(windowData));
118}
119
120void destroyView(BridgeView* bv) {
121 ViewContext* view = static_cast<ViewContext*>(bv);
122
123 view->getContext()->deleteView(view);
124}
125
126CogsBool initializeView(BridgeView* bv, EntityId cameraId) {
127 ViewContext* view = static_cast<ViewContext*>(bv);
128 return view->initialize(view->getContext()->store->getEntity(cameraId));
129}
130
131void setViewCamera(BridgeView* bv, EntityId cameraId) {
132 ViewContext* view = static_cast<ViewContext*>(bv);
133 view->setCamera(view->getContext()->store->getEntity(cameraId));
134}
135
136EntityId getViewCamera(BridgeView* bv) {
137 ViewContext* view = static_cast<ViewContext*>(bv);
138 assert(view);
139 EntityPtr cameraEntity = view->getCamera();
140 return cameraEntity ? cameraEntity->getId() : NoEntity;
141}
142
143BridgeContext* getViewContext(BridgeView* bv) {
144 ViewContext* view = static_cast<ViewContext*>(bv);
145 assert(view);
146 return view->getContext();
147}
148
149BridgeView* getDefaultView(BridgeContext* ctx) {
150 Context* context = static_cast<Context*>(ctx);
151 return context->getDefaultView();
152}
153
154void * getSharedSurface(BridgeContext * ctx)
155{
156 return static_cast<Context*>(ctx)->sharedSurface;
157}
158
159void setupContext(BridgeContext * ctx)
160{
161 auto context = static_cast<Context *>(ctx);
162
163 context->scene->setup(true);
164}
165
166void clearContext(BridgeContext * ctx)
167{
168 auto context = static_cast<Context *>(ctx);
169 context->clear();
170}
171
172void prependSearchPath(BridgeContext * ctx, const char * path)
173{
174 addSearchPath(ctx, path);
175 auto context = static_cast<Context*>(ctx);
176 context->engine->setDirty();
177}
178
179CogsBool loadScene(BridgeContext * ctx, const char * filename, int flags)
180{
181 auto context = static_cast<Context*>(ctx);
182 CogsBool rv = readAsset(context, filename, static_cast<AssetLoadFlags>(flags));
183 context->engine->setDirty();
184 return rv;
185}
186
187CogsBool loadAsset(BridgeContext * ctx, const char * filename, EntityId rootId, int flags)
188{
189 const AssetLoadFlags loadFlags = static_cast<AssetLoadFlags>(flags);
190 if ((loadFlags & AssetLoadFlags::ClearScene) == AssetLoadFlags::ClearScene) {
191 LOG_ERROR(logger, "loadAsset: Invalid flag ClearScene - load Ignored");
192 return false;
193 }
194
195 auto context = static_cast<Context*>(ctx);
196 CogsBool rv = readAsset(context, filename, loadFlags, rootId == NoEntity ? nullptr : context->store->getEntityPtr(rootId));
197 context->engine->setDirty();
198 return rv;
199}
200
201CogsBool loadAssetFromString(BridgeContext * ctx, const char* contents, EntityId rootId, int flags)
202{
203 const AssetLoadFlags loadFlags = static_cast<AssetLoadFlags>(flags);
204 if ((loadFlags & AssetLoadFlags::ClearScene) == AssetLoadFlags::ClearScene) {
205 LOG_ERROR(logger, "loadAssetFromString: Invalid flag ClearScene - load Ignored");
206 return false;
207 }
208
209 auto context = static_cast<Context*>(ctx);
210
211 CogsBool rv = readAssetFromString(context, contents, loadFlags, rootId == NoEntity ? nullptr : context->store->getEntityPtr(rootId));
212 context->engine->setDirty();
213 return rv;
214}
215
216CogsBool writeAsset(BridgeContext * ctx, const char * filename, EntityId rootId, int flags)
217{
218 auto context = static_cast<Context*>(ctx);
219 return writeAsset(context, filename, static_cast<AssetWriteFlags>(flags), rootId == NoEntity ? nullptr : context->store->getEntityPtr(rootId));
220}
221
222CogsBool writeModel(BridgeContext * ctx, const char * filename, EntityId rootId)
223{
224 auto context = static_cast<Context*>(ctx);
225 return writeModel(context, filename, context->store->getEntityPtr(rootId));
226}
227
228CogsBool loadPermutations(BridgeContext * ctx, const char * name)
229{
230 auto context = static_cast<Context*>(ctx);
231 CogsBool rv = context->renderer->getEnginePermutations().load(name);
232 context->engine->setDirty();
233 return rv;
234}
235
236EntityId createEntity(BridgeContext * ctx, const char * type)
237{
238 auto context = static_cast<Context *>(ctx);
239
240 auto entity = context->store->createEntity(Cogs::StringView(), type);
241 context->engine->setDirty();
242 return entity->getId();
243}
244
245void destroyEntity(BridgeContext * ctx, EntityId id)
246{
247 auto context = static_cast<Context *>(ctx);
248
249 context->store->destroyEntity(id);
250
251 context->engine->setDirty();
252}
253
254uint32_t getEntityStoreRevision(BridgeContext * ctx)
255{
256 auto context = static_cast<Context *>(ctx);
257 return context->store->getRevision();
258}
259
260const char * getEntityName(BridgeContext * ctx, EntityId entityId)
261{
262 auto context = static_cast<Context *>(ctx);
263 auto entity = context->store->getEntityPtr(entityId);
264 if (!entity) {
265 entityError("getEntityName", entityId);
266 return nullptr;
267 }
268
269 return entity->getName().c_str();
270}
271
272void setEntityName(BridgeContext * ctx, EntityId entityId, const char * name)
273{
274 auto context = static_cast<Context *>(ctx);
275 auto entity = context->store->getEntityPtr(entityId);
276 if (!entity) {
277 entityError("setEntityName", entityId);
278 return;
279 }
280
281 if (entity->getName() != name) {
282 context->store->renameEntity(entity, name);
283 context->engine->setDirty();
284 }
285}
286
287EntityId getEntityParent(BridgeContext * ctx, EntityId entityId)
288{
289 auto context = static_cast<Context*>(ctx);
290 auto entity = context->store->getEntityPtr(entityId);
291
292 if (!entity) {
293 entityError("getEntityParent", entityId);
294 return NoEntity;
295 }
296
297 const auto parent = context->store->getEntityParent(entity);
298 return parent ? parent->getId() : NoEntity;
299}
300
301void addChildEntity(BridgeContext * ctx, EntityId parentId, EntityId childId)
302{
303 auto context = static_cast<Context *>(ctx);
304 auto parent = context->store->getEntityPtr(parentId);
305 auto child = context->store->getEntity(childId);
306 if (parent && child) {
307 context->store->addChild(parent, child);
308 context->engine->setDirty();
309 }
310 else {
311 if (!parent) entityError("addChildEntity(parentId)", parentId);
312 if (!child) entityError("addChildEntity(childId)", childId);
313 }
314}
315
316void removeChildEntity(BridgeContext * ctx, EntityId parentId, EntityId childId)
317{
318 auto context = static_cast<Context *>(ctx);
319 auto parent = context->store->getEntityPtr(parentId);
320 auto child = context->store->getEntityPtr(childId);
321 if (parent && child) {
322 context->store->removeChild(parent, child);
323 context->engine->setDirty();
324 }
325 else {
326 if (!parent) entityError("removeChildEntity(parentId)", parentId);
327 if (!child) entityError("removeChildEntity(childId)", childId);
328 }
329}
330
331void setEntityParent(BridgeContext* ctx, EntityId parentId, EntityId childId)
332{
333 auto context = static_cast<Context*>(ctx);
334 auto child = context->store->getEntityPtr(childId);
335 if (child == nullptr) {
336 entityError("setEntityParent(childId)", childId);
337 }
338 else {
339 Entity* newParent = context->store->getEntityPtr(parentId);
340 if (newParent == nullptr && parentId != NoEntity) {
341 entityError("setEntityParent(parentId)", childId);
342 }
343 else {
344 context->store->setEntityParent(newParent, child);
345 }
346 }
347}
348
349void addComponent(BridgeContext * ctx, EntityId entityId, ComponentId componentId)
350{
351 auto context = static_cast<Context*>(ctx);
352 auto entity = context->store->getEntityPtr(entityId);
353 if (!entity) {
354 entityError("addComponent", entityId);
355 return;
356 }
357
358 context->store->addComponent(entity, componentId);
359 context->engine->setDirty();
360}
361
362void removeComponent(BridgeContext * ctx, EntityId entityId, ComponentId componentId)
363{
364 auto context = static_cast<Context*>(ctx);
365 auto entity = context->store->getEntityPtr(entityId);
366 if (!entity) {
367 entityError("removeComponent", entityId);
368 return;
369 }
370
371 context->store->removeComponent(entity, entity->getComponentHandle(componentId));
372 context->engine->setDirty();
373}
374
375int getChildren(BridgeContext * ctx, EntityId entityId, EntityId * ids, int idCount)
376{
377 auto context = static_cast<Context*>(ctx);
378 auto entity = context->store->getEntityPtr(entityId);
379 if (!entity) {
380 entityError("getChildren", entityId);
381 return 0;
382 }
383
384 auto sceneComponent = entity->getComponent<SceneComponent>();
385
386 if (!sceneComponent) {
387 return 0;
388 }
389
390 if (sceneComponent->children.size() > static_cast<size_t>(idCount)) {
391 // Notify client about number of clients as a negative.
392 // LOG_ERROR(logger, "Too many child instances (%zd) in entity with id: %zd, name: %s", sceneComponent->children.size(), entityId, entity->getName().c_str());
393 return -static_cast<int>(sceneComponent->children.size());
394 }
395
396 int index = 0;
397 for (auto & c : sceneComponent->children) {
398 ids[index++] = c->getId();
399 }
400
401 return static_cast<int>(sceneComponent->children.size());
402}
403
404int getEntitiesWithComponent(BridgeContext * ctx, ComponentId componentId, EntityId * ids, int idCount)
405{
406 auto context = static_cast<Context*>(ctx);
407 std::vector<EntityId> entities;
408 context->store->getEntitiesWithComponent(entities, componentId);
409 if (static_cast<size_t>(idCount) < entities.size()) {
410 return -static_cast<int>(entities.size());
411 }
412 std::memcpy(ids, entities.data(), sizeof(EntityId)*entities.size());
413 return static_cast<int>(entities.size());
414}
415
416
417int getComponents(BridgeContext * ctx, EntityId entityId, ComponentId * ids)
418{
419 auto context = static_cast<Context*>(ctx);
420 auto entity = context->store->getEntityPtr(entityId);
421 if (!entity) {
422 entityError("getComponents", entityId);
423 return 0;
424 }
425
426 auto & components = entity->getComponents();
427
428 if (ids) {
429 int index = 0;
430 for (auto& c : components) {
431 ids[index++] = c.resolve()->getTypeId();
432 }
433 }
434
435 return static_cast<int>(components.size());
436}
437
438EntityId getEntityId(BridgeContext * ctx, const char * name)
439{
440 auto context = static_cast<Context *>(ctx);
441
442 auto entity = context->store->findEntity(name, nullptr);
443
444 return entity ? entity->getId() : NoEntity;
445}
446
447EntityId getEntityFull(BridgeContext * ctx, EntityId rootId, const char* name, const int exactName )
448{
449 auto context = static_cast<Context*>(ctx);
450
451 auto searchFlag = (exactName <= 0 || exactName > (int)Cogs::Core::EntityFind::MaxFlag) ? Cogs::Core::EntityFind::PartialNameMatch : Cogs::Core::EntityFind(exactName);
452
453 auto entity = context->store->findEntity(name, (rootId != NoEntity) ? context->store->getEntityPtr(rootId) : nullptr, searchFlag);
454
455 return entity? entity->getId() : NoEntity;
456}
457
458const char * getEntityTemplate(BridgeContext * ctx, EntityId entityId)
459{
460 auto context = static_cast<Context*>(ctx);
461 auto entity = context->store->getEntityPtr(entityId);
462
463 if (!entity) return nullptr;
464
465 size_t templateId = static_cast<const EntityData *>(entity->getUserData())->templateId;
466 const EntityDefinition* definition = context->store->getEntityDefinition(templateId);
467
468 if (!definition) return nullptr;
469
470 return definition->name.c_str();
471}
472
473int getNumComponents(BridgeContext* ctx, EntityId entityId)
474{
475 auto context = static_cast<Context*>(ctx);
476 const Cogs::ComponentModel::Entity* entity = context->store->getEntityPtr(entityId);
477 if (entity) {
478 return static_cast<int>(entity->getComponents().size());
479 }
480 else {
481 return -1;
482 }
483}
484
485int getComponentType(BridgeContext* ctx, EntityId entityId, int componentNo)
486{
487 auto context = static_cast<Context*>(ctx);
488 const Cogs::ComponentModel::Entity* entity = context->store->getEntityPtr(entityId);
489 if (entity) {
490 const auto& components = entity->getComponents();
491 const size_t index = static_cast<size_t>(componentNo);
492 if (index < components.size()) {
493 auto compPtr = components[index].resolve();
494 if (compPtr) {
495 return compPtr->getTypeId();
496 }
497 }
498 }
499
500 return NoComponentId;
501}
502
503void setLoggerLevel(const char* level)
504{
508}
509
510void setLoggerCallback(LoggerCallback * callback)
511{
512 if (callback) {
513 if (!redirectedLogger) {
514 redirectedLogger = new Cogs::Logging::RedirectedLogger();
515 redirectedLogger->setLoggerCallback(callback);
516 }
517 }
518 else if (redirectedLogger){
519 redirectedLogger->setLoggerCallback(nullptr);
520
521 if (!redirectedLogger->getFileLineLoggerCallback()) {
522 delete redirectedLogger;
523 redirectedLogger = nullptr;
524 }
525 }
526}
527
528void setFileLineLoggerCallback(FileLineLoggerCallback * callback)
529{
530 if (callback) {
531 if (!redirectedLogger) {
532 redirectedLogger = new Cogs::Logging::RedirectedLogger();
533 redirectedLogger->setFileLineLoggerCallback(callback);
534 }
535 }
536 else if (redirectedLogger){
537 redirectedLogger->setFileLineLoggerCallback(nullptr);
538
539 if (!redirectedLogger->getLoggerCallback()) {
540 delete redirectedLogger;
541 redirectedLogger = nullptr;
542 }
543 }
544}
545
546void setUpdateCallback(BridgeContext * ctx, ::NeedsUpdateCallback* callback, void* data)
547{
548 auto context = static_cast<Context*>(ctx);
549 context->engine->setNeedsUpdateCallback(callback, data);
550}
551
552CogsBool needsUpdate(BridgeContext * ctx) {
553 const Context* context = static_cast<const Context*>(ctx);
554 return context->engine->needsUpdate();
555}
556
557void setVariable(BridgeContext * ctx, const char * name, const char * value)
558{
559 auto context = static_cast<Context *>(ctx);
560 context->variables->set(name, value);
561 context->engine->setDirty();
562}
563
564void setBoolVariable(BridgeContext * ctx, const char * name, CogsBool value)
565{
566 auto context = static_cast<Context *>(ctx);
567 context->variables->set(name, value);
568 context->engine->setDirty();
569}
570
571void setIntVariable(BridgeContext * ctx, const char * name, int value)
572{
573 auto context = static_cast<Context *>(ctx);
574 context->variables->set(name, value);
575 context->engine->setDirty();
576}
577
578void setFloatVariable(BridgeContext * ctx, const char * name, float value)
579{
580 auto context = static_cast<Context *>(ctx);
581 context->variables->set(name, value);
582 context->engine->setDirty();
583}
584
585void setDoubleVariable(BridgeContext * ctx, const char * name, double value)
586{
587 auto context = static_cast<Context *>(ctx);
588 context->variables->set(name, value);
589 context->engine->setDirty();
590}
591
592CogsBool hasVariable(BridgeContext* ctx, const char* name)
593{
594 auto context = static_cast<Context*>(ctx);
595 return context->variables->exist(name);
596}
597
598char * getVariable(BridgeContext * ctx, const char * name)
599{
600 auto context = static_cast<Context *>(ctx);
601 return const_cast<char *>(context->variables->get(name, nullptr));
602}
603
604CogsBool getBoolVariable(BridgeContext * ctx, const char * name)
605{
606 auto context = static_cast<Context *>(ctx);
607 return context->variables->get(name, false);
608}
609
610int getIntVariable(BridgeContext * ctx, const char * name)
611{
612 auto context = static_cast<Context *>(ctx);
613 return context->variables->get(name, 0);
614}
615
616float getFloatVariable(BridgeContext * ctx, const char * name)
617{
618 auto context = static_cast<Context *>(ctx);
619 return context->variables->get(name, 0.0f);
620}
621
622double getDoubleVariable(BridgeContext * ctx, const char * name)
623{
624 auto context = static_cast<Context *>(ctx);
625 return context->variables->get(name, 0.0);
626}
627
628char * getVariableOrDefault(BridgeContext * ctx, const char * name, const char * defaultValue)
629{
630 Context* context = static_cast<Context *>(ctx);
631 return const_cast<char *>(context->variables->get(name, defaultValue));
632}
633
634CogsBool getBoolVariableOrDefault(BridgeContext * ctx, const char * name, CogsBool defaultValue)
635{
636 Context* context = static_cast<Context *>(ctx);
637 return context->variables->get(name, defaultValue);
638}
639
640int getIntVariableOrDefault(BridgeContext * ctx, const char * name, int defaultValue)
641{
642 Context* context = static_cast<Context *>(ctx);
643 return context->variables->get(name, defaultValue);
644}
645
646float getFloatVariableOrDefault(BridgeContext * ctx, const char * name, float defaultValue)
647{
648 Context* context = static_cast<Context *>(ctx);
649 return context->variables->get(name, defaultValue);
650}
651
652double getDoubleVariableOrDefault(BridgeContext * ctx, const char * name, double defaultValue)
653{
654 Context* context = static_cast<Context *>(ctx);
655 return context->variables->get(name, defaultValue);
656}
657
658CogsBool eraseVariable(BridgeContext * ctx, const char * name)
659{
660 auto context = static_cast<Context *>(ctx);
661 context->engine->setDirty();
662 return context->variables->erase(name);
663}
664
665
666const void* loadExtensionModule(const char * name)
667{
669}
670
671CogsBool checkExtension(const char * name)
672{
674}
675
676void* getExtensionSymbol(const char * extension, const char* symbol)
677{
678 return ExtensionRegistry::getExtensionSymbol(extension, symbol);
679}
680
681
682const char * getLicenseText(BridgeContext * ctx)
683{
684 auto context = static_cast<Context *>(ctx);
685
686 static std::string text = context->resourceStore->getResourceContentString("Licenses.md");
687
688 return text.c_str();
689}
690
691void setPostSystemsUpdateCallback(BridgeContext* ctx, ::RenderCallback* callback)
692{
693 static_cast<Context*>(ctx)->callbacks.postSystemsUpdateCallback = reinterpret_cast<Cogs::Core::RenderCallback*>(callback);
694}
695
696void setPreRenderCallback(BridgeContext* ctx, ::RenderCallback* callback)
697{
698 static_cast<Context*>(ctx)->callbacks.preRenderCallback = reinterpret_cast<Cogs::Core::RenderCallback*>(callback);
699}
700
701void setPostRenderCallback(BridgeContext* ctx, ::RenderCallback* callback)
702{
703 static_cast<Context*>(ctx)->callbacks.postRenderCallback = reinterpret_cast<Cogs::Core::RenderCallback*>(callback);
704}
705
706void setComponentNotifyCallback(BridgeContext* ctx, ::ComponentNotifyCallback* callback)
707{
708 Context* context = static_cast<Context*>(ctx);
709 if (callback && context->callbacks.componentNotifyCallback) {
710 LOG_WARNING(logger, "Replacing non-null componentNotifyCallback, set to null first to remove this message");
711 }
712 context->callbacks.componentNotifyCallback = callback;
713}
714
715ComponentNotifyCallback* getComponentNotifyCallback(BridgeContext* ctx)
716{
717 Context* context = static_cast<Context*>(ctx);
718 return context->callbacks.componentNotifyCallback;
719}
720
721
722void registerDynamicType(BridgeContext * ctx, const char * name, size_t messageMask)
723{
724 auto context = static_cast<Context *>(ctx);
725 context->dynamicComponentSystem->registerType(context, name, messageMask);
726}
727
728void registerMessageCallback(BridgeContext * ctx, EntityId entityId, ComponentId componentId, void * callback)
729{
730 auto context = static_cast<Context *>(ctx);
731 auto entity = context->store->getEntityPtr(entityId);
732 if (!entity) {
733 entityError("registerMessageCallback", entityId);
734 return;
735 }
736
737 auto component = entity->getComponent(componentId);
738
739 auto dynamicComponent = (DynamicComponent *)component;
740
741 dynamicComponent->messageCallback = callback;
742}
743
744void registerUserData(BridgeContext * ctx, EntityId entityId, ComponentId componentId, void * userData)
745{
746 auto context = static_cast<Context *>(ctx);
747 auto entity = context->store->getEntityPtr(entityId);
748 if (!entity) {
749 entityError("registerUserData", entityId);
750 return;
751 }
752
753 auto component = entity->getComponent(componentId);
754
755 auto dynamicComponent = (DynamicComponent *)component;
756
757 dynamicComponent->userData = userData;
758}
759
760int getMessageId(BridgeContext * ctx, const char * name)
761{
762 auto context = static_cast<Context *>(ctx);
763
764 return static_cast<int>(context->dynamicComponentSystem->getMessageId(name));
765}
766
767void addInputActionMapping(BridgeContext * ctx, const char * name, const char * device, const char * action)
768{
769 auto context = static_cast<Context *>(ctx);
770
771 context->getDefaultView()->inputManager->addActionMapping(name, device, action);
772}
773
774
775CogsBool getInputAction(BridgeContext * ctx, const char * name)
776{
777 auto context = static_cast<Context *>(ctx);
778
779 return context->getDefaultView()->inputManager->getActionState(name) ? 1 : 0;
780}
781
782void addInputAxisMapping(BridgeContext * ctx, const char * name, const char * device, const char * axis, float scale)
783{
784 auto context = static_cast<Context *>(ctx);
785
786 context->getDefaultView()->inputManager->addAxisMapping(name, device, axis, scale);
787}
788
789float getInputAxis(BridgeContext * ctx, const char * name)
790{
791 auto context = static_cast<Context *>(ctx);
792
793 return context->getDefaultView()->inputManager->getAxisValue(name);
794}
795
796void gainedFocus(BridgeView* bv, double timestamp_ms) {
797 ViewContext* viewContext = static_cast<ViewContext*>(bv);
798 viewContext->inputManager->gainedFocus(timestamp_ms);
799}
800
801void lostFocus(BridgeView* bv, double timestamp_ms) {
802 ViewContext* viewContext = static_cast<ViewContext*>(bv);
803 viewContext->inputManager->lostFocus(timestamp_ms);
804}
805
806void inputTriggerPointerPress(BridgeView* bv, int pointerType, PointerId pointerId, int button, int x, int y, double timestamp_ms) {
807 Cogs::PointerType type = static_cast<Cogs::PointerType>(pointerType);
808 Cogs::MouseButton btn = static_cast<Cogs::MouseButton>(button);
809 ViewContext* viewContext = static_cast<ViewContext*>(bv);
810 viewContext->inputManager->triggerPointerPress(type, pointerId, btn, {x, y}, timestamp_ms);
811
812}
813
814void inputTriggerPointerRelease(BridgeView* bv, int pointerType, PointerId pointerId, int button, int x, int y, double timestamp_ms) {
815 Cogs::PointerType type = static_cast<Cogs::PointerType>(pointerType);
816 Cogs::MouseButton btn = static_cast<Cogs::MouseButton>(button);
817 ViewContext* viewContext = static_cast<ViewContext*>(bv);
818 viewContext->inputManager->triggerPointerRelease(type, pointerId, btn, {x, y}, timestamp_ms);
819
820}
821
822void inputTriggerPointerMove(BridgeView* bv, int pointerType, PointerId pointerId, int x, int y, double timestamp_ms) {
823 Cogs::PointerType type = static_cast<Cogs::PointerType>(pointerType);
824 ViewContext* viewContext = static_cast<ViewContext*>(bv);
825 viewContext->inputManager->triggerPointerMove(type, pointerId, {x, y}, timestamp_ms);
826}
827
828void inputTriggerMouseWheel(BridgeView* bv, int deltaValue, double timestamp_ms) {
829 ViewContext* viewContext = static_cast<ViewContext*>(bv);
830 viewContext->inputManager->triggerMouseWheel(deltaValue, timestamp_ms);
831}
832
833void inputTriggerKeyDown(BridgeView* bv, int key, double timestamp_ms) {
834 ViewContext* viewContext = static_cast<ViewContext*>(bv);
835 viewContext->inputManager->triggerKeyDown(static_cast<Cogs::Key>(key), timestamp_ms);
836}
837
838void inputTriggerKeyUp(BridgeView* bv, int key, double timestamp_ms) {
839 ViewContext* viewContext = static_cast<ViewContext*>(bv);
840 viewContext->inputManager->triggerKeyUp(static_cast<Cogs::Key>(key), timestamp_ms);
841}
842
843void inputTriggerKeyChar(BridgeView* bv, const char* ch, double timestamp_ms) {
844 ViewContext* viewContext = static_cast<ViewContext*>(bv);
845 viewContext->inputManager->triggerKeyChar(ch, timestamp_ms);
846}
847
848// Input Focus is handled for all views, but passing view for input functions consistency.
849CogsBool hasGuiInputFocus(BridgeView* /*bv*/, int inputDeviceTypes)
850{
851 Cogs::Core::InputDeviceType deviceTypes = static_cast<Cogs::Core::InputDeviceType>(inputDeviceTypes);
852 if (deviceTypes == None) {
853 LOG_WARNING_ONCE(logger, "hasGuiInputFocus - no devices to check");
854 }
855 else if ((deviceTypes & InputDeviceType::Keyboard) == InputDeviceType::Keyboard && Cogs::Core::ImguiRenderer::isUsingKeyboard()) {
856 return true;
857 }
858 else if ((deviceTypes & InputDeviceType::Mouse) == InputDeviceType::Mouse && Cogs::Core::ImguiRenderer::isUsingMouse()) {
859 return true;
860 }
861
862 return false;
863}
864
865void setClipboardCallbacks(GetClipboardTextFn getter, SetClipboardTextFn setter) {
866 ImguiRenderer::setClipboardCallbacks(getter, setter);
867}
Container for components, providing composition of dynamic entities.
Definition: Entity.h:18
T * getComponent() const
Get a pointer to the first component implementing the given type in the entity.
Definition: Entity.h:35
constexpr size_t getId() const noexcept
Get the unique identifier of this entity.
Definition: Entity.h:113
void getComponents(ComponentCollection< T > &collection) const
Get all the components implementing the templated type.
Definition: Entity.h:52
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
static void cleanupStatic()
Perform static cleanup of the Context.
Definition: Context.cpp:216
class IRenderer * renderer
Renderer.
Definition: Context.h:228
static void initializeStatic()
Perform static initialization of the Context.
Definition: Context.cpp:191
void clear()
Does clearing of context.
Definition: Context.cpp:357
class EntityStore * store
Entity store.
Definition: Context.h:231
std::unique_ptr< class Variables > variables
Variables service instance.
Definition: Context.h:180
std::unique_ptr< class ResourceStore > resourceStore
ResourceStore service instance.
Definition: Context.h:210
std::unique_ptr< class Engine > engine
Engine instance.
Definition: Context.h:222
std::unique_ptr< class Scene > scene
Scene structure.
Definition: Context.h:225
Base class for components implementing dynamic behavior.
EntityPtr getEntity(const StringView &name, bool logIfNotFound=true) const
Retrieve a reference to the shared entity pointer to the Entity with the given name.
ComponentModel::Component * addComponent(ComponentModel::Entity *entity, Reflection::TypeId typeId)
Add a component of the given type to the entity.
void addChild(ComponentModel::Entity *parent, const EntityPtr &entity)
Add a child to the given parent.
void renameEntity(ComponentModel::Entity *entityPtr, StringView name)
Rename the given entity.
const EntityDefinition * getEntityDefinition(const StringView &name) const
Fetch the entity definition with the given name from the store.
Definition: EntityStore.cpp:92
ComponentModel::Entity * getEntityPtr(const EntityId entityId)
Get a raw pointer to the entity with the given id.
void destroyEntity(const EntityId id)
Destroy the entity with the given id.
Cogs::ComponentModel::Entity * getEntityParent(const ComponentModel::Entity *entity) const
Gets the parent of the given entity.
void setEntityParent(ComponentModel::Entity *parent, ComponentModel::Entity *child)
Move Root entity to a parent: Equal to addChild(parent, child) + destroyEntity(child) Move Child enti...
EntityPtr createEntity(const StringView &name, const StringView &type, bool storeOwnership=true)
Create a new Entity.
void removeChild(ComponentModel::Entity *parent, const ComponentModel::Entity *entity)
Remove the parent-child relationship between parent and entity.
EntityPtr findEntity(const StringView &name, const ComponentModel::Entity *root=nullptr, EntityFind findOptions=EntityFind::Default) const
Finds an entity with the given name.
uint32_t getRevision() const
Returns a number that changes every time an entity is created or destroyed.
Definition: EntityStore.h:358
static bool hasExtension(const StringView &key, bool silent=false)
Check if an extension with the given key is present in this build.
static const void * loadExtensionModule(const std::string &path, void **modulehandle=nullptr, ExtensionModuleLoadResult *result=nullptr)
Load the extension module with the given name.
static void * getExtensionSymbol(const char *extension, const char *name)
Retrieves the address of a symbol in the extension module.
virtual EnginePermutations & getEnginePermutations()=0
Get the reference to the EnginePermutations structure.
static bool isUsingMouse()
Tests whether any ImGui control is being interacted with, or if the mouse is over an ImGui window or ...
static bool isUsingKeyboard()
Tests whether any ImGui control is currently accepting text input.
Contains information on how the entity behaves in the scene.
Cogs::Core::EntityPtr getCamera() const
Gets view camera. The camera must be valid when rendering a frame in the view.
void setCamera(const Cogs::Core::EntityPtr &renderCamera)
Sets or updates the camera of this ViewContext instance.
std::unique_ptr< class InputManager > inputManager
Definition: ViewContext.h:78
bool initialize(const Cogs::Core::EntityPtr &renderCamera)
Initialises the standard components in this ViewContext instance.
Definition: ViewContext.cpp:62
static void setDefaultMinimumCategory(Category category)
Sets the default minimum category for all future consumers.
Definition: Consumer.cpp:39
Log implementation class.
Definition: LogManager.h:140
RedirectedLogger is a message consumer that forwards any incoming message to the callback functions r...
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:50
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
Definition: EntityPtr.h:12
EntityFind
Options to findEntity/getEntityFull.
Definition: EntityStore.h:34
@ MaxFlag
Do not go beyond this flag. Used as bounding value.
@ PartialNameMatch
Search for the first entity that partially contains the specified name.
AssetWriteFlags
Flags that control serialization of assets.
AssetLoadFlags
Asset and Scene loading flags. May be combined with resource loading flags.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:181
Category COGSFOUNDATION_API parseCategoryString(const StringView category)
Utility function that takes a loglevel name as a string and returns the corresponding log level enum ...
Definition: LogManager.cpp:290
void COGSFOUNDATION_API updateLoggerCategory(Category category)
Definition: LogManager.cpp:219
Category
Logging categories used to filter log messages.
Definition: LogManager.h:31
Holds extra housekeeping data for an Entity instance.
Definition: EntityStore.h:24
Defines how to construct entities of a certain type by a list of components to instantiate and defaul...