[ox/model] Add Reflect op type, fix union field type output, bump desc type versions

This commit is contained in:
Gary Talent 2022-05-29 01:17:10 -05:00
parent ff473bf465
commit 40cc222cd8
6 changed files with 35 additions and 17 deletions

View File

@ -35,7 +35,7 @@ struct DescriptorField {
// order of fields matters // order of fields matters
static constexpr auto TypeName = "net.drinkingtea.ox.DescriptorField"; static constexpr auto TypeName = "net.drinkingtea.ox.DescriptorField";
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 2;
// do not serialize type // do not serialize type
const struct DescriptorType *type = nullptr; const struct DescriptorType *type = nullptr;
@ -82,7 +82,7 @@ using FieldList = Vector<DescriptorField>;
struct DescriptorType { struct DescriptorType {
static constexpr auto TypeName = "net.drinkingtea.ox.DescriptorType"; static constexpr auto TypeName = "net.drinkingtea.ox.DescriptorType";
static constexpr auto TypeVersion = 1; static constexpr auto TypeVersion = 2;
String typeName; String typeName;
PrimitiveType primitiveType = PrimitiveType::UnsignedInteger; PrimitiveType primitiveType = PrimitiveType::UnsignedInteger;
@ -117,9 +117,14 @@ template<typename T>
constexpr Error model(T *io, DescriptorType *type) noexcept { constexpr Error model(T *io, DescriptorType *type) noexcept {
io->template setTypeInfo<DescriptorType>(); io->template setTypeInfo<DescriptorType>();
oxReturnError(io->field("typeName", &type->typeName)); oxReturnError(io->field("typeName", &type->typeName));
auto pt = static_cast<uint8_t>(type->primitiveType); if constexpr(ox_strcmp(T::opType(), "Reflect") == 0) {
oxReturnError(io->field("primitiveType", &pt)); uint8_t pt = 0;
type->primitiveType = static_cast<PrimitiveType>(pt); oxReturnError(io->field("primitiveType", &pt));
} else {
auto pt = type ? static_cast<uint8_t>(type->primitiveType) : 0;
oxReturnError(io->field("primitiveType", &pt));
type->primitiveType = static_cast<PrimitiveType>(pt);
}
oxReturnError(io->field("fieldList", &type->fieldList)); oxReturnError(io->field("fieldList", &type->fieldList));
oxReturnError(io->field("length", &type->length)); oxReturnError(io->field("length", &type->length));
oxReturnError(io->field("preloadable", &type->preloadable)); oxReturnError(io->field("preloadable", &type->preloadable));
@ -128,7 +133,7 @@ constexpr Error model(T *io, DescriptorType *type) noexcept {
template<typename T> template<typename T>
constexpr Error model(T *io, DescriptorField *field) noexcept { constexpr Error model(T *io, DescriptorField *field) noexcept {
io->template setTypeInfo<DescriptorField>(DescriptorField::TypeName, 4); io->template setTypeInfo<DescriptorField>();
oxReturnError(io->field("typeName", &field->typeName)); oxReturnError(io->field("typeName", &field->typeName));
oxReturnError(io->field("fieldName", &field->fieldName)); oxReturnError(io->field("fieldName", &field->fieldName));
oxReturnError(io->field("subscriptLevels", &field->subscriptLevels)); oxReturnError(io->field("subscriptLevels", &field->subscriptLevels));

View File

@ -67,7 +67,7 @@ class TypeDescWriter {
} }
static constexpr auto opType() noexcept { static constexpr auto opType() noexcept {
return OpType::WriteDefinition; return OpType::Reflect;
} }
private: private:
@ -121,7 +121,7 @@ constexpr Error TypeDescWriter::field(const char *name, T *val, std::size_t) noe
if (t == nullptr) { if (t == nullptr) {
type(p, &alreadyExisted); type(p, &alreadyExisted);
} }
m_type->fieldList.emplace_back(t, name, detail::indirectionLevels(val), alreadyExisted ? t->typeName : ""); m_type->fieldList.emplace_back(t, name, detail::indirectionLevels(val), t->typeName);
return OxError(0); return OxError(0);
} }
return OxError(1); return OxError(1);
@ -133,7 +133,7 @@ constexpr Error TypeDescWriter::field(const char *name, T val) noexcept {
bool alreadyExisted = false; bool alreadyExisted = false;
const auto t = type(val, &alreadyExisted); const auto t = type(val, &alreadyExisted);
oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated"); oxAssert(t != nullptr, "field(const char *name, T val): Type not found or generated");
m_type->fieldList.emplace_back(t, name, 0, alreadyExisted ? t->typeName : ""); m_type->fieldList.emplace_back(t, name, 0, t->typeName);
return OxError(0); return OxError(0);
} }
return OxError(1); return OxError(1);

View File

@ -43,7 +43,7 @@ class FieldCounter {
} }
static constexpr auto opType() { static constexpr auto opType() {
return OpType::Read; return OpType::Reflect;
} }
}; };

View File

@ -18,6 +18,7 @@ namespace OpType {
constexpr auto Read = "Read"; constexpr auto Read = "Read";
constexpr auto Write = "Write"; constexpr auto Write = "Write";
constexpr auto WriteDefinition = "WriteDefinition"; constexpr auto WriteDefinition = "WriteDefinition";
constexpr auto Reflect = "Reflect";
} }
// empty default implementations of model functions // empty default implementations of model functions
@ -39,6 +40,11 @@ constexpr Error modelWriteDefinition(T*, O*) noexcept {
return OxError(1, "Model: modelWriteDefinition not implemented"); return OxError(1, "Model: modelWriteDefinition not implemented");
} }
template<typename T, typename O>
constexpr Error modelReflect(T*, O*) noexcept {
return OxError(1, "Model: modelReflect not implemented");
}
template<typename T, typename O> template<typename T, typename O>
constexpr Error model(T *io, O *obj) noexcept { constexpr Error model(T *io, O *obj) noexcept {
if constexpr(ox_strcmp(T::opType(), OpType::Read) == 0) { if constexpr(ox_strcmp(T::opType(), OpType::Read) == 0) {
@ -47,6 +53,8 @@ constexpr Error model(T *io, O *obj) noexcept {
return modelWrite(io, obj); return modelWrite(io, obj);
} else if constexpr(ox_strcmp(T::opType(), OpType::WriteDefinition) == 0) { } else if constexpr(ox_strcmp(T::opType(), OpType::WriteDefinition) == 0) {
return modelWriteDefinition(io, obj); return modelWriteDefinition(io, obj);
} else if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) {
return modelReflect(io, obj);
} else { } else {
oxAssert(OxError(1), "Missing model function"); oxAssert(OxError(1), "Missing model function");
return OxError(1); return OxError(1);

View File

@ -46,7 +46,7 @@ struct TypeNameCatcher {
} }
static constexpr auto opType() noexcept { static constexpr auto opType() noexcept {
return OpType::WriteDefinition; return OpType::Reflect;
} }
}; };

View File

@ -11,6 +11,7 @@
#include <ox/std/hashmap.hpp> #include <ox/std/hashmap.hpp>
#include <ox/std/memory.hpp> #include <ox/std/memory.hpp>
#include <ox/std/string.hpp> #include <ox/std/string.hpp>
#include <ox/std/typetraits.hpp>
#include "typenamecatcher.hpp" #include "typenamecatcher.hpp"
#include "desctypes.hpp" #include "desctypes.hpp"
@ -60,10 +61,14 @@ class TypeStore {
const String name = nameCstr; const String name = nameCstr;
auto [val, err] = m_cache.at(name); auto [val, err] = m_cache.at(name);
if (err) { if (err) {
oxRequireM(dt, loadDescriptor(name)); if (!std::is_constant_evaluated()) {
auto &out = m_cache[name]; oxRequireM(dt, loadDescriptor(name));
out = std::move(dt); auto &out = m_cache[name];
return out.get(); out = std::move(dt);
return out.get();
} else {
return OxError(1, "Type not available");
}
} }
return val->get(); return val->get();
} }
@ -87,7 +92,7 @@ class TypeStore {
} }
protected: protected:
constexpr virtual Result<UniquePtr<DescriptorType>> loadDescriptor(const ox::String&) noexcept { virtual Result<UniquePtr<DescriptorType>> loadDescriptor(const ox::String&) noexcept {
return OxError(1); return OxError(1);
} }