[ox] Make model type version mandatory
This commit is contained in:
parent
3834de3318
commit
c4a1655a8f
14
deps/ox/src/ox/fs/filesystem/filelocation.hpp
vendored
14
deps/ox/src/ox/fs/filesystem/filelocation.hpp
vendored
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
deps/ox/src/ox/mc/read.hpp
vendored
16
deps/ox/src/ox/mc/read.hpp
vendored
@ -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);
|
||||||
|
3
deps/ox/src/ox/mc/test/tests.cpp
vendored
3
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -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;
|
||||||
|
8
deps/ox/src/ox/mc/write.hpp
vendored
8
deps/ox/src/ox/mc/write.hpp
vendored
@ -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());
|
||||||
|
4
deps/ox/src/ox/model/desctypes.hpp
vendored
4
deps/ox/src/ox/model/desctypes.hpp
vendored
@ -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;
|
||||||
|
2
deps/ox/src/ox/model/descwrite.hpp
vendored
2
deps/ox/src/ox/model/descwrite.hpp
vendored
@ -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 {
|
||||||
|
35
deps/ox/src/ox/model/fieldcounter.hpp
vendored
35
deps/ox/src/ox/model/fieldcounter.hpp
vendored
@ -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;
|
||||||
|
}();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
8
deps/ox/src/ox/model/modelops.hpp
vendored
8
deps/ox/src/ox/model/modelops.hpp
vendored
@ -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));
|
||||||
|
8
deps/ox/src/ox/model/optype.hpp
vendored
8
deps/ox/src/ox/model/optype.hpp
vendored
@ -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 {
|
||||||
|
7
deps/ox/src/ox/model/typenamecatcher.hpp
vendored
7
deps/ox/src/ox/model/typenamecatcher.hpp
vendored
@ -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>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
39
deps/ox/src/ox/model/walk.hpp
vendored
39
deps/ox/src/ox/model/walk.hpp
vendored
@ -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);
|
||||||
|
4
deps/ox/src/ox/oc/read.hpp
vendored
4
deps/ox/src/ox/oc/read.hpp
vendored
@ -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.
|
||||||
*/
|
*/
|
||||||
|
3
deps/ox/src/ox/oc/test/tests.cpp
vendored
3
deps/ox/src/ox/oc/test/tests.cpp
vendored
@ -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;
|
||||||
|
2
deps/ox/src/ox/oc/write.hpp
vendored
2
deps/ox/src/ox/oc/write.hpp
vendored
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user