[ox] Make model type version mandatory

This commit is contained in:
Gary Talent 2022-05-29 22:21:05 -05:00
parent 3834de3318
commit c4a1655a8f
14 changed files with 89 additions and 76 deletions

View File

@ -28,9 +28,11 @@ class FileAddress {
public: public:
static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress"; static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress";
static constexpr auto TypeVersion = 1;
union Data { union Data {
static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress.Data"; static constexpr auto TypeName = "net.drinkingtea.ox.FileAddress.Data";
static constexpr auto TypeVersion = 1;
char *path = nullptr; char *path = nullptr;
const char *constPath; const char *constPath;
uint64_t inode; uint64_t inode;
@ -129,8 +131,14 @@ constexpr const char *getModelTypeName<FileAddress>() noexcept {
template<typename T> template<typename T>
constexpr Error model(T *io, FileAddress::Data *obj) noexcept { constexpr Error model(T *io, FileAddress::Data *obj) noexcept {
io->template setTypeInfo<FileAddress::Data>(); io->template setTypeInfo<FileAddress::Data>();
if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) {
String dummy;
oxReturnError(io->field("path", &dummy));
oxReturnError(io->field("constPath", &dummy));
} else {
oxReturnError(io->field("path", SerStr(&obj->path))); oxReturnError(io->field("path", SerStr(&obj->path)));
oxReturnError(io->field("constPath", SerStr(&obj->path))); oxReturnError(io->field("constPath", SerStr(&obj->path)));
}
oxReturnError(io->field("inode", &obj->inode)); oxReturnError(io->field("inode", &obj->inode));
return OxError(0); return OxError(0);
} }
@ -138,10 +146,16 @@ constexpr Error model(T *io, FileAddress::Data *obj) noexcept {
template<typename T> template<typename T>
constexpr Error model(T *io, FileAddress *fa) noexcept { constexpr Error model(T *io, FileAddress *fa) noexcept {
io->template setTypeInfo<FileAddress>(); io->template setTypeInfo<FileAddress>();
if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) {
int8_t type = 0;
oxReturnError(io->field("type", &type));
oxReturnError(io->field("data", UnionView(&fa->m_data, 0)));
} else {
auto type = static_cast<int8_t>(fa->m_type); auto type = static_cast<int8_t>(fa->m_type);
oxReturnError(io->field("type", &type)); oxReturnError(io->field("type", &type));
fa->m_type = static_cast<FileAddressType>(type); fa->m_type = static_cast<FileAddressType>(type);
oxReturnError(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type)))); oxReturnError(io->field("data", UnionView(&fa->m_data, static_cast<int>(fa->m_type))));
}
return OxError(0); return OxError(0);
} }

View File

@ -95,9 +95,7 @@ class MetalClawReader {
StringLength stringLength(const char *name) noexcept; StringLength stringLength(const char *name) noexcept;
template<typename T = std::nullptr_t> template<typename T = std::nullptr_t>
constexpr void setTypeInfo() noexcept; constexpr void setTypeInfo(const char *name = T::TypeName, int version = T::TypeVersion, int fields = ModelFieldCount_v<T>) noexcept;
constexpr void setTypeInfo(const char *name, int fields) noexcept;
/** /**
* Returns a MetalClawReader to parse a child object. * Returns a MetalClawReader to parse a child object.
@ -237,7 +235,7 @@ Error MetalClawReader::field(const char *name, T *val, std::size_t valLen) noexc
// read the list // read the list
if (valLen >= len) { if (valLen >= len) {
auto reader = child(""); auto reader = child("");
reader.setTypeInfo("List", static_cast<int>(len)); reader.setTypeInfo("List", 0, static_cast<int>(len));
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
oxReturnError(reader.field("", &val[i])); oxReturnError(reader.field("", &val[i]));
} }
@ -264,7 +262,7 @@ Error MetalClawReader::field(const char*, HashMap<String, T> *val) noexcept {
m_buffIt += bytesRead; m_buffIt += bytesRead;
// read the list // read the list
auto reader = child(""); auto reader = child("");
reader.setTypeInfo("List", static_cast<int>(len)); reader.setTypeInfo("List", 0, static_cast<int>(len));
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
const auto keyLen = reader.stringLength(nullptr); const auto keyLen = reader.stringLength(nullptr);
auto wkey = ox_malloca(keyLen + 1, char, 0); auto wkey = ox_malloca(keyLen + 1, char, 0);
@ -292,7 +290,7 @@ Error MetalClawReader::field(const char*, Handler handler) noexcept {
// read the list // read the list
auto reader = child(""); auto reader = child("");
reader.setTypeInfo("List", static_cast<int>(len)); reader.setTypeInfo("List", 0, static_cast<int>(len));
for (std::size_t i = 0; i < len; ++i) { for (std::size_t i = 0; i < len; ++i) {
T val; T val;
oxReturnError(reader.field("", &val)); oxReturnError(reader.field("", &val));
@ -305,11 +303,7 @@ Error MetalClawReader::field(const char*, Handler handler) noexcept {
} }
template<typename T> template<typename T>
constexpr void MetalClawReader::setTypeInfo() noexcept { constexpr void MetalClawReader::setTypeInfo(const char*, int, int fields) noexcept {
setTypeInfo(ModelTypeName_v<T>, countFields<T>());
}
constexpr void MetalClawReader::setTypeInfo(const char*, int fields) noexcept {
m_fields = fields; m_fields = fields;
m_buffIt = static_cast<std::size_t>((fields / 8 + 1) - (fields % 8 == 0)); m_buffIt = static_cast<std::size_t>((fields / 8 + 1) - (fields % 8 == 0));
m_fieldPresence.setFields(fields); m_fieldPresence.setFields(fields);

View File

@ -16,6 +16,7 @@
union TestUnion { union TestUnion {
static constexpr auto TypeName = "TestUnion"; static constexpr auto TypeName = "TestUnion";
static constexpr auto TypeVersion = 1;
bool Bool; bool Bool;
uint32_t Int = 5; uint32_t Int = 5;
char CString[32]; char CString[32];
@ -23,6 +24,7 @@ union TestUnion {
struct TestStructNest { struct TestStructNest {
static constexpr auto TypeName = "TestStructNest"; static constexpr auto TypeName = "TestStructNest";
static constexpr auto TypeVersion = 1;
bool Bool = false; bool Bool = false;
uint32_t Int = 0; uint32_t Int = 0;
ox::BString<32> BString = ""; ox::BString<32> BString = "";
@ -30,6 +32,7 @@ struct TestStructNest {
struct TestStruct { struct TestStruct {
static constexpr auto TypeName = "TestStruct"; static constexpr auto TypeName = "TestStruct";
static constexpr auto TypeVersion = 1;
bool Bool = false; bool Bool = false;
int32_t Int = 0; int32_t Int = 0;
int32_t Int1 = 0; int32_t Int1 = 0;

View File

@ -77,7 +77,7 @@ class MetalClawWriter {
Error field(const char*, UnionView<U> val) noexcept; Error field(const char*, UnionView<U> val) noexcept;
template<typename T = std::nullptr_t> template<typename T = std::nullptr_t>
void setTypeInfo(const char *name = T::TypeName, int fields = countFields<T>()) noexcept; void setTypeInfo(const char *name = T::TypeName, int version = T::TypeVersion, int fields = ModelFieldCount_v<T>) noexcept;
[[nodiscard]] [[nodiscard]]
std::size_t size() const noexcept; std::size_t size() const noexcept;
@ -171,7 +171,7 @@ Error MetalClawWriter::field(const char*, T *val, std::size_t len) noexcept {
} }
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt); MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
writer.setTypeInfo<T>("List", len); writer.setTypeInfo<T>("List", 0, len);
// write the array // write the array
for (std::size_t i = 0; i < len; i++) { for (std::size_t i = 0; i < len; i++) {
@ -205,7 +205,7 @@ Error MetalClawWriter::field(const char*, HashMap<String, T> *val) noexcept {
MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt); MetalClawWriter writer(m_buff + m_buffIt, m_buffLen - m_buffIt);
// double len for both key and value // double len for both key and value
writer.setTypeInfo("Map", len * 2); writer.setTypeInfo("Map", 0, len * 2);
// write the array // write the array
for (std::size_t i = 0; i < len; i++) { for (std::size_t i = 0; i < len; i++) {
@ -245,7 +245,7 @@ Error MetalClawWriter::appendInteger(I val) noexcept {
} }
template<typename T> template<typename T>
void MetalClawWriter::setTypeInfo(const char*, int fields) noexcept { void MetalClawWriter::setTypeInfo(const char*, int, int fields) noexcept {
m_fields = fields; m_fields = fields;
m_fieldPresence.setFields(fields); m_fieldPresence.setFields(fields);
m_buffIt = static_cast<std::size_t>(m_fieldPresence.getMaxLen()); m_buffIt = static_cast<std::size_t>(m_fieldPresence.getMaxLen());

View File

@ -85,6 +85,7 @@ struct DescriptorType {
static constexpr auto TypeVersion = 2; static constexpr auto TypeVersion = 2;
String typeName; String typeName;
int typeVersion = 0;
PrimitiveType primitiveType = PrimitiveType::UnsignedInteger; PrimitiveType primitiveType = PrimitiveType::UnsignedInteger;
// fieldList only applies to structs // fieldList only applies to structs
FieldList fieldList; FieldList fieldList;
@ -117,6 +118,7 @@ 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));
oxReturnError(io->field("typeVersion", &type->typeVersion));
if constexpr(ox_strcmp(T::opType(), "Reflect") == 0) { if constexpr(ox_strcmp(T::opType(), "Reflect") == 0) {
uint8_t pt = 0; uint8_t pt = 0;
oxReturnError(io->field("primitiveType", &pt)); oxReturnError(io->field("primitiveType", &pt));
@ -148,7 +150,7 @@ class TypeDescReader;
template<typename T> template<typename T>
constexpr Error model(TypeDescReader<T> *io, DescriptorField *field) noexcept { constexpr Error model(TypeDescReader<T> *io, DescriptorField *field) noexcept {
io->template setTypeInfo<DescriptorField>(DescriptorField::TypeName, 4); io->template setTypeInfo<DescriptorField>(DescriptorField::TypeName, DescriptorField::TypeVersion, 4);
oxReturnError(io->field("typeName", &field->typeName)); oxReturnError(io->field("typeName", &field->typeName));
auto &typeStore = io->typeStore(); auto &typeStore = io->typeStore();
auto &[type, err] = typeStore->at(field->typeName).value; auto &[type, err] = typeStore->at(field->typeName).value;

View File

@ -59,7 +59,7 @@ class TypeDescWriter {
constexpr Error field(const char *name, T *val) noexcept; constexpr Error field(const char *name, T *val) noexcept;
template<typename T = std::nullptr_t> template<typename T = std::nullptr_t>
constexpr void setTypeInfo(const char *name = T::TypeName, int fields = countFields<T>()) noexcept; constexpr void setTypeInfo(const char *name = T::TypeName, int fields = ModelFieldCount_v<T>) noexcept;
[[nodiscard]] [[nodiscard]]
constexpr DescriptorType *definition() noexcept { constexpr DescriptorType *definition() noexcept {

View File

@ -15,29 +15,31 @@
namespace ox { namespace ox {
namespace detail {
template<typename T> template<typename T>
class FieldCounter { class FieldCounter {
public: public:
int fields = 0; int fields = 0;
template<typename U = std::nullptr_t> template<typename U = std::nullptr_t>
constexpr void setTypeInfo(const char* = "", int = 0) { constexpr void setTypeInfo(const char * = "", int = 0, int = 0) {
} }
template<typename U> template<typename U>
constexpr ox::Error field(const char*, U) noexcept { constexpr ox::Error field(const char *, U) noexcept {
++fields; ++fields;
return OxError(0); return OxError(0);
} }
template<typename U> template<typename U>
constexpr ox::Error field(const char*, U, std::size_t) noexcept { constexpr ox::Error field(const char *, U, std::size_t) noexcept {
++fields; ++fields;
return OxError(0); return OxError(0);
} }
template<typename U, typename Handler> template<typename U, typename Handler>
constexpr Error field(const char*, Handler) { constexpr Error field(const char *, Handler) {
++fields; ++fields;
return OxError(0); return OxError(0);
} }
@ -47,21 +49,16 @@ class FieldCounter {
} }
}; };
template<typename T>
constexpr int countFields() noexcept {
if (std::is_constant_evaluated()) {
auto a = std::allocator<T>();
auto t = a.allocate(1);
FieldCounter<T> c;
oxIgnoreError(model(&c, t));
a.deallocate(t, 1);
return c.fields;
} else {
T t;
FieldCounter<T> c;
oxIgnoreError(model(&c, &t));
return c.fields;
}
} }
template<typename T>
constexpr auto ModelFieldCount_v = [] {
auto a = std::allocator<T>();
auto t = a.allocate(1);
detail::FieldCounter<T> c;
oxAssert(model(&c, t), "Count failed");
a.deallocate(t, 1);
return c.fields;
}();
} }

View File

@ -52,7 +52,7 @@ class MemberList {
} }
template<typename T = void> template<typename T = void>
constexpr void setTypeInfo(const char* = T::TypeName, int = countFields<T>()) noexcept { constexpr void setTypeInfo(const char* = T::TypeName, int = ModelFieldCount_v<T>) noexcept {
} }
[[nodiscard]] [[nodiscard]]
@ -172,7 +172,7 @@ class Mover {
} }
template<typename T = void> template<typename T = void>
constexpr void setTypeInfo(const char* = T::TypeName, int = countFields<T>()) noexcept { constexpr void setTypeInfo(const char* = T::TypeName, int = T::TypeVersion, int = ModelFieldCount_v<T>) noexcept {
} }
[[nodiscard]] [[nodiscard]]
@ -262,7 +262,7 @@ class Equals {
template<typename T> template<typename T>
constexpr void moveModel(T *dst, T *src) noexcept { constexpr void moveModel(T *dst, T *src) noexcept {
constexpr auto size = countFields<T>(); constexpr auto size = ModelFieldCount_v<T>;
detail::MemberList<size> dstFields; detail::MemberList<size> dstFields;
detail::Mover<size> mover(&dstFields); detail::Mover<size> mover(&dstFields);
oxIgnoreError(model(&dstFields, dst)); oxIgnoreError(model(&dstFields, dst));
@ -271,7 +271,7 @@ constexpr void moveModel(T *dst, T *src) noexcept {
template<typename T> template<typename T>
constexpr void copyModel(T *dst, const T *src) noexcept { constexpr void copyModel(T *dst, const T *src) noexcept {
constexpr auto size = countFields<T>(); constexpr auto size = ModelFieldCount_v<T>;
detail::MemberList<size> dstFields; detail::MemberList<size> dstFields;
detail::Copier<size> copier(&dstFields); detail::Copier<size> copier(&dstFields);
oxIgnoreError(model(&dstFields, dst)); oxIgnoreError(model(&dstFields, dst));

View File

@ -17,7 +17,6 @@ namespace ox {
namespace OpType { namespace OpType {
constexpr auto Read = "Read"; constexpr auto Read = "Read";
constexpr auto Write = "Write"; constexpr auto Write = "Write";
constexpr auto WriteDefinition = "WriteDefinition";
constexpr auto Reflect = "Reflect"; constexpr auto Reflect = "Reflect";
} }
@ -35,11 +34,6 @@ constexpr Error modelWrite(T*, O*) noexcept {
return OxError(1, "Model: modelWrite not implemented"); return OxError(1, "Model: modelWrite not implemented");
} }
template<typename T, typename O>
constexpr Error modelWriteDefinition(T*, O*) noexcept {
return OxError(1, "Model: modelWriteDefinition not implemented");
}
template<typename T, typename O> template<typename T, typename O>
constexpr Error modelReflect(T*, O*) noexcept { constexpr Error modelReflect(T*, O*) noexcept {
return OxError(1, "Model: modelReflect not implemented"); return OxError(1, "Model: modelReflect not implemented");
@ -51,8 +45,6 @@ constexpr Error model(T *io, O *obj) noexcept {
return modelRead(io, obj); return modelRead(io, obj);
} else if constexpr(ox_strcmp(T::opType(), OpType::Write) == 0) { } else if constexpr(ox_strcmp(T::opType(), OpType::Write) == 0) {
return modelWrite(io, obj); return modelWrite(io, obj);
} else if constexpr(ox_strcmp(T::opType(), OpType::WriteDefinition) == 0) {
return modelWriteDefinition(io, obj);
} else if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) { } else if constexpr(ox_strcmp(T::opType(), OpType::Reflect) == 0) {
return modelReflect(io, obj); return modelReflect(io, obj);
} else { } else {

View File

@ -59,7 +59,7 @@ struct TypeInfoCatcher {
constexpr TypeInfoCatcher() noexcept = default; constexpr TypeInfoCatcher() noexcept = default;
template<typename T = std::nullptr_t> template<typename T = std::nullptr_t>
constexpr void setTypeInfo(const char *n = T::TypeName, int v = T::TypeVersion) noexcept { constexpr void setTypeInfo(const char *n = T::TypeName, int v = T::TypeVersion, int = 0) noexcept {
this->name = n; this->name = n;
this->version = v; this->version = v;
} }
@ -80,7 +80,7 @@ struct TypeInfoCatcher {
} }
static constexpr auto opType() noexcept { static constexpr auto opType() noexcept {
return OpType::WriteDefinition; return OpType::Reflect;
} }
}; };
@ -135,4 +135,7 @@ consteval auto requireModelTypeName() noexcept {
template<typename T, typename Str = const char*> template<typename T, typename Str = const char*>
constexpr auto ModelTypeName_v = getModelTypeName<T, Str>(); constexpr auto ModelTypeName_v = getModelTypeName<T, Str>();
template<typename T, typename Str = const char*>
constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
} }

View File

@ -17,7 +17,7 @@ namespace ox {
template<typename Reader, typename T> template<typename Reader, typename T>
class DataWalker { class DataWalker {
template<typename ReaderBase, typename FH> template<typename ReaderBase, typename FH>
friend Error parseField(const DescriptorField &field, ReaderBase *rdr, DataWalker<ReaderBase, FH> *walker) noexcept; friend constexpr Error parseField(const DescriptorField &field, ReaderBase *rdr, DataWalker<ReaderBase, FH> *walker) noexcept;
private: private:
Vector<const DescriptorType*> m_typeStack; Vector<const DescriptorType*> m_typeStack;
@ -26,36 +26,36 @@ class DataWalker {
Vector<String> m_typePath; Vector<String> m_typePath;
public: public:
DataWalker(DescriptorType *type, T fieldHandler) noexcept; constexpr DataWalker(DescriptorType *type, T fieldHandler) noexcept;
Result<const DescriptorType*> type() const noexcept; constexpr Result<const DescriptorType*> type() const noexcept;
Error read(const DescriptorField&, Reader *rdr) noexcept; constexpr Error read(const DescriptorField&, Reader *rdr) noexcept;
protected: protected:
void pushNamePath(const FieldName &fn) noexcept; constexpr void pushNamePath(const FieldName &fn) noexcept;
void popNamePath() noexcept; constexpr void popNamePath() noexcept;
void pushType(const DescriptorType *type) noexcept; constexpr void pushType(const DescriptorType *type) noexcept;
void popType() noexcept; constexpr void popType() noexcept;
}; };
template<typename Reader, typename T> template<typename Reader, typename T>
DataWalker<Reader, T>::DataWalker(DescriptorType *type, T fieldHandler) noexcept: m_fieldHandler(fieldHandler) { constexpr DataWalker<Reader, T>::DataWalker(DescriptorType *type, T fieldHandler) noexcept: m_fieldHandler(fieldHandler) {
m_typeStack.push_back(type); m_typeStack.push_back(type);
} }
template<typename Reader, typename T> template<typename Reader, typename T>
Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept { constexpr Result<const DescriptorType*> DataWalker<Reader, T>::type() const noexcept {
oxRequire(out, m_typeStack.back()); oxRequire(out, m_typeStack.back());
return out; return out;
} }
template<typename Reader, typename T> template<typename Reader, typename T>
Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) noexcept { constexpr Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) noexcept {
// get const ref of paths // get const ref of paths
const auto &pathCr = m_path; const auto &pathCr = m_path;
const auto &typePathCr = m_typePath; const auto &typePathCr = m_typePath;
@ -63,33 +63,33 @@ Error DataWalker<Reader, T>::read(const DescriptorField &f, Reader *rdr) noexcep
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::pushNamePath(const FieldName &fn) noexcept { constexpr void DataWalker<Reader, T>::pushNamePath(const FieldName &fn) noexcept {
m_path.push_back(fn); m_path.push_back(fn);
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::popNamePath() noexcept { constexpr void DataWalker<Reader, T>::popNamePath() noexcept {
m_path.pop_back(); m_path.pop_back();
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::pushType(const DescriptorType *type) noexcept { constexpr void DataWalker<Reader, T>::pushType(const DescriptorType *type) noexcept {
m_typeStack.push_back(type); m_typeStack.push_back(type);
} }
template<typename Reader, typename T> template<typename Reader, typename T>
void DataWalker<Reader, T>::popType() noexcept { constexpr void DataWalker<Reader, T>::popType() noexcept {
m_typeStack.pop_back(); m_typeStack.pop_back();
} }
template<typename Reader, typename FH> template<typename Reader, typename FH>
static Error parseField(const DescriptorField &field, Reader *rdr, DataWalker<Reader, FH> *walker) noexcept { static constexpr Error parseField(const DescriptorField &field, Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
walker->pushNamePath(field.fieldName); walker->pushNamePath(field.fieldName);
if (field.subscriptLevels) { if (field.subscriptLevels) {
// add array handling // add array handling
oxRequire(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true)); oxRequire(arrayLen, rdr->arrayLength(field.fieldName.c_str(), true));
auto child = rdr->child(field.fieldName.c_str()); auto child = rdr->child(field.fieldName.c_str());
child.setTypeInfo(field.fieldName.c_str(), arrayLen); child.setTypeInfo(field.type->typeName.c_str(), field.type->typeVersion, arrayLen);
DescriptorField f(field); // create mutable copy DescriptorField f(field); // create mutable copy
--f.subscriptLevels; --f.subscriptLevels;
String subscript; String subscript;
@ -134,8 +134,9 @@ template<typename Reader, typename FH>
constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept { constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
oxRequire(type, walker->type()); oxRequire(type, walker->type());
auto typeName = type->typeName.c_str(); auto typeName = type->typeName.c_str();
auto typeVersion = type->typeVersion;
auto &fields = type->fieldList; auto &fields = type->fieldList;
rdr->setTypeInfo(typeName, fields.size()); rdr->setTypeInfo(typeName, typeVersion, fields.size());
for (const auto &field : fields) { for (const auto &field : fields) {
oxReturnError(parseField(field, rdr, walker)); oxReturnError(parseField(field, rdr, walker));
} }
@ -143,7 +144,7 @@ constexpr Error model(Reader *rdr, DataWalker<Reader, FH> *walker) noexcept {
} }
template<typename Reader, typename Handler> template<typename Reader, typename Handler>
Error walkModel(DescriptorType *type, const char *data, std::size_t dataLen, Handler handler) noexcept { constexpr Error walkModel(DescriptorType *type, const char *data, std::size_t dataLen, Handler handler) noexcept {
DataWalker<Reader, Handler> walker(type, handler); DataWalker<Reader, Handler> walker(type, handler);
Reader rdr(reinterpret_cast<const uint8_t*>(data), dataLen); Reader rdr(reinterpret_cast<const uint8_t*>(data), dataLen);
return model(&rdr, &walker); return model(&rdr, &walker);

View File

@ -96,6 +96,10 @@ class OrganicClawReader {
constexpr void setTypeInfo(const char*, int) noexcept { constexpr void setTypeInfo(const char*, int) noexcept {
} }
template<typename T = void>
constexpr void setTypeInfo(const char*, int, int) noexcept {
}
/** /**
* Returns a OrganicClawReader to parse a child object. * Returns a OrganicClawReader to parse a child object.
*/ */

View File

@ -16,6 +16,7 @@
union TestUnion { union TestUnion {
static constexpr auto TypeName = "TestUnion"; static constexpr auto TypeName = "TestUnion";
static constexpr auto TypeVersion = 1;
bool Bool; bool Bool;
uint32_t Int = 5; uint32_t Int = 5;
char String[32]; char String[32];
@ -23,6 +24,7 @@ union TestUnion {
struct TestStructNest { struct TestStructNest {
static constexpr auto TypeName = "TestStructNest"; static constexpr auto TypeName = "TestStructNest";
static constexpr auto TypeVersion = 1;
bool Bool = false; bool Bool = false;
uint32_t Int = 0; uint32_t Int = 0;
ox::BString<32> String = ""; ox::BString<32> String = "";
@ -30,6 +32,7 @@ struct TestStructNest {
struct TestStruct { struct TestStruct {
static constexpr auto TypeName = "TestStruct"; static constexpr auto TypeName = "TestStruct";
static constexpr auto TypeVersion = 1;
bool Bool = false; bool Bool = false;
int32_t Int = 0; int32_t Int = 0;
int32_t Int1 = 0; int32_t Int1 = 0;

View File

@ -69,7 +69,7 @@ class OrganicClawWriter {
Error field(const char*, T *val) noexcept; Error field(const char*, T *val) noexcept;
template<typename T = void> template<typename T = void>
constexpr void setTypeInfo(const char* = T::TypeName, int = countFields<T>()) noexcept { constexpr void setTypeInfo(const char* = T::TypeName, int = T::TypeVersion, int = ModelFieldCount_v<T>) noexcept {
} }
static constexpr auto opType() noexcept { static constexpr auto opType() noexcept {