From 93e72ae938e05539f3f39eb7c0fd5df57e978e8a Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Thu, 7 Jul 2022 20:02:26 -0500 Subject: [PATCH] [ox/model] Fix Vector support for ModelValue system --- deps/ox/src/ox/mc/test/tests.cpp | 10 +++++++++- deps/ox/src/ox/model/desctypes.hpp | 6 ++++-- deps/ox/src/ox/model/descwrite.hpp | 32 ++++++++++++++++++++++++------ deps/ox/src/ox/model/types.hpp | 2 ++ deps/ox/src/ox/model/typestore.hpp | 11 ++++++---- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/deps/ox/src/ox/mc/test/tests.cpp b/deps/ox/src/ox/mc/test/tests.cpp index df800c77..60c27ed6 100644 --- a/deps/ox/src/ox/mc/test/tests.cpp +++ b/deps/ox/src/ox/mc/test/tests.cpp @@ -48,6 +48,7 @@ struct TestStruct { ox::String String = ""; ox::BString<32> BString = ""; uint32_t List[4] = {0, 0, 0, 0}; + ox::Vector Vector = {1, 2, 3, 4, 5}; ox::HashMap Map; TestStructNest EmptyStruct; TestStructNest Struct; @@ -76,6 +77,7 @@ oxModelEnd() template constexpr ox::Error model(T *io, ox::CommonPtrWith auto *obj) noexcept { io->template setTypeInfo(); + oxReturnError(io->field("Vector", &obj->Vector)); oxReturnError(io->field("Bool", &obj->Bool)); oxReturnError(io->field("Int", &obj->Int)); oxReturnError(io->field("Int1", &obj->Int1)); @@ -158,6 +160,10 @@ std::map tests = { oxAssert(testIn.List[1] == testOut.List[1], "List[1] value mismatch"); oxAssert(testIn.List[2] == testOut.List[2], "List[2] value mismatch"); oxAssert(testIn.List[3] == testOut.List[3], "List[3] value mismatch"); + oxAssert(testIn.Vector[0] == testOut.Vector[0], "Vector[0] value mismatch"); + oxAssert(testIn.Vector[1] == testOut.Vector[1], "Vector[1] value mismatch"); + oxAssert(testIn.Vector[2] == testOut.Vector[2], "Vector[2] value mismatch"); + oxAssert(testIn.Vector[3] == testOut.Vector[3], "Vector[3] value mismatch"); oxAssert(testIn.Map["asdf"] == testOut.Map["asdf"], "Map[\"asdf\"] value mismatch"); oxAssert(testIn.Map["aoeu"] == testOut.Map["aoeu"], "Map[\"aoeu\"] value mismatch"); oxAssert(testIn.EmptyStruct.Bool == testOut.EmptyStruct.Bool, "EmptyStruct.Bool value mismatch"); @@ -296,7 +302,7 @@ std::map tests = { testIn.List[1] = 2; testIn.List[2] = 3; testIn.List[3] = 4; - testIn.Struct.Bool = false; + testIn.Struct.Bool = true; testIn.Struct.Int = 300; testIn.Struct.BString = "Test String 2"; testIn.unionIdx = 1; @@ -310,6 +316,7 @@ std::map tests = { oxAssert(ox::readMC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed"); oxAssert(testOut["Int"].get() == testIn.Int, "testOut.Int failed"); oxAssert(testOut["Bool"].get() == testIn.Bool, "testOut.Bool failed"); + oxAssert(testOut["BString"].get() == testIn.BString.c_str(), "testOut.String failed"); oxAssert(testOut["String"].get() == testIn.String, "testOut.String failed"); auto &testOutStruct = testOut["Struct"].get(); auto &testOutUnion = testOut["Union"].get(); @@ -320,6 +327,7 @@ std::map tests = { oxAssert(testOutStruct.typeName() == TestStructNest::TypeName, "ModelObject TypeName failed"); oxAssert(testOutStruct.typeVersion() == TestStructNest::TypeVersion, "ModelObject TypeVersion failed"); oxAssert(testOutStruct["Bool"].get() == testIn.Struct.Bool, "testOut.Struct.Bool failed"); + oxDebugf("{}", testOutStruct["BString"].get()); oxAssert(testOutStruct["BString"].get() == testIn.Struct.BString.c_str(), "testOut.Struct.BString failed"); oxAssert(testOut["unionIdx"].get() == testIn.unionIdx, "testOut.unionIdx failed"); oxAssert(testOutUnion.unionIdx() == testIn.unionIdx, "testOut.Union idx wrong"); diff --git a/deps/ox/src/ox/model/desctypes.hpp b/deps/ox/src/ox/model/desctypes.hpp index 6ecaf9d7..75d2f4c2 100644 --- a/deps/ox/src/ox/model/desctypes.hpp +++ b/deps/ox/src/ox/model/desctypes.hpp @@ -45,16 +45,18 @@ struct DescriptorField { String fieldName; int subscriptLevels = 0; String typeName; // gives reference to type for lookup if type is null + int typeVersion = 0; bool list = false; constexpr DescriptorField() noexcept = default; constexpr DescriptorField(const DescriptorType *pType, String pFieldName, - int pSubscriptLevels, String pTypeName) noexcept: + int pSubscriptLevels, String pTypeName, int pTypeVersion) noexcept: type(pType), fieldName(std::move(pFieldName)), subscriptLevels(pSubscriptLevels), - typeName(std::move(pTypeName)) { + typeName(std::move(pTypeName)), + typeVersion(pTypeVersion) { } constexpr DescriptorField(const DescriptorField &other) noexcept: diff --git a/deps/ox/src/ox/model/descwrite.hpp b/deps/ox/src/ox/model/descwrite.hpp index 7d913f68..5b7c96a5 100644 --- a/deps/ox/src/ox/model/descwrite.hpp +++ b/deps/ox/src/ox/model/descwrite.hpp @@ -150,7 +150,7 @@ constexpr Error TypeDescWriter::field(const char *name, const T *val, std::size_ constexpr typename remove_pointer::type *p = nullptr; const auto t = type(p); oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated"); - m_type->fieldList.emplace_back(t, name, detail::indirectionLevels_v + 1, t->typeName); + m_type->fieldList.emplace_back(t, name, detail::indirectionLevels_v + 1, t->typeName, t->typeVersion); return OxError(0); } return OxError(1); @@ -159,10 +159,14 @@ constexpr Error TypeDescWriter::field(const char *name, const T *val, std::size_ template constexpr Error TypeDescWriter::field(const char *name, T val) noexcept { if (m_type) { - const auto t = type(val); - oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated"); - m_type->fieldList.emplace_back(t, name, 0, t->typeName); - return OxError(0); + if constexpr(isVector_v::type> || isArray_v::type>) { + return field(name, val->data(), val->size()); + } else { + const auto t = type(val); + oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated"); + m_type->fieldList.emplace_back(t, name, 0, t->typeName, t->typeVersion); + return OxError(0); + } } return OxError(1); } @@ -175,7 +179,7 @@ constexpr Error TypeDescWriter::field(const char *name, const T *val) noexcept { } else { const auto t = type(val); oxAssert(t != nullptr, "field(const char *name, T *val): Type not found or generated"); - m_type->fieldList.emplace_back(t, name, 0, t->typeName); + m_type->fieldList.emplace_back(t, name, 0, t->typeName, t->typeVersion); return OxError(0); } } @@ -309,6 +313,22 @@ constexpr const DescriptorType *TypeDescWriter::getType(const String &tn, int ty } } +template +constexpr Result buildTypeDef(TypeStore *typeStore) noexcept { + TypeDescWriter writer(typeStore); + ModelHandlerInterface handler(&writer); + if (std::is_constant_evaluated()) { + std::allocator a; + T *t = a.allocate(1); + oxReturnError(model(&handler, t)); + a.deallocate(t, 1); + } else { + T *t = reinterpret_cast(ox_alloca(sizeof(T))); + oxReturnError(model(&handler, t)); + } + return writer.definition(); +} + template constexpr Result buildTypeDef(TypeStore *typeStore, T *val) noexcept { TypeDescWriter writer(typeStore); diff --git a/deps/ox/src/ox/model/types.hpp b/deps/ox/src/ox/model/types.hpp index 62dadccf..da65c358 100644 --- a/deps/ox/src/ox/model/types.hpp +++ b/deps/ox/src/ox/model/types.hpp @@ -69,6 +69,8 @@ constexpr bool isVector(const QVector*) noexcept { template constexpr bool isVector_v = isVector(static_cast(nullptr)); +static_assert(isVector_v>); + template constexpr bool isArray_v = false; diff --git a/deps/ox/src/ox/model/typestore.hpp b/deps/ox/src/ox/model/typestore.hpp index 05128d43..488e6b9e 100644 --- a/deps/ox/src/ox/model/typestore.hpp +++ b/deps/ox/src/ox/model/typestore.hpp @@ -32,14 +32,14 @@ class TypeStore { constexpr virtual ~TypeStore() noexcept = default; - constexpr Result get(const auto &name, int typeVersion) const noexcept { + constexpr Result get(const auto &name, int typeVersion) const noexcept { const auto typeId = buildTypeId(name, typeVersion); oxRequire(out, m_cache.at(typeId)); return out->get(); } template - constexpr Result get() const noexcept { + constexpr Result get() const noexcept { constexpr auto typeName = requireModelTypeName(); constexpr auto typeVersion = requireModelTypeVersion(); const auto typeId = buildTypeId(typeName, typeVersion); @@ -64,12 +64,15 @@ class TypeStore { return getInit(name); } - constexpr Result getLoad(const auto &typeName, auto typeVersion) noexcept { + constexpr Result getLoad(const auto &typeName, auto typeVersion) noexcept { const auto typeId = buildTypeId(typeName, typeVersion); auto [val, err] = m_cache.at(typeId); if (err) { if (!std::is_constant_evaluated()) { oxRequireM(dt, loadDescriptor(typeName, typeVersion)); + for (auto &f : dt->fieldList) { + oxReturnError(this->getLoad(f.typeName, f.typeVersion).moveTo(&f.type)); + } auto &out = m_cache[typeId]; out = std::move(dt); return out.get(); @@ -81,7 +84,7 @@ class TypeStore { } template - constexpr Result getLoad() noexcept { + constexpr Result getLoad() noexcept { constexpr auto typeName = requireModelTypeName(); constexpr auto typeVersion = requireModelTypeVersion(); return getLoad(typeName, typeVersion);