1#include "FieldFunctions.h"
5#include "EntityStore.h"
7#include "FieldSetter.h"
11#include "Resources/ResourceBase.h"
13#include "Foundation/ComponentModel/Component.h"
14#include "Foundation/Logging/Logger.h"
18#include <glm/vec2.hpp>
19#include <glm/vec3.hpp>
20#include <glm/vec4.hpp>
21#include <glm/mat4x4.hpp>
22#include <glm/ext/quaternion_float.hpp>
23#include <glm/ext/quaternion_double.hpp>
31 size_t scanEncodedLength(
const char* value) {
36 if (*value == 0)
break;
39 else if (*value ==
'|') {
53 size_t scanEncodedVectorLength(
const char* value) {
58 if (*value == 0)
break;
60 else if (*value ==
'|') {
71 std::vector<std::string> decodeMultiString(
const char* value)
73 std::vector<std::string> strings;
74 strings.reserve(scanEncodedVectorLength(value));
77 str.reserve(scanEncodedLength(value));
81 str.push_back(*value);
83 assert(
false &&
"Invalid EncodedMultiStringField encoding");
87 else if (*value ==
'|') {
88 strings.emplace_back(str);
90 str.reserve(scanEncodedLength(value + 1));
93 str.push_back(*value);
103 std::string encodeMultiString(
const std::vector<std::string>& value)
107 for (
const auto& str : value) {
108 estimate += str.length() + 1;
110 output.reserve(estimate);
112 for (
const std::string& s : value) {
113 for (
const char c : s) {
114 if (c ==
'\\' || c ==
'|') output.push_back(
'\\');
119 output.push_back(
'|');
125 template<
typename Collection>
126 int getMultiValue(
const void* field,
void* value,
int size)
128 auto collection =
static_cast<const Collection*
>(field);
130 if (value && collection->size()) {
131 std::memcpy(value, collection->data(), size * collection->size());
134 return static_cast<int>(collection->size());
140void setEntityField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId, EntityId targetId)
153 Cogs::setField(context, entityId, componentId, fieldId, targetPtr);
155 Cogs::setField(context, entityId, componentId, fieldId,
WeakEntityPtr(targetPtr));
158 LOG_ERROR(logger,
"setEntityField: Type match error for field '%s' in component '%s'.", field->
getName().
c_str(), componentType.
getName().
c_str());
162EntityId getEntityField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId)
173 const EntityPtr* fieldPtr = Cogs::getField<EntityPtr>(context, entityId, componentId, fieldId);
174 return (*fieldPtr) ? (*fieldPtr)->getId() : NoEntity;
177 const EntityPtr fieldPtr = Cogs::getField<WeakEntityPtr>(context, entityId, componentId, fieldId)->lock();
178 return fieldPtr ? fieldPtr->getId() : NoEntity;
181 LOG_ERROR(logger,
"getEntityField: Type match error for field '%s' in component '%s'.", field->
getName().
c_str(), componentType.
getName().
c_str());
186void setMultiEntityField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const EntityId * targetIds,
int count)
188 auto context =
static_cast<Context *
>(ctx);
190 std::vector<WeakEntityPtr> entities;
192 for (
int i = 0; i < count; ++i) {
196 Cogs::setField(context, entityId, componentId, fieldId, std::move(entities));
199void setFloatField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float value)
201 auto context =
static_cast<Context *
>(ctx);
203 Cogs::setField(context, entityId, componentId, fieldId, value);
206void setDoubleField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double value)
208 auto context =
static_cast<Context *
>(ctx);
210 Cogs::setField(context, entityId, componentId, fieldId, value);
213void setIntegerField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const int value)
215 auto context =
static_cast<Context *
>(ctx);
217 Cogs::setField(context, entityId, componentId, fieldId, value);
220void setUIntegerField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const uint32_t value)
222 auto context =
static_cast<Context *
>(ctx);
224 Cogs::setField(context, entityId, componentId, fieldId, value);
227void setInt64Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const int64_t value)
229 auto context =
static_cast<Context *
>(ctx);
231 Cogs::setField(context, entityId, componentId, fieldId, value);
234void setUInt64Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const uint64_t value)
236 auto context =
static_cast<Context *
>(ctx);
238 Cogs::setField(context, entityId, componentId, fieldId, value);
242void setBoolField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const CogsBool value)
244 auto context =
static_cast<Context *
>(ctx);
246 Cogs::setField(context, entityId, componentId, fieldId, value != 0);
249int getBoolField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId)
251 auto context =
static_cast<Context*
>(ctx);
252 auto fieldPtr = Cogs::getField<bool>(context, entityId, componentId, fieldId);
253 return *fieldPtr ? 1 : 0;
256void setVector2Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * value)
258 auto context =
static_cast<Context *
>(ctx);
260 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::vec2 *
>(value));
263void setVector3Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * value)
265 auto context =
static_cast<Context *
>(ctx);
267 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::vec3 *
>(value));
270void setVector4Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * value)
272 auto context =
static_cast<Context *
>(ctx);
274 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::vec4 *
>(value));
278void setVector2iField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const int32_t * value)
280 auto context =
static_cast<Context *
>(ctx);
282 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::ivec2 *
>(value));
285void setVector3iField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const int32_t * value)
287 auto context =
static_cast<Context *
>(ctx);
289 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::ivec3 *
>(value));
292void setVector4iField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const int32_t * value)
294 auto context =
static_cast<Context *
>(ctx);
296 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::ivec4 *
>(value));
299void setVector2uField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const uint32_t * value)
301 auto context =
static_cast<Context *
>(ctx);
303 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::uvec2 *
>(value));
306void setVector3uField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const uint32_t * value)
308 auto context =
static_cast<Context *
>(ctx);
310 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::uvec3 *
>(value));
313void setVector4uField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const uint32_t * value)
315 auto context =
static_cast<Context *
>(ctx);
317 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::uvec4 *
>(value));
322void setVector2dField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * value)
324 auto context =
static_cast<Context *
>(ctx);
326 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::dvec2 *
>(value));
329void setVector3dField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * value)
331 auto context =
static_cast<Context *
>(ctx);
333 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::dvec3 *
>(value));
336void setVector4dField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * value)
338 auto context =
static_cast<Context *
>(ctx);
340 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::dvec4 *
>(value));
343void setQuaternionField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * value)
345 auto context =
static_cast<Context *
>(ctx);
347 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::quat *
>(value));
350void setQuaterniondField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * value)
352 auto context =
static_cast<Context *
>(ctx);
354 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::dquat *
>(value));
357void setMatrixField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * value)
359 auto context =
static_cast<Context *
>(ctx);
361 Cogs::setField(context, entityId, componentId, fieldId, *
reinterpret_cast<const glm::mat4 *
>(value));
364void setMultiMatrixField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float* values,
const int count)
368 Cogs::assignField(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::mat4*
>(values), count);
371void setMultiFloatField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * values,
const int count)
373 auto context =
static_cast<Context *
>(ctx);
378void setMultiFloatFieldSubset(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * values,
const int offset,
const int count)
380 auto context =
static_cast<Context *
>(ctx);
382 Cogs::assignFieldSubset(context, entityId, componentId, fieldId, values, offset, count);
385void setMultiDoubleField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * values,
const int count)
387 auto context =
static_cast<Context *
>(ctx);
392void setMultiIntegerField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const int * values,
const int count)
394 auto context =
static_cast<Context *
>(ctx);
399void setMultiUInt64Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const uint64_t * values,
const int count)
401 auto context =
static_cast<Context *
>(ctx);
406void setMultiUInt64FieldSubset(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const uint64_t * values,
const int offset,
const int count)
408 auto context =
static_cast<Context *
>(ctx);
410 Cogs::assignFieldSubset(context, entityId, componentId, fieldId, values, offset, count);
413void setMultiVector2Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * values,
const int count)
415 auto context =
static_cast<Context *
>(ctx);
417 Cogs::assignField(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::vec2 *
>(values), count);
420void setMultiVector3Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * values,
const int count)
422 auto context =
static_cast<Context *
>(ctx);
424 Cogs::assignField(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::vec3 *
>(values), count);
427void setMultiVector3FieldSubset(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * values,
const int offset,
const int count)
429 auto context =
static_cast<Context *
>(ctx);
431 Cogs::assignFieldSubset(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::vec3 *
>(values), offset, count);
434void setMultiVector4Field(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * values,
const int count)
436 auto context =
static_cast<Context *
>(ctx);
438 Cogs::assignField(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::vec4 *
>(values), count);
441void setMultiVector4FieldSubset(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const float * values,
const int offset,
const int count)
443 auto context =
static_cast<Context *
>(ctx);
445 Cogs::assignFieldSubset(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::vec4 *
>(values), offset, count);
448void setMultiVector2dField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * values,
const int count)
450 auto context =
static_cast<Context *
>(ctx);
452 Cogs::assignField(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::dvec2 *
>(values), count);
455void setMultiVector3dField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * values,
const int count)
457 auto context =
static_cast<Context *
>(ctx);
459 Cogs::assignField(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::dvec3 *
>(values), count);
462void setMultiVector4dField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const double * values,
const int count)
464 auto context =
static_cast<Context *
>(ctx);
466 Cogs::assignField(context, entityId, componentId, fieldId,
reinterpret_cast<const glm::dvec4 *
>(values), count);
469void setStringField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const char * value)
471 auto context =
static_cast<Context *
>(ctx);
473 Cogs::setField(context, entityId, componentId, fieldId, std::string(value));
476void setMultiStringField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const char ** value,
const int count)
478 auto context =
static_cast<Context *
>(ctx);
480 std::vector<std::string> strings(count);
482 for (
int i = 0; i < count; ++i) {
483 strings[i] = std::string(value[i]);
486 Cogs::setField(context, entityId, componentId, fieldId, std::move(strings));
489void getFieldValue(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
void * value,
int typeSize)
491 auto context =
static_cast<Context *
>(ctx);
493 auto fieldPtr = Cogs::getField<uint8_t>(context, entityId, componentId, fieldId);
496 auto field = componentType.
getField(fieldId);
497 if (fieldPtr ==
nullptr) {
498 LOG_ERROR(logger,
"getFieldValue: Invalid field '%d' in component '%s'.", fieldId, componentType.
getName().
c_str());
505 if (Cogs::Reflection::TypeDatabase::getType<bool>() == fieldType)
506 assert((typeSize == 1 || typeSize == 4) &&
"Field size mismatch");
508 assert(
static_cast<int>(fieldType.getSize()) == typeSize &&
"Field size mismatch");
510 std::memset(value, 0, typeSize);
511 std::memcpy(value, fieldPtr, typeSize);
514const char * getStringFieldValue(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId)
516 auto context =
static_cast<Context *
>(ctx);
517 auto fieldPtr = Cogs::getField<std::string>(context, entityId, componentId, fieldId);
519 return fieldPtr->c_str();
522void getVector3FieldValue(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
float * value)
524 auto context =
static_cast<Context *
>(ctx);
526 auto fieldPtr = Cogs::getField<glm::vec3>(context, entityId, componentId, fieldId);
528 *
reinterpret_cast<glm::vec3 *
>(value) = *fieldPtr;
539void setEncodedMultiStringField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
const char* value)
541 auto context =
static_cast<Context*
>(ctx);
543 std::vector<std::string> strings = ::decodeMultiString(value);
544 Cogs::setField(context, entityId, componentId, fieldId, std::move(strings));
547const char* getEncodedMultiStringFieldValue(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId)
549 auto context =
static_cast<Context*
>(ctx);
551 const auto fieldPtr = Cogs::getField<std::vector<std::string>>(context, entityId, componentId, fieldId);
553 static std::string output;
554 output = ::encodeMultiString(*fieldPtr);
555 return output.c_str();
560int getEncodedMultiStringField(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
char* value,
int size)
562 auto context =
static_cast<Context*
>(ctx);
564 const auto fieldPtr = Cogs::getField<std::vector<std::string>>(context, entityId, componentId, fieldId);
566 std::string output = ::encodeMultiString(*fieldPtr);
568 int actualLength =
static_cast<int>(output.size());
569 int toCopy = std::min(actualLength + 1, size);
570 std::memcpy(value, output.data(),
static_cast<size_t>(toCopy));
574int getMultiFieldValue(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId,
void * value,
int size)
576 auto context =
static_cast<Context *
>(ctx);
588 auto field = componentType.
getField(fieldId);
593 assert(component !=
nullptr &&
"Null component - Not added to entity?");
594 auto fieldPtr = field->
getPtr<
void *>(component);
597 return getMultiValue<std::vector<int32_t>>(fieldPtr, value, size);
599 return getMultiValue<std::vector<uint32_t>>(fieldPtr, value, size);
601 return getMultiValue<std::vector<float>>(fieldPtr, value, size);
603 return getMultiValue<std::vector<glm::vec2>>(fieldPtr, value, size);
605 return getMultiValue<std::vector<glm::vec3>>(fieldPtr, value, size);
607 return getMultiValue<std::vector<glm::vec4>>(fieldPtr, value, size);
609 return getMultiValue<std::vector<glm::quat>>(fieldPtr, value, size);
611 LOG_ERROR(logger,
"getMultiFieldValue: Unsupported. Field: '%s' Type: '%s'", field->
getName().
c_str(), type.getName().c_str());
617ResourceId getResourceFieldValue(BridgeContext* ctx, EntityId entityId,
const ComponentId componentId,
const FieldId fieldId)
619 auto context =
static_cast<Context *
>(ctx);
621 const auto fieldPtr = Cogs::getField<ResourceHandleBase>(context, entityId, componentId, fieldId);
623 auto id = fieldPtr->getId();
624 auto resource = fieldPtr->get();
626 if (
id == NoResourceId && resource !=
nullptr) {
627 auto manager = resource->getOwner();
628 id = manager->getNextResourceId();
629 manager->setResourceId(resource,
id);
Base class for Component instances.
A Context instance contains all the services, systems and runtime components needed to use Cogs.
class EntityStore * store
Entity store.
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::Entity * getEntityPtr(const EntityId entityId)
Get a raw pointer to the entity with the given id.
Log implementation class.
Field definition describing a single data member of a data structure.
const Name & getName() const
Get the name of the field.
TypeId getTypeId() const
Get the type id of the field.
FieldValueType * getPtr(void *container) const
Get a pointer to this field on the given container.
static const Type & getType()
Get the Type of the given template argument.
Represents a discrete type definition, describing a native type class.
constexpr const Name & getName() const
Get the unique name of the type.
const Field * getField(const Name &name) const
Get a pointer to the field info of the field with the given name.
constexpr TypeId getTypeId() const
Get the unique Reflection::TypeId of this instance.
Contains code for composing and managing entities built from components.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
std::shared_ptr< ComponentModel::Entity > EntityPtr
Smart pointer for Entity access.
std::weak_ptr< ComponentModel::Entity > WeakEntityPtr
Weak Smart pointer for Entity access.
constexpr Log getLogger(const char(&name)[LEN]) noexcept
constexpr FieldId NoField
No field id.
void assignField(Cogs::Core::Context *context, EntityId entityId, const ComponentId componentId, const Cogs::Reflection::FieldId fieldId, const DataType *data, int count)
Assign value to a Component field.
const char * c_str() const
Gets the name as a null-terminated string.