[ox/model] Fix Vector support for ModelValue system
This commit is contained in:
parent
7d95dbaa99
commit
93e72ae938
10
deps/ox/src/ox/mc/test/tests.cpp
vendored
10
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -48,6 +48,7 @@ struct TestStruct {
|
||||
ox::String String = "";
|
||||
ox::BString<32> BString = "";
|
||||
uint32_t List[4] = {0, 0, 0, 0};
|
||||
ox::Vector<uint32_t> Vector = {1, 2, 3, 4, 5};
|
||||
ox::HashMap<ox::String, int> Map;
|
||||
TestStructNest EmptyStruct;
|
||||
TestStructNest Struct;
|
||||
@ -76,6 +77,7 @@ oxModelEnd()
|
||||
template<typename T>
|
||||
constexpr ox::Error model(T *io, ox::CommonPtrWith<TestStruct> auto *obj) noexcept {
|
||||
io->template setTypeInfo<TestStruct>();
|
||||
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<ox::String, ox::Error(*)()> 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<ox::String, ox::Error(*)()> 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<ox::String, ox::Error(*)()> tests = {
|
||||
oxAssert(ox::readMC(dataBuff.data(), dataBuff.size(), &testOut), "Data read failed");
|
||||
oxAssert(testOut["Int"].get<int>() == testIn.Int, "testOut.Int failed");
|
||||
oxAssert(testOut["Bool"].get<bool>() == testIn.Bool, "testOut.Bool failed");
|
||||
oxAssert(testOut["BString"].get<ox::String>() == testIn.BString.c_str(), "testOut.String failed");
|
||||
oxAssert(testOut["String"].get<ox::String>() == testIn.String, "testOut.String failed");
|
||||
auto &testOutStruct = testOut["Struct"].get<ox::ModelObject>();
|
||||
auto &testOutUnion = testOut["Union"].get<ox::ModelUnion>();
|
||||
@ -320,6 +327,7 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
oxAssert(testOutStruct.typeName() == TestStructNest::TypeName, "ModelObject TypeName failed");
|
||||
oxAssert(testOutStruct.typeVersion() == TestStructNest::TypeVersion, "ModelObject TypeVersion failed");
|
||||
oxAssert(testOutStruct["Bool"].get<bool>() == testIn.Struct.Bool, "testOut.Struct.Bool failed");
|
||||
oxDebugf("{}", testOutStruct["BString"].get<ox::String>());
|
||||
oxAssert(testOutStruct["BString"].get<ox::String>() == testIn.Struct.BString.c_str(), "testOut.Struct.BString failed");
|
||||
oxAssert(testOut["unionIdx"].get<int>() == testIn.unionIdx, "testOut.unionIdx failed");
|
||||
oxAssert(testOutUnion.unionIdx() == testIn.unionIdx, "testOut.Union idx wrong");
|
||||
|
6
deps/ox/src/ox/model/desctypes.hpp
vendored
6
deps/ox/src/ox/model/desctypes.hpp
vendored
@ -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:
|
||||
|
26
deps/ox/src/ox/model/descwrite.hpp
vendored
26
deps/ox/src/ox/model/descwrite.hpp
vendored
@ -150,7 +150,7 @@ constexpr Error TypeDescWriter::field(const char *name, const T *val, std::size_
|
||||
constexpr typename remove_pointer<decltype(val)>::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<T> + 1, t->typeName);
|
||||
m_type->fieldList.emplace_back(t, name, detail::indirectionLevels_v<T> + 1, t->typeName, t->typeVersion);
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1);
|
||||
@ -159,11 +159,15 @@ constexpr Error TypeDescWriter::field(const char *name, const T *val, std::size_
|
||||
template<typename T>
|
||||
constexpr Error TypeDescWriter::field(const char *name, T val) noexcept {
|
||||
if (m_type) {
|
||||
if constexpr(isVector_v<typename ox::remove_pointer<T>::type> || isArray_v<typename ox::remove_pointer<T>::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);
|
||||
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<typename T>
|
||||
constexpr Result<DescriptorType*> buildTypeDef(TypeStore *typeStore) noexcept {
|
||||
TypeDescWriter writer(typeStore);
|
||||
ModelHandlerInterface handler(&writer);
|
||||
if (std::is_constant_evaluated()) {
|
||||
std::allocator<T> a;
|
||||
T *t = a.allocate(1);
|
||||
oxReturnError(model(&handler, t));
|
||||
a.deallocate(t, 1);
|
||||
} else {
|
||||
T *t = reinterpret_cast<T*>(ox_alloca(sizeof(T)));
|
||||
oxReturnError(model(&handler, t));
|
||||
}
|
||||
return writer.definition();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Result<DescriptorType*> buildTypeDef(TypeStore *typeStore, T *val) noexcept {
|
||||
TypeDescWriter writer(typeStore);
|
||||
|
2
deps/ox/src/ox/model/types.hpp
vendored
2
deps/ox/src/ox/model/types.hpp
vendored
@ -69,6 +69,8 @@ constexpr bool isVector(const QVector<T>*) noexcept {
|
||||
template<typename T>
|
||||
constexpr bool isVector_v = isVector(static_cast<const T*>(nullptr));
|
||||
|
||||
static_assert(isVector_v<ox::Vector<unsigned int, 0ul>>);
|
||||
|
||||
template<typename T>
|
||||
constexpr bool isArray_v = false;
|
||||
|
||||
|
11
deps/ox/src/ox/model/typestore.hpp
vendored
11
deps/ox/src/ox/model/typestore.hpp
vendored
@ -32,14 +32,14 @@ class TypeStore {
|
||||
|
||||
constexpr virtual ~TypeStore() noexcept = default;
|
||||
|
||||
constexpr Result<DescriptorType*> get(const auto &name, int typeVersion) const noexcept {
|
||||
constexpr Result<const DescriptorType*> get(const auto &name, int typeVersion) const noexcept {
|
||||
const auto typeId = buildTypeId(name, typeVersion);
|
||||
oxRequire(out, m_cache.at(typeId));
|
||||
return out->get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Result<DescriptorType*> get() const noexcept {
|
||||
constexpr Result<const DescriptorType*> get() const noexcept {
|
||||
constexpr auto typeName = requireModelTypeName<T>();
|
||||
constexpr auto typeVersion = requireModelTypeVersion<T>();
|
||||
const auto typeId = buildTypeId(typeName, typeVersion);
|
||||
@ -64,12 +64,15 @@ class TypeStore {
|
||||
return getInit(name);
|
||||
}
|
||||
|
||||
constexpr Result<DescriptorType*> getLoad(const auto &typeName, auto typeVersion) noexcept {
|
||||
constexpr Result<const DescriptorType*> 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<typename T>
|
||||
constexpr Result<DescriptorType*> getLoad() noexcept {
|
||||
constexpr Result<const DescriptorType*> getLoad() noexcept {
|
||||
constexpr auto typeName = requireModelTypeName<T>();
|
||||
constexpr auto typeVersion = requireModelTypeVersion<T>();
|
||||
return getLoad(typeName, typeVersion);
|
||||
|
Loading…
Reference in New Issue
Block a user