1#include "PropertiesManager.h"
3Cogs::Core::PropertyStore::PropertyStore(MemBlockType memType)
10Cogs::Core::PropertyStore::PropertyStore(
const PropertyStore & other)
12 headers.copy(other.headers);
13 data.copy(other.data);
14 dataSize = other.dataSize;
17Cogs::Core::PropertyStore::PropertyStore(PropertyStore&& other)
noexcept
19 headers = std::move(other.headers);
20 data = std::move(other.data);
21 dataSize = other.dataSize;
26 headers.copy(other.headers);
27 data.copy(other.data);
28 dataSize = other.dataSize;
34 headers = std::move(other.headers);
35 data = std::move(other.data);
36 dataSize = other.dataSize;
40uint32_t Cogs::Core::PropertyStore::addProperty(StringView key,
bool value)
42 auto & p = addProperty(key, PropertyType::Bool);
47uint32_t Cogs::Core::PropertyStore::addProperty(StringView key,
float value)
49 auto & p = addProperty(key, PropertyType::Float);
54uint32_t Cogs::Core::PropertyStore::addProperty(StringView key,
double value)
56 auto& p = addProperty(key, PropertyType::Double);
57 p.doubleValue = value;
61uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, int32_t value)
63 auto & p = addProperty(key, PropertyType::Integer);
68uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, uint32_t value)
70 auto& p = addProperty(key, PropertyType::UnsignedInteger);
75uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, std::span<const float> values)
77 size_t n = values.size();
79 PropertyInfo& p = addProperty(key, PropertyType::FloatArray);
86 PropertyInfo& p = addProperty(key, PropertyType::Float);
87 p.floatValue = values[0];
92 PropertyInfo& p = addProperty(key, PropertyType::Float2);
93 p.float2Value[0] = values[0];
94 p.float2Value[1] = values[1];
98 PropertyInfo& p = addProperty(key, PropertyType::FloatArray);
99 addPropertyData(p, values.data(), values.size_bytes());
103uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, std::span<const double> values)
105 size_t n = values.size();
107 PropertyInfo& p = addProperty(key, PropertyType::DoubleArray);
114 PropertyInfo& p = addProperty(key, PropertyType::Double);
115 p.doubleValue = values[0];
119 PropertyInfo& p = addProperty(key, PropertyType::DoubleArray);
120 addPropertyData(p, values.data(), values.size_bytes());
124uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, std::span<const int32_t> values)
126 size_t n = values.size();
128 PropertyInfo& p = addProperty(key, PropertyType::IntArray);
135 PropertyInfo& p = addProperty(key, PropertyType::Integer);
136 p.intValue = values[0];
141 PropertyInfo& p = addProperty(key, PropertyType::Int2);
142 p.int2Value[0] = values[0];
143 p.int2Value[1] = values[1];
147 PropertyInfo& p = addProperty(key, PropertyType::IntArray);
148 addPropertyData(p, values.data(), values.size_bytes());
152uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, std::span<const uint32_t> values)
154 size_t n = values.size();
156 PropertyInfo& p = addProperty(key, PropertyType::UIntArray);
163 PropertyInfo& p = addProperty(key, PropertyType::UnsignedInteger);
164 p.uintValue = values[0];
169 PropertyInfo& p = addProperty(key, PropertyType::UInt2);
170 p.uint2Value[0] = values[0];
171 p.uint2Value[1] = values[1];
175 PropertyInfo& p = addProperty(key, PropertyType::UIntArray);
176 addPropertyData(p, values.data(), values.size_bytes());
180uint32_t Cogs::Core::PropertyStore::addProperty(StringView key,
const glm::vec3& values)
182 return addProperty(key, std::span(&values[0], 3));
185bool Cogs::Core::PropertyStore::getProperty(StringView key,
bool defaultValue)
187 auto & p = getProperty(key);
189 if (p.type == PropertyType::Bool)
return p.boolValue;
194float Cogs::Core::PropertyStore::getProperty(StringView key,
float defaultValue)
196 auto & p = getProperty(key);
198 if (p.type == PropertyType::Float)
return p.floatValue;
199 else if (p.type == PropertyType::Integer)
return (
float)p.intValue;
204int Cogs::Core::PropertyStore::getProperty(StringView key,
int defaultValue)
206 auto & p = getProperty(key);
208 if (p.type == PropertyType::Integer)
return p.intValue;
209 else if (p.type == PropertyType::Float)
return static_cast<int>(p.floatValue);
214uint32_t Cogs::Core::PropertyStore::getProperty(StringView key, uint32_t defaultValue)
216 const PropertyInfo& p = getProperty(key);
217 if (p.type == PropertyType::UnsignedInteger)
return p.uintValue;
218 else if (p.type == PropertyType::Integer && 0 <= p.intValue)
return p.intValue;
219 else if (p.type == PropertyType::Float && 0.f <= p.floatValue)
return static_cast<int>(p.floatValue);
223uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, StringRef value)
225 PropertyInfo& p = addProperty(key, PropertyType::StringRef);
226 p.stringRefValue = value;
230uint32_t Cogs::Core::PropertyStore::addProperty(StringView key, StringView value)
232 auto & p = addProperty(key, PropertyType::String);
234 if (!value.empty()) {
236 addPropertyData(p, value.data(), value.size() + 1);
238 getPropertyData(p)[value.size()] = 0;
247Cogs::StringView Cogs::Core::PropertyStore::getProperty(StringView key, StringView defaultValue)
249 PropertyInfo& p = getProperty(key);
250 return p.type != PropertyType::Unknown ? getString(p) : defaultValue;
253std::span<const float> Cogs::Core::PropertyStore::getProperty(StringView key, std::span<const float> defaultValue)
255 PropertyInfo& p = getProperty(key);
257 case PropertyType::Float:
258 case PropertyType::Float2:
259 case PropertyType::FloatArray:
260 return getFloatArray(p.index);
266glm::vec3 Cogs::Core::PropertyStore::getProperty(StringView key, glm::vec3 defaultValue)
268 auto& p = getProperty(key);
270 if (p.type == PropertyType::FloatArray) {
271 const auto array = getFloatArray(p.index);
272 if (array.size() == 3 || array.size() == 4) {
274 return glm::vec3(array[0], array[1], array[2]);
283 return getProperty(Strings::add(key));
288 static PropertyInfo unknown = {};
290 for (
auto & p : headers) {
301 return headers[index];
306 return headers[index];
309uint32_t Cogs::Core::PropertyStore::findProperty(StringView key)
const
311 return findProperty(0, size(), Strings::add(key));
314uint32_t Cogs::Core::PropertyStore::findProperty(uint32_t first, uint32_t count, StringRef key)
const
316 uint32_t last = first + count;
317 for (uint32_t i = first; i < last; ++i) {
318 auto & p = headers[i];
319 if (p.key == key)
return i;
325Cogs::StringView Cogs::Core::PropertyStore::getKey(
const PropertyInfo & p)
const
327 return Strings::get(headers[p.index].key);
330Cogs::StringView Cogs::Core::PropertyStore::getString(
const PropertyInfo & p)
const
332 if (p.type == PropertyType::StringRef) {
333 return Strings::get(p.stringRefValue);
336 if (p.type == PropertyType::String) {
338 return StringView{
static_cast<const char *
>(data.data()) + p.data.offset, p.data.size - 1 };
351 return getString(getPropertyByIndex(index));
354std::span<float> Cogs::Core::PropertyStore::getFloatArray(uint32_t index)
356 PropertyInfo& p = getPropertyByIndex(index);
357 if (p.type == PropertyType::Float) {
358 return std::span(&p.floatValue, &p.floatValue + 1);
360 if (p.type == PropertyType::Float2) {
361 return std::span(p.float2Value);
363 if (p.type == PropertyType::FloatArray) {
364 void* data = getPropertyData(p);
365 size_t size = p.data.size /
sizeof(float);
366 return std::span(
static_cast<float*
>(data), size);
371std::span<const float> Cogs::Core::PropertyStore::getFloatArray(uint32_t index)
const
374 return getFloatArray(getPropertyByIndex(index));
379std::span<const double> Cogs::Core::PropertyStore::getDoubleArray(
const PropertyInfo& p)
const
381 if (p.type == PropertyType::Double) {
382 return std::span(&p.doubleValue, &p.doubleValue + 1);
384 if (p.type == PropertyType::DoubleArray) {
385 const void* data = getPropertyData(p);
386 size_t size = p.data.size /
sizeof(double);
387 return std::span(
static_cast<const double*
>(data), size);
392std::span<const double> Cogs::Core::PropertyStore::getDoubleArray(uint32_t index)
const
395 return getDoubleArray(getPropertyByIndex(index));
400std::span<const float> Cogs::Core::PropertyStore::getFloatArray(
const PropertyInfo& p)
const
402 if (p.type == PropertyType::Float) {
403 return std::span(&p.floatValue, &p.floatValue + 1);
405 if (p.type == PropertyType::Float2) {
406 return std::span(p.float2Value);
408 if (p.type == PropertyType::FloatArray) {
409 const void* data = getPropertyData(p);
410 size_t size = p.data.size /
sizeof(float);
411 return std::span(
static_cast<const float*
>(data), size);
416std::span<const int32_t> Cogs::Core::PropertyStore::getIntArray(
const PropertyInfo& p)
const
418 if (p.type == PropertyType::Integer) {
419 return std::span(&p.intValue, 1);
421 else if (p.type == PropertyType::Int2) {
422 return std::span(p.int2Value);
424 else if (p.type == PropertyType::IntArray) {
425 const void* data = getPropertyData(p);
426 size_t size = p.data.size /
sizeof(int32_t);
427 return std::span(
static_cast<const int32_t*
>(data), size);
432std::span<const int32_t> Cogs::Core::PropertyStore::getIntArray(uint32_t index)
const
435 return getIntArray(getPropertyByIndex(index));
440std::span<const uint32_t> Cogs::Core::PropertyStore::getUIntArray(
const PropertyInfo& p)
const
442 if (p.type == PropertyType::UnsignedInteger) {
443 return std::span(&p.uintValue, 1);
445 else if (p.type == PropertyType::UInt2) {
446 return std::span(p.uint2Value);
448 else if (p.type == PropertyType::UIntArray) {
449 const void* data = getPropertyData(p);
450 size_t size = p.data.size /
sizeof(uint32_t);
451 return std::span(
static_cast<const uint32_t*
>(data), size);
456std::span<const uint32_t> Cogs::Core::PropertyStore::getUIntArray(uint32_t index)
const
459 return getUIntArray(getPropertyByIndex(index));
466 uint32_t index =
static_cast<uint32_t
>(headers.size());
468 PropertyInfo& p = headers.grow();
470 p.key = Strings::add(key);
476void Cogs::Core::PropertyStore::addPropertyData(PropertyInfo & p,
const void * data,
size_t size)
478 auto[ptr, offset] = allocate(size);
479 std::memcpy(ptr, data, size);
480 p.data.offset = offset;
481 p.data.size =
static_cast<uint32_t
>(size);
484uint8_t * Cogs::Core::PropertyStore::getPropertyData(
const PropertyInfo & p)
486 return static_cast<uint8_t *
>(data.data()) + p.data.offset;
489const uint8_t * Cogs::Core::PropertyStore::getPropertyData(
const PropertyInfo & p)
const
491 return static_cast<const uint8_t*
>(data.data()) + p.data.offset;
494uint32_t Cogs::Core::PropertyStore::addProperty(
const PropertyStore& other, uint32_t otherIndex)
496 if (otherIndex == NoProperty) {
499 const PropertyInfo& otherInfo = other.getPropertyByIndex(otherIndex);
500 PropertyInfo& pInfo = addProperty(other.getKey(otherInfo), otherInfo.type);
501 if (otherInfo.type == PropertyType::Unknown) {
504 else if (PropertyType::FirstInlineType <= otherInfo.type && otherInfo.type < PropertyType::LastInlineType) {
506 pInfo.data = otherInfo.data;
509 addPropertyData(pInfo, other.getData() + otherInfo.data.offset, otherInfo.data.size);
515void Cogs::Core::PropertyStore::copyProperties(
const PropertyStore & other, uint32_t offset, uint32_t count)
517 for (uint32_t i = 0; i < count; ++i) {
518 auto & otherP = other.getPropertyByIndex(offset + i);
520 if (PropertyInfo& existing = getProperty(otherP.key); existing.key == otherP.key) {
523 existing.type = otherP.type;
524 if (PropertyType::FirstInlineType <= otherP.type && otherP.type < PropertyType::LastInlineType) {
526 existing.data = otherP.data;
531 addPropertyData(existing, other.getData() + otherP.data.offset, otherP.data.size);
536 PropertyInfo& p = addProperty(other.getKey(otherP), otherP.type);
537 if (otherP.type == PropertyType::Unknown) {
542 if (PropertyType::FirstInlineType <= otherP.type && otherP.type < PropertyType::LastInlineType) {
544 p.data = otherP.data;
546 addPropertyData(p, other.getData() + otherP.data.offset, otherP.data.size);
553 const size_t currentCapacity = data.size();
554 const size_t requiredCapacity = dataSize + propertySize;
556 if (currentCapacity < requiredCapacity) {
557 constexpr size_t alignment = 0x1f;
558 size_t newCapacity = (((requiredCapacity * 3) / 2) + alignment) & ~alignment;
559 data.resize(newCapacity,
true);
561 assert(requiredCapacity <= data.size());
563 const uint32_t offset =
static_cast<uint32_t
>(dataSize);
564 auto ptr =
static_cast<uint8_t *
>(data.data()) + offset;
566 dataSize += propertySize;
570 dataSize = 4 * ((dataSize + 3) / 4);
573 return { ptr, offset };
576uint32_t Cogs::Core::PropertyRange::getPropertyIndex(StringRef key)
const
578 return store->findProperty(firstProperty, numProperties, key);
581float Cogs::Core::PropertyRange::getProperty(StringRef key,
float defaultValue)
const
583 auto index = store->findProperty(firstProperty, numProperties, key);
585 auto & p = store->getPropertyByIndex(index);
587 if (p.type == PropertyType::Float)
return p.floatValue;
592int Cogs::Core::PropertyRange::getProperty(StringRef key,
int defaultValue)
const
594 auto index = store->findProperty(firstProperty, numProperties, key);
596 auto & p = store->getPropertyByIndex(index);
598 if (p.type == PropertyType::Integer)
return p.intValue;
603Cogs::StringView Cogs::Core::PropertyRange::getProperty(StringRef key, StringView defaultValue)
const
605 auto index = store->findProperty(firstProperty, numProperties, key);
607 auto & p = store->getPropertyByIndex(index);
609 if (p.type == PropertyType::String)
return store->getString(index);
614std::span<const float> Cogs::Core::PropertyRange::getProperty(StringRef key, std::span<const float> defaultValue)
const
616 auto index = store->findProperty(firstProperty, numProperties, key);
618 else return defaultValue;
621std::span<const uint32_t> Cogs::Core::PropertyRange::getProperty(StringRef key, std::span<const uint32_t> defaultValue)
const
624 return store->getUIntArray(index);
Provides a weakly referenced view over the contents of a string.
static constexpr uint32_t NoProperty
Return from findProperty if key not found.