1#include "EntityCreator.h"
3#include "Foundation/Logging/Logger.h"
5#include "EntityStore.h"
7#include "Systems/Core/TransformSystem.h"
8#include "Systems/Core/PropertiesSystem.h"
9#include "Systems/Core/AssetSystem.h"
11#include "Components/Core/RenderComponent.h"
13#include "Resources/AssetManager.h"
22 LOG_ERROR(logger,
"Could not find entity name:'%.*s'.", StringViewFormat(name));
25 LOG_ERROR(logger,
"Could not create entity type:'%.*s'.", StringViewFormat(type));
30Cogs::Core::EntityPtr Cogs::Core::createEntity(EntityCreationContext & entityContext,
const SceneEntityDefinition & definition)
32 auto context = entityContext.context;
33 auto & scene = *entityContext.scene;
35 if (definition.isSequence())
return nullptr;
37 const auto name = scene.properties.getString(definition.nameIndex);
40 if (definition.isModel()) {
41 type = entityContext.skipModel ?
"Group" :
"Model";
43 else if (definition.isAsset()) {
46 else if (definition.isModel() || definition.isLodGroup()) {
49 type = Strings::get(definition.type);
52 const bool lookupExisting = !name.
empty() && name[0] ==
'$';
57 entity = context->store->findEntity(name.
substr(1));
59 switch (entityContext.parentMode) {
60 case EntityParentMode::None:
61 entity = context->store->createEntity(name, type);
63 case EntityParentMode::Default:
64 entity = context->store->createChildEntity(type, entityContext.parent, name);
66 case EntityParentMode::TransformOnly:
67 entity = context->store->createEntity(name, type,
false);
70 auto parentTransform = entityContext.parent->getComponentHandle<TransformComponent>();
72 auto transform = entity->getComponent<TransformComponent>();
75 transform->parent = parentTransform;
86 logFail(lookupExisting, type, name);
90 if (definition.objectId < ~0u) {
91 auto renderComponent = entity->getComponent<RenderComponent>();
93 if (renderComponent) {
94 renderComponent->objectId = definition.objectId;
96 LOG_ERROR(logger,
"objectId property set but no target RenderComponent defined.");
100 if (definition.numFields) {
101 std::span<FieldValue> fields = std::span(scene.fieldValues).subspan(definition.firstField, definition.numFields);
105 if (definition.numProperties > 0) {
106 auto propertiesComponent = entity->getComponent<PropertiesComponent>();
108 if (!propertiesComponent) {
109 propertiesComponent = context->store->addComponent<PropertiesComponent>(entity.get());
112 propertiesComponent->properties.copyProperties(scene.properties, definition.firstProperty, definition.numProperties);
115 if (definition.isParentedByName()) {
116 auto parentName = scene.properties.getString(definition.parentIndex);
118 auto p = context->store->findEntity(parentName.substr(1));
119 context->store->addChild(p.get(), entity);
122 if (definition.isAsset()) {
123 auto path = scene.properties.getString(definition.asset.index);
125 auto assetComponent = entity->getComponent<AssetComponent>();
127 if (!assetComponent) {
128 assetComponent = context->store->addComponent<AssetComponent>(entity.get());
131 assetComponent->asset = context->assetManager->loadAsset(path, NoResourceId, AssetLoadFlags::None);
132 assetComponent->flags = (
AssetFlags)definition.asset.flags;
140 if (definition.isSequence()) {
144 const StringView name = scene.properties.getString(definition.nameIndex);
146 if (definition.isAsset()) {
149 else if (definition.isModel() || definition.isLodGroup()) {
152 type = Strings::get(definition.type);
155 const bool lookupExisting = !name.empty() && name[0] ==
'$';
157 if (lookupExisting) {
158 entity = context->store->findEntity(name.substr(1));
161 entity = context->store->createChildEntity(type, parent, name);
163 entity = context->store->createEntity(name, type);
167 logFail(lookupExisting, type, name);
171 if (definition.objectId < ~0u) {
172 auto renderComponent = entity->getComponent<RenderComponent>();
174 if (renderComponent) {
175 renderComponent->objectId = definition.objectId;
177 LOG_ERROR(logger,
"objectId property set but no target RenderComponent defined.");
181 if (definition.numFields) {
182 auto fields = std::span(scene.fieldValues).subspan(definition.firstField, definition.numFields);
186 if (definition.numProperties > 0) {
187 auto propertiesComponent = entity->getComponent<PropertiesComponent>();
189 if (!propertiesComponent) {
190 propertiesComponent = context->store->addComponent<PropertiesComponent>(entity.get());
193 propertiesComponent->properties.copyProperties(scene.properties, definition.firstProperty, definition.numProperties);
196 if (definition.isParentedByName()) {
197 auto parentName = scene.properties.getString(definition.parentIndex);
199 auto p = context->store->findEntity(parentName.substr(1));
200 context->store->addChild(p.get(), entity);
203 if (definition.isAsset()) {
204 auto path = scene.properties.getString(definition.asset.index);
206 auto assetComponent = entity->getComponent<AssetComponent>();
208 if (!assetComponent) {
209 assetComponent = context->store->addComponent<AssetComponent>(entity.get());
212 assetComponent->asset = context->assetManager->loadAsset(path, NoResourceId, AssetLoadFlags::None);
213 assetComponent->flags = (
AssetFlags)definition.asset.flags;
Container for components, providing composition of dynamic entities.
Log implementation class.
Provides a weakly referenced view over the contents of a string.
constexpr bool empty() const noexcept
Check if the string is empty.
constexpr StringView substr(size_t offset, size_t count=NoPosition) const noexcept
Get the given sub string.
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
void applyFieldValues(class Context *context, std::span< FieldValue > entityDefinition, ComponentModel::Entity *entity)
Apply defaults from the given entityDefinition to the given entity.
AssetFlags
Controls asset system's model instance behaviour.
constexpr Log getLogger(const char(&name)[LEN]) noexcept