Cogs.Core
EntityStore.cpp
1#include "EntityStore.h"
2
3#include "Systems/Core/TransformSystem.h"
4
5#include "Components/Core/RenderComponent.h"
6
7#include "Systems/Core/SceneSystem.h"
8
9#include "Services/DeferredNameResolution.h"
10
11#include "EntityDefinitions.h"
12#include "Context.h"
13#include "MemoryContext.h"
14
15#include "Serialization/AssetReader.h"
16
17#include "Foundation/Logging/Logger.h"
18#include "Foundation/HashFunctions.h"
19#include "Foundation/Reflection/TypeDatabase.h"
20
21#include <algorithm>
22
23using namespace Cogs::Reflection;
24
25namespace
26{
27 const Cogs::Logging::Log logger = Cogs::Logging::getLogger("EntityStore");
28}
29
31 entityPool(8192, 8192, context->memory->baseAllocator, MemBlockType::Entity),
32 entityDataPool(MemBlockType::Entity)
33{
34 LOG_TRACE(logger, "Initializing entity store...");
35
36 this->context = context;
37
38 LOG_TRACE(logger, "Initializing entity definitions...");
39
41
42 LOG_TRACE(logger, "Entity definitions initialized.");
43}
44
46{
47 LOG_DEBUG(logger, "Cleaning up entities...");
48
49 entitiesByName.clear();
50 entities.clear();
51
52 if (entityPool.size()) {
53 LOG_WARNING(logger, "%zd entities allocated after clear. First N(6) from default scene", entityPool.size());
54 }
55
56 LOG_DEBUG(logger, "Entity store cleaned up.");
57}
58
60{
61 const size_t hashCode = Cogs::hash(definition.name);
62
63 if (entityDefinitions.contains(hashCode)) {
64 LOG_WARNING(logger, "Overwriting existing entity definition for %s.", definition.name.c_str());
65 }
66 LOG_TRACE(logger, "Adding entity definition for %s.", definition.name.c_str());
67
68 entityDefinitions[hashCode] = definition;
69}
70
71void Cogs::Core::EntityStore::getEntityDefinitions(std::vector<StringView>& names) const
72{
73 names.clear();
74 names.reserve(entityDefinitions.size());
75 for (const auto & [_, def] : entityDefinitions) {
76 names.emplace_back(def.name);
77 }
78}
79
80void Cogs::Core::EntityStore::getEntityDefinitionComponents(std::vector<StringView>& components, const StringView & name) const
81{
82 components.clear();
83 if (auto * def = getEntityDefinition(name); def) {
84 components.reserve(def->components.size());
85 for (auto & c : def->components) {
86 components.emplace_back(c);
87 }
88 }
89}
90
91
93{
94 return getEntityDefinition(Cogs::hash(name));
95}
96
98{
99 auto fIt = entityDefinitions.find(id);
100
101 return fIt != entityDefinitions.end() ? &fIt->second : nullptr;
102}
103
105{
106 auto entityPtr = entityPool.create();
107 auto entityData = entityDataPool.create();
108 auto entity = EntityPtr(entityPtr, [&](Entity * e)
109 {
110 this->destroyEntityComponents(e);
111
112 entityDataPool.destroy(static_cast<EntityData*>(e->getUserData()));
113 e->setId(NoEntity);
114 entityPool.destroy(e);
115 revision++;
116 });
117
118 auto entityId = entityPool.getHandle(entityPtr);
119
120 entity->setId(entityId);
121
122 if (storeOwnership) {
123 entities[entityId] = entity;
124 }
125
126 if (name.size()) {
127 context->deferredResolution->scheduleRescan();
128 entity->setName(name);
129
130 if (storeOwnership) {
131 storeNamedEntity(entity, name);
132 }
133 }
134
135 const size_t typeCode = Cogs::hash(type);
136
137 entityData->templateId = typeCode;
138 entity->setUserData(entityData);
139
140 auto definitionIt = entityDefinitions.find(typeCode);
141
142 if (definitionIt != entityDefinitions.end()) {
143 auto & entityDefinition = definitionIt->second;
144
145 createEntityComponents(entityDefinition, entity);
146
147 applyFieldValues(context, {entityDefinition.defaultValues}, entity.get());
148 } else {
149 LOG_WARNING(logger, "Could not find entity definition for type: %.*s, name:%.*s. No components will be added.", StringViewFormat(type), StringViewFormat(name));
150 }
151
152 revision++;
153 return entity;
154}
155
156void Cogs::Core::EntityStore::createEntities(size_t count, std::vector<EntityPtr> & entities)
157{
158 createEntities(count, entities, [&](Entity * e)
159 {
160 this->destroyEntityComponents(e);
161
162 entityDataPool.destroy(static_cast<EntityData*>(e->getUserData()));
163 e->setId(NoEntity);
164 entityPool.destroy(e);
165 });
166}
167
168void Cogs::Core::EntityStore::createEntities(size_t count, std::vector<EntityPtr> & entities, std::function<void(Entity *)> destructor)
169{
170 entities.resize(count);
171
172 for (EntityPtr & entity : entities) {
173 Entity* entityPtr = entityPool.create();
174 EntityData* entityData = entityDataPool.create();
175 entityPtr->setUserData(entityData);
176
177 entity = EntityPtr(entityPtr, destructor);
178 auto entityId = entityPool.getHandle(entityPtr);
179
180 entity->setId(entityId);
181 }
182}
183
184void Cogs::Core::EntityStore::createEntityComponents(EntityDefinition & entityDefinition, const EntityPtr & entity)
185{
186 if (!entityDefinition.compiled) {
187 compileEntityDefinition(entityDefinition);
188 }
189
190 for (auto creator : entityDefinition.creators) {
191 auto component = (*creator)();
192
193 if (component.resolve()) {
194 entity->addComponent(component);
195 } else {
196 LOG_ERROR(logger, "Null component returned by system creator.");
197 }
198 }
199}
200
201void Cogs::Core::EntityStore::compileEntityDefinition(EntityDefinition & entityDefinition)
202{
203 for (const std::string& componentName : entityDefinition.components) {
204 const Reflection::Type & type = TypeDatabase::getType(componentName);
205
206 if (!type.isValid()) {
207 LOG_ERROR(logger, "Type \"%s\" not valid as component.", componentName.c_str());
208 continue;
209 }
210
211 auto creatorIt = creators.find(type.getTypeId());
212
213 if (creatorIt != creators.end()) {
214 entityDefinition.creators.push_back(&creators[type.getTypeId()]);
215 } else {
216 LOG_ERROR(logger, "No creator function available for components of type %s.", componentName.c_str());
217 }
218 }
219
220 entityDefinition.compiled = true;
221}
222
224{
225 debug_assert(parent && "Invalid parent entity pointer.");
226 debug_assert(entity && "Invalid entity cannot be parented.");
227 if (!parent || !entity) return;
228
229 TransformComponent* transform = entity->getComponent<TransformComponent>();
230 const TransformComponent* parentTransform = parent->getComponent<TransformComponent>();
231
232 bool noTransform = false;
233 bool noScene = false;
234
235 if (transform && parentTransform) {
236 transform->parent = context->transformSystem->getHandle(parentTransform);
237 transform->setChanged();
238
239 context->transformSystem->updateTransformData(*transform);
240 } else {
241 noTransform = true;
242 }
243
244 SceneComponent* sceneComponent = entity->getComponent<SceneComponent>();
245 SceneComponent* parentSceneComponent = parent->getComponent<SceneComponent>();
246
247 if (sceneComponent && parentSceneComponent) {
248 parentSceneComponent->children.push_back(entity);
249 parentSceneComponent->setFieldChanged(&SceneComponent::children);
250
251 sceneComponent->parent = context->sceneSystem->getHandle(parentSceneComponent);
252 SceneSystem::updateState(*sceneComponent);
253 } else {
254 noScene = true;
255 }
256
257 if (noTransform && noScene) {
258 std::string pid = parent->getName().empty() ? std::to_string(parent->getId()) : parent->getName();
259 std::string cid = entity->getName().empty() ? std::to_string(entity->getId()) : entity->getName();
260 LOG_WARNING(logger, "addChild failed: Both parent and child must have Scene and Transform components: Parent:%s Child:%s.", pid.c_str(), cid.c_str());
261 }
262}
263
264void Cogs::Core::EntityStore::addChild(EntityId parent, EntityId child)
265{
266 addChild(getEntityPtr(parent), getEntity(child));
267}
268
270{
271 auto & creator = creators[typeId];
272
273 auto component = creator ? creator() : ComponentHandle::Empty();
274
275 auto * compPtr = component.resolve();
276 if (compPtr) {
277 entity->addComponent(component);
278 } else {
279 LOG_ERROR(logger, "Could not create component with type id %d.", typeId);
280 return nullptr;
281 }
282
283 return compPtr;
284}
285
287{
288 return addComponent(entity, TypeDatabase::getType(type).getTypeId());
289}
290
291void Cogs::Core::EntityStore::removeComponent(ComponentModel::Entity * entity, ComponentModel::ComponentHandle handle)
292{
293 auto component = handle.resolve();
294
295 if (!component) {
296 LOG_ERROR(logger, "Cannot remove empty component handle.");
297 return;
298 }
299
300 entity->removeComponent(handle);
301
302 auto & destroyer = destroyers[component->getTypeId()];
303
304 if (destroyer) destroyer(handle);
305}
306
308{
309 if (!parent) {
310 LOG_ERROR(logger, "Cannot remove child from null entity.");
311 return;
312 }
313
314 if (!entity) {
315 LOG_ERROR(logger, "Cannot remove null child from parent.");
316 return;
317 }
318
319 auto transform = entity->getComponent<TransformComponent>();
320
321 if (transform) {
323 transform->setChanged();
324 }
325
326 auto sceneComponent = parent->getComponent<SceneComponent>();
327
328 if (!sceneComponent) {
329 LOG_ERROR(logger, "Cannot remove child from parent without SceneComponent.");
330 return;
331 }
332
333 auto it = std::find_if(sceneComponent->children.begin(),
334 sceneComponent->children.end(),
335 [=](const EntityPtr & e) { return e.get() == entity; });
336
337 if (it != sceneComponent->children.end()) {
338 sceneComponent->children.erase(it);
339 }
340
341 sceneComponent->setChanged();
342}
343
345{
346 if (!entity) {
347 LOG_ERROR(logger, "Cannot remove children from null entity.");
348 return;
349 }
350
351 auto sceneComponent = entity->getComponent<SceneComponent>();
352
353 if (!sceneComponent) {
354 return;
355 }
356
357 // Break all transform relationships. Be defensive about references to parent entity.
358 for (auto & child : sceneComponent->children) {
359 auto childTransform = child->getComponent<TransformComponent>();
360
361 if (childTransform) {
363 childTransform->setChanged();
364 }
365
366 auto childSceneComponent = child->getComponent<SceneComponent>();
367
368 if (childSceneComponent) {
369 childSceneComponent->parent = {};
370 }
371 }
372
373 sceneComponent->children.clear();
374 sceneComponent->setChanged();
375}
376
378{
379 Entity* oldParent = context->store->getEntityParent(child);
380 if (oldParent != nullptr && parent == nullptr) {
381 EntityPtr childPtr = findEntity(child->getId(), oldParent);
382 assert(childPtr);
383 // Move to Root
384 removeChild(oldParent, child);
385 if (!entities.contains(child->getId())) {
386 entities[child->getId()] = childPtr;
387 storeNamedEntity(childPtr, child->getName());
388 }
389 }
390 else if (oldParent != nullptr && parent != nullptr) {
391 // Change parent
392 EntityPtr childPtr = findEntity(child->getId(), oldParent);
393 assert(childPtr);
394 removeChild(oldParent, child);
395 addChild(parent, childPtr);
396 }
397 else if (oldParent == nullptr && parent != nullptr) {
398 EntityPtr childPtr = getEntity(child->getId());
399 assert(childPtr);
400 destroyEntity(childPtr->getId());
401 addChild(parent, childPtr);
402 }
403
404 // old and new parent null - no change
405}
406
408{
409 auto entityIt = entities.find(id);
410
411 if (entityIt != entities.end()) {
412 auto entity = entityIt->second;
413
414 assert(entity->getId() == static_cast<size_t>(id) && "Registered id does not match internal entity id. Entity store corrupted.");
415
416 StringView name(entity->getName());
417
418 if (name.size()) {
419 entitiesByName.erase(Cogs::hash(name));
420 }
421
422 // NOTE: It is important that this owning reference is destroyed last.
423 entities.erase(id);
424 } else {
425 LOG_WARNING(logger, "Could not erase entity with id %zu. No such entity found in store.", size_t(id));
426 }
427}
428
429void Cogs::Core::EntityStore::destroyEntityComponents(Entity * entity)
430{
431 for (const ComponentHandle& c : entity->getComponents()) {
432 const Component* component = c.resolve();
433
434 assert(destroyers.contains(component->getTypeId()) && "No system registered to handle given type.");
435
436 destroyers[component->getTypeId()](c);
437 }
438}
439
440EntityId Cogs::Core::EntityStore::getNextEntityId()
441{
442 static EntityId entityId = 0;
443
444 entityId++;
445
446 return entityId;
447}
448
449Cogs::Core::EntityPtr Cogs::Core::EntityStore::getEntity(const EntityId entityId, bool logIfNotFound, bool onlyRegistered) const
450{
451 auto it = entities.find(entityId);
452 if (it != entities.end()) {
453 return it->second;
454 }
455
456 if (!onlyRegistered) {
457 for (const auto& [_, child] : entities) {
458 EntityPtr output = findEntity(entityId, child.get());
459 if (output) {
460 return output;
461 }
462 }
463 }
464
465 if (logIfNotFound) {
466 LOG_ERROR(logger, "getEntity - unknown Id: %zu", static_cast<size_t>(entityId));
467 }
468
469 return {};
470}
471
473{
474 auto it = entitiesByName.find(Cogs::hash(name));
475
476 if (it == std::end(entitiesByName)) {
477 if (logIfNotFound) {
478 LOG_WARNING(logger, "No entity named '%.*s' found.", StringViewFormat(name));
479 }
480 return EntityPtr{};
481 }
482
483 EntityPtr ptr = it->second.lock();
484 if (!ptr) {
485 LOG_ERROR(logger, "Internal Error: Entity erased without removing entry in 'entitiesByName'.");
486 }
487
488 // Ensure that name matches.
489 else if (StringView(ptr->getName()) != name) {
490 LOG_ERROR(logger, "getEntity: Entity with name: '%s' vs '%.*s' duplicate hash in store.", ptr->getName().c_str(), StringViewFormat(name));
491 return EntityPtr{};
492 }
493
494 return ptr;
495}
496
498{
499 if (root) {
500 const SceneComponent* sceneComponent = root->getComponent<SceneComponent>();
501
502 if (!sceneComponent) {
503 return EntityPtr{};
504 }
505
506 for (const EntityPtr& child : sceneComponent->children) {
508 if (name == child->getName()) {
509 return child;
510 }
511 }
512 else {
513 if (child->getName().find(std::string_view(name)) != std::string::npos) {
514 return child;
515 }
516 }
517
519 EntityPtr found = findEntity(name, child.get(), find);
520 if (found) {
521 return found;
522 }
523 }
524 }
525 }
526 else {
527 // Look for global entities. Do quick lookup.
528 EntityPtr entity = getEntity(name, false);
529 if (entity) {
530 // If non-recursive search entity must be a root entity.
532 if (getEntityParent(entity.get()) == nullptr) {
533 return entity;
534 }
535 }
536 else {
537 return entity;
538 }
539 }
540
541 for (const auto& [_, child] : entities) {
542
543 // Using only root entities if Non-recursive search.
544 if ((find & EntityFind::NonRecursive) != EntityFind::NonRecursive || !getEntityParent(child.get())) {
546 if (name == child->getName()) {
547 return child;
548 }
549 }
550 else {
551 if (child->getName().find(std::string_view(name)) != std::string::npos) {
552 return child;
553 }
554 }
555
557 EntityPtr found = findEntity(name, child.get(), find);
558
559 if (found) {
560 return found;
561 }
562 }
563 }
564 }
565 }
566
567 return EntityPtr{};
568}
569
571{
572 EntityPtr output;
573 const SceneComponent* sceneComponent = parent->getComponent<SceneComponent>();
574 if (sceneComponent) {
575 for (const EntityPtr& child : sceneComponent->children) {
576 if (entityId == static_cast<EntityId>(child->getId())) {
577 output = child;
578 break;
579 }
580
581 output = findEntity(entityId, child.get());
582 if (output) {
583 break;
584 }
585 }
586 }
587
588 return output;
589}
590
592{
593 auto transformComponent = entity->getComponent<TransformComponent>();
594
595 if (transformComponent) {
596 auto* parentTransform = transformComponent->parent.resolve();
597 if (parentTransform) {
598 auto parent = parentTransform->getContainer();
599 return parent;
600 }
601 }
602
603 return nullptr;
604}
605
607{
608 auto it = entities.find(entityPtr->getId());
609 if (it == entities.end()) {
610 // Not in global store, just rename the entity's name.
611 entityPtr->setName(name);
612 }
613 else {
614 if (!entityPtr->getName().empty()) {
615 const size_t oldHashCode = Cogs::hash(entityPtr->getName());
616
617 auto oldIt = entitiesByName.find(oldHashCode);
618 if (oldIt == entitiesByName.end()) {
619 LOG_WARNING(logger, "renameEntity: Failed old name lookup: '%s' in store.", entityPtr->getName().c_str());
620 }
621 else {
622 entitiesByName.erase(oldIt);
623 }
624 }
625
626 if (!name.empty()) {
627 storeNamedEntity(it->second, name);
628 }
629
630 entityPtr->setName(name);
631 }
632
633 context->deferredResolution->scheduleRescan();
634}
635
636
638{
639 std::string result;
640
641 for (auto& e : entities) {
642 result += dumpHierarchy(e.second.get());
643 }
644 return result;
645}
646
647std::string Cogs::Core::EntityStore::dumpHierarchy(const ComponentModel::Entity* parent, const std::string& prefix) const {
648 std::string newprefix = prefix + " ";
649 std::string result;
650 const ComponentCollectionBase& components = parent->getComponents();
651
652 result.reserve(4000);
653 result += prefix;
654 result += parent->getName().empty() ? "<unnamed entity>" : parent->getName().c_str();
655
656 if (components.size()) {
657 const char* sep = " [";
658
659 for (ComponentHandle c : components) {
660 const Reflection::Type& type = TypeDatabase::getType(c.typeId);
661
662 result += sep;
663 result += type.getName().getName();
664 sep = ", ";
665 }
666 result += "]";
667 }
668 result += "\n";
669
670 SceneComponent* sceneComponent = parent->getComponent<SceneComponent>();
671
672 if (sceneComponent) {
673 for (const EntityPtr& child : sceneComponent->children) {
674 result += dumpHierarchy(child.get(), newprefix);
675 }
676 }
677 return result;
678}
679
680
682{
683 if (entityId == NoEntity) {
684 return nullptr;
685 }
686
687 if (!entityPool.isValid(static_cast<Collections::ElementHandle>(entityId))) {
688 LOG_ERROR(logger, "getEntityPtr: EntityHandle out of range: %zd.", static_cast<size_t>(entityId));
689 return nullptr;
690 }
691
692 ComponentModel::Entity* entity = entityPool[static_cast<Collections::ElementHandle>(entityId)];
693
694 // Checks that entity pointed to not deleted or space reused by new entity.
695 return (entity && static_cast<EntityId>(entity->getId()) == entityId) ? entity : nullptr;
696}
697
698void Cogs::Core::EntityStore::addSystem(const TypeId typeId, ComponentCreator creator, ComponentDestroyer destroyer)
699{
700 creators[typeId] = creator;
701 destroyers[typeId] = destroyer;
702}
703
705{
706 const TypeId typeId = system->getComponentType();
707
708 if (typeId == Reflection::NoType) {
709 LOG_ERROR(logger, "Cannot add system using uninitialized type id (Reflection::NoType).");
710
711 return;
712 }
713
714 auto creator = [system]() -> ComponentHandle
715 {
716 return system->createComponent();
717 };
718
719 auto destroyer = [system](ComponentHandle c)
720 {
721 system->destroyComponent(c);
722 };
723
724 systems[typeId] = system;
725 addSystem(typeId, creator, destroyer);
726}
727
729{
730 auto entity = createEntity(name, type, false);
731
732 addChild(parent, entity);
733
734 return entity;
735}
736
737void Cogs::Core::EntityStore::getEntitiesWithComponent(std::vector<EntityId>& entities, Reflection::TypeId componentTypeId)
738{
739 entities.clear();
740 if (auto it = systems.find(componentTypeId); it != systems.end()) {
741 it->second->addEntitiesWithComponent(entities, componentTypeId);
742 }
743}
744
745void Cogs::Core::EntityStore::storeNamedEntity(const EntityPtr& entity, StringView name)
746{
747 const size_t hashCode = Cogs::hash(name);
748
749 const auto it = entitiesByName.find(hashCode);
750 if (it != entitiesByName.end()) {
751 const EntityPtr oldEntityPtr = it->second.lock();
752 if (!oldEntityPtr) {
753 LOG_ERROR(logger, "Expired Entity with name: '%.*s' in store. Replaced.", StringViewFormat(name));
754 entitiesByName[hashCode] = entity;
755 }
756 else if (name == oldEntityPtr->getName())
757 LOG_WARNING_ONCE(logger, "Entity with name: '%.*s' already exists in store.", StringViewFormat(name));
758 else
759 LOG_ERROR(logger, "Entity with name: '%s' vs '%.*s' duplicate hash in store.", oldEntityPtr->getName().c_str(), StringViewFormat(name));
760 }
761 else {
762 entitiesByName[hashCode] = entity;
763 }
764}
A collection of components, held by component handles.
size_t size() const
Get the size of the collection.
Base class for Component instances.
Definition: Component.h:143
void setChanged()
Sets the component to the ComponentFlags::Changed state with carry.
Definition: Component.h:202
ComponentType * getComponent() const
Definition: Component.h:159
constexpr Reflection::TypeId getTypeId() const
Get the Reflection::TypeId of the component.
Definition: Component.h:380
Container for components, providing composition of dynamic entities.
Definition: Entity.h:18
void removeComponent(ComponentHandle component)
Definition: Entity.cpp:29
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
constexpr void setId(const size_t id) noexcept
Definition: Entity.h:117
void getComponents(ComponentCollection< T > &collection) const
Get all the components implementing the templated type.
Definition: Entity.h:52
const std::string & getName() const noexcept
Get the name of this entity.
Definition: Entity.h:120
constexpr void * getUserData() const noexcept
Get user data.
Definition: Entity.h:137
constexpr void setUserData(void *userData) noexcept
Definition: Entity.h:131
void addComponent(ComponentHandle component)
Definition: Entity.cpp:18
void setName(const StringView &name)
Definition: Entity.cpp:98
Base class for component systems.
virtual ComponentHandle createComponent()
Create a new component instance.
Reflection::TypeId getComponentType() const
Get the reflected type of the components managed by this system.
virtual void destroyComponent(ComponentHandle)
Destroy the component held by the given handle.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
EntityPtr getEntity(const StringView &name, bool logIfNotFound=true) const
Retrieve a reference to the shared entity pointer to the Entity with the given name.
EntityStore(Context *context)
Construct the store with the given context instance.
Definition: EntityStore.cpp:30
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.
void getEntityDefinitionComponents(std::vector< StringView > &components, const StringView &name) const
Get components of a known entity definition.
Definition: EntityStore.cpp:80
std::string dumpHierarchy() const
Generates a debug dump of the entire entity hierarchy.
void clear()
Clear out all top level entities owned by the store.
Definition: EntityStore.cpp:45
void addSystem(const Reflection::TypeId typeId, ComponentCreator creator, ComponentDestroyer destroyer)
Adds the given creator and destroyer functions for handling components of the given typeId.
void removeChildren(ComponentModel::Entity *entity)
Removes all children from 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 createChildEntity(const StringView &type, ComponentModel::Entity *parent, const StringView &name=StringView())
Create a new Entity, parenting it to the given parent.
EntityPtr createEntity(const StringView &name, const StringView &type, bool storeOwnership=true)
Create a new Entity.
void addEntityDefinition(const EntityDefinition &definition)
Add the given entity definition to the store.
Definition: EntityStore.cpp:59
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.
void getEntityDefinitions(std::vector< StringView > &names) const
Get names of currently known entity definitions.
Definition: EntityStore.cpp:71
void createEntities(size_t count, std::vector< EntityPtr > &entities)
Allocates and initializes a collection of empty entities.
Contains information on how the entity behaves in the scene.
std::vector< EntityPtr > children
Contains all child entities owned by this component.
ComponentModel::ComponentHandle parent
Handle to the scene component of the parent entity.
Defines a 4x4 transformation matrix for the entity and a global offset for root entities.
ComponentModel::ComponentHandle parent
Parent transform of the component.
Log implementation class.
Definition: LogManager.h:139
static const Type & getType()
Get the Type of the given template argument.
Definition: TypeDatabase.h:168
Represents a discrete type definition, describing a native type class.
Definition: Type.h:89
constexpr const Name & getName() const
Get the unique name of the type.
Definition: Type.h:198
constexpr bool isValid() const
Gets if the type is considered a valid, registered type.
Definition: Type.h:328
constexpr TypeId getTypeId() const
Get the unique Reflection::TypeId of this instance.
Definition: Type.h:325
Provides a weakly referenced view over the contents of a string.
Definition: StringView.h:24
constexpr size_t size() const noexcept
Get the size of the string.
Definition: StringView.h:178
constexpr bool empty() const noexcept
Check if the string is empty.
Definition: StringView.h:122
uint32_t ElementHandle
Handle type for elements.
Definition: PoolBase.h:16
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
Definition: EntityPtr.h:12
void applyFieldValues(class Context *context, std::span< FieldValue > entityDefinition, ComponentModel::Entity *entity)
Apply defaults from the given entityDefinition to the given entity.
void COGSCORE_DLL_API createDefaultEntityDefinitions(class EntityStore *entityStore)
Create the default entity definitions supported by Cogs.
EntityFind
Options to findEntity/getEntityFull.
Definition: EntityStore.h:34
@ NonRecursive
Do not search recursively.
@ PartialNameMatch
Search for the first entity that partially contains the specified name.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
Definition: LogManager.h:180
Contains reflection support.
Definition: Component.h:11
uint16_t TypeId
Built in type used to uniquely identify a single type instance.
Definition: Name.h:48
constexpr TypeId NoType
Definition of no type.
Definition: Name.h:51
constexpr size_t hash() noexcept
Simple getter function that returns the initial value for fnv1a hashing.
Definition: HashFunctions.h:62
Handle to a Component instance.
Definition: Component.h:67
COGSFOUNDATION_API class Component * resolve() const
Resolve the handle, returning a pointer to the held Component instance.
Definition: Component.cpp:65
static ComponentHandle Empty()
Returns an empty, invalid handle. Will evaluate to false if tested against using operator bool().
Definition: Component.h:119
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...
const std::string & getName() const
Get the string name. This can be empty, even in valid instances of Name.
Definition: Name.h:112