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
715
716void registerDynamicType(BridgeContext * ctx, const char * name, size_t messageMask)
717{
718 auto context = static_cast<Context *>(ctx);
719 context->dynamicComponentSystem->registerType(context, name, messageMask);
720}
721
722void registerMessageCallback(BridgeContext * ctx, EntityId entityId, ComponentId componentId, void * callback)
723{
724 auto context = static_cast<Context *>(ctx);
725 auto entity = context->store->getEntityPtr(entityId);
726 if (!entity) {
727 entityError("registerMessageCallback", entityId);
728 return;
729 }
730
731 auto component = entity->getComponent(componentId);
732
733 auto dynamicComponent = (DynamicComponent *)component;
734
735 dynamicComponent->messageCallback = callback;
736}
737
738void registerUserData(BridgeContext * ctx, EntityId entityId, ComponentId componentId, void * userData)
739{
740 auto context = static_cast<Context *>(ctx);
741 auto entity = context->store->getEntityPtr(entityId);
742 if (!entity) {
743 entityError("registerUserData", entityId);
744 return;
745 }
746
747 auto component = entity->getComponent(componentId);
748
749 auto dynamicComponent = (DynamicComponent *)component;
750
751 dynamicComponent->userData = userData;
752}
753
754int getMessageId(BridgeContext * ctx, const char * name)
755{
756 auto context = static_cast<Context *>(ctx);
757
758 return static_cast<int>(context->dynamicComponentSystem->getMessageId(name));
759}
760
761void addInputActionMapping(BridgeContext * ctx, const char * name, const char * device, const char * action)
762{
763 auto context = static_cast<Context *>(ctx);
764
765 context->getDefaultView()->inputManager->addActionMapping(name, device, action);
766}
767
768
769CogsBool getInputAction(BridgeContext * ctx, const char * name)
770{
771 auto context = static_cast<Context *>(ctx);
772
773 return context->getDefaultView()->inputManager->getActionState(name) ? 1 : 0;
774}
775
776void addInputAxisMapping(BridgeContext * ctx, const char * name, const char * device, const char * axis, float scale)
777{
778 auto context = static_cast<Context *>(ctx);
779
780 context->getDefaultView()->inputManager->addAxisMapping(name, device, axis, scale);
781}
782
783float getInputAxis(BridgeContext * ctx, const char * name)
784{
785 auto context = static_cast<Context *>(ctx);
786
787 return context->getDefaultView()->inputManager->getAxisValue(name);
788}
789
790void gainedFocus(BridgeView* bv, double timestamp_ms) {
791 ViewContext* viewContext = static_cast<ViewContext*>(bv);
792 viewContext->inputManager->gainedFocus(timestamp_ms);
793}
794
795void lostFocus(BridgeView* bv, double timestamp_ms) {
796 ViewContext* viewContext = static_cast<ViewContext*>(bv);
797 viewContext->inputManager->lostFocus(timestamp_ms);
798}
799
800void inputTriggerPointerPress(BridgeView* bv, int pointerType, PointerId pointerId, int button, int x, int y, double timestamp_ms) {
801 Cogs::PointerType type = static_cast<Cogs::PointerType>(pointerType);
802 Cogs::MouseButton btn = static_cast<Cogs::MouseButton>(button);
803 ViewContext* viewContext = static_cast<ViewContext*>(bv);
804 viewContext->inputManager->triggerPointerPress(type, pointerId, btn, {x, y}, timestamp_ms);
805
806}
807
808void inputTriggerPointerRelease(BridgeView* bv, int pointerType, PointerId pointerId, int button, int x, int y, double timestamp_ms) {
809 Cogs::PointerType type = static_cast<Cogs::PointerType>(pointerType);
810 Cogs::MouseButton btn = static_cast<Cogs::MouseButton>(button);
811 ViewContext* viewContext = static_cast<ViewContext*>(bv);
812 viewContext->inputManager->triggerPointerRelease(type, pointerId, btn, {x, y}, timestamp_ms);
813
814}
815
816void inputTriggerPointerMove(BridgeView* bv, int pointerType, PointerId pointerId, int x, int y, double timestamp_ms) {
817 Cogs::PointerType type = static_cast<Cogs::PointerType>(pointerType);
818 ViewContext* viewContext = static_cast<ViewContext*>(bv);
819 viewContext->inputManager->triggerPointerMove(type, pointerId, {x, y}, timestamp_ms);
820}
821
822void inputTriggerMouseWheel(BridgeView* bv, int deltaValue, double timestamp_ms) {
823 ViewContext* viewContext = static_cast<ViewContext*>(bv);
824 viewContext->inputManager->triggerMouseWheel(deltaValue, timestamp_ms);
825}
826
827void inputTriggerKeyDown(BridgeView* bv, int key, double timestamp_ms) {
828 ViewContext* viewContext = static_cast<ViewContext*>(bv);
829 viewContext->inputManager->triggerKeyDown(static_cast<Cogs::Key>(key), timestamp_ms);
830}
831
832void inputTriggerKeyUp(BridgeView* bv, int key, double timestamp_ms) {
833 ViewContext* viewContext = static_cast<ViewContext*>(bv);
834 viewContext->inputManager->triggerKeyUp(static_cast<Cogs::Key>(key), timestamp_ms);
835}
836
837void inputTriggerKeyChar(BridgeView* bv, const char* ch, double timestamp_ms) {
838 ViewContext* viewContext = static_cast<ViewContext*>(bv);
839 viewContext->inputManager->triggerKeyChar(ch, timestamp_ms);
840}
841
842// Input Focus is handled for all views, but passing view for input functions consistency.
843CogsBool hasGuiInputFocus(BridgeView* /*bv*/, int inputDeviceTypes)
844{
845 Cogs::Core::InputDeviceType deviceTypes = static_cast<Cogs::Core::InputDeviceType>(inputDeviceTypes);
846 if (deviceTypes == None) {
847 LOG_WARNING_ONCE(logger, "hasGuiInputFocus - no devices to check");
848 }
849 else if ((deviceTypes & InputDeviceType::Keyboard) == InputDeviceType::Keyboard && Cogs::Core::ImguiRenderer::isUsingKeyboard()) {
850 return true;
851 }
852 else if ((deviceTypes & InputDeviceType::Mouse) == InputDeviceType::Mouse && Cogs::Core::ImguiRenderer::isUsingMouse()) {
853 return true;
854 }
855
856 return false;
857}
858
859void setClipboardCallbacks(GetClipboardTextFn getter, SetClipboardTextFn setter) {
860 ImguiRenderer::setClipboardCallbacks(getter, setter);
861}
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:214
class IRenderer * renderer
Renderer.
Definition: Context.h:228
static void initializeStatic()
Perform static initialization of the Context.
Definition: Context.cpp:189
void clear()
Does clearing of context.
Definition: Context.cpp:355
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:139
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:24
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:180
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...