[ox] Make TypeStore own all type info
This commit is contained in:
parent
440d9c0a46
commit
9c3a46d144
2
deps/ox/src/ox/claw/read.hpp
vendored
2
deps/ox/src/ox/claw/read.hpp
vendored
@ -72,7 +72,7 @@ template<typename T>
|
||||
Result<T> readClaw(const char *buff, std::size_t buffLen) {
|
||||
T val;
|
||||
oxReturnError(readClaw(buff, buffLen, &val));
|
||||
return std::move(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
18
deps/ox/src/ox/mc/test/tests.cpp
vendored
18
deps/ox/src/ox/mc/test/tests.cpp
vendored
@ -16,7 +16,6 @@
|
||||
|
||||
union TestUnion {
|
||||
static constexpr auto TypeName = "TestUnion";
|
||||
static constexpr auto Fields = 3;
|
||||
bool Bool;
|
||||
uint32_t Int = 5;
|
||||
char CString[32];
|
||||
@ -24,7 +23,6 @@ union TestUnion {
|
||||
|
||||
struct TestStructNest {
|
||||
static constexpr auto TypeName = "TestStructNest";
|
||||
static constexpr auto Fields = 3;
|
||||
bool Bool = false;
|
||||
uint32_t Int = 0;
|
||||
ox::BString<32> BString = "";
|
||||
@ -32,7 +30,6 @@ struct TestStructNest {
|
||||
|
||||
struct TestStruct {
|
||||
static constexpr auto TypeName = "TestStruct";
|
||||
static constexpr auto Fields = 16;
|
||||
bool Bool = false;
|
||||
int32_t Int = 0;
|
||||
int32_t Int1 = 0;
|
||||
@ -272,7 +269,7 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
[] {
|
||||
//constexpr size_t descBuffLen = 1024;
|
||||
//uint8_t descBuff[descBuffLen];
|
||||
static constexpr size_t dataBuffLen = 1024;
|
||||
static constexpr size_t dataBuffLen = ox::units::MB;
|
||||
char dataBuff[dataBuffLen];
|
||||
TestStruct testIn, testOut;
|
||||
testIn.Bool = true;
|
||||
@ -286,10 +283,11 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
testIn.Struct.Int = 300;
|
||||
testIn.Struct.BString = "Test String 2";
|
||||
oxAssert(ox::writeMC(dataBuff, dataBuffLen, &testIn), "Data generation failed");
|
||||
auto type = ox::buildTypeDef(&testIn);
|
||||
ox::TypeStore typeStore;
|
||||
auto type = ox::buildTypeDef(&typeStore, &testIn);
|
||||
oxAssert(type.error, "Descriptor write failed");
|
||||
oxReturnError(ox::walkModel<ox::MetalClawReader>(type.value.get(), dataBuff, dataBuffLen,
|
||||
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error {
|
||||
oxReturnError(ox::walkModel<ox::MetalClawReader>(type.value, dataBuff, dataBuffLen,
|
||||
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f, ox::MetalClawReader *rdr) -> ox::Error {
|
||||
//std::cout << f.fieldName.c_str() << '\n';
|
||||
auto fieldName = f.fieldName.c_str();
|
||||
switch (f.type->primitiveType) {
|
||||
@ -360,10 +358,10 @@ std::map<ox::String, ox::Error(*)()> tests = {
|
||||
break;
|
||||
}
|
||||
case ox::PrimitiveType::String: {
|
||||
ox::Vector<char> v(rdr->stringLength(fieldName) + 1);
|
||||
ox::String s;
|
||||
//std::cout << rdr->stringLength() << '\n';
|
||||
oxAssert(rdr->field(fieldName, ox::SerStr(v.data(), v.size())), "Walking model failed.");
|
||||
std::cout << fieldName << ":\t" << "string:\t\t" << v.data() << '\n';
|
||||
oxAssert(rdr->field(fieldName, &s), "Walking model failed.");
|
||||
oxOutf("{}:\tstring:\t\t{}\n", fieldName, s);
|
||||
break;
|
||||
}
|
||||
case ox::PrimitiveType::Struct:
|
||||
|
1
deps/ox/src/ox/model/CMakeLists.txt
vendored
1
deps/ox/src/ox/model/CMakeLists.txt
vendored
@ -30,6 +30,7 @@ install(
|
||||
modelops.hpp
|
||||
typenamecatcher.hpp
|
||||
types.hpp
|
||||
typestore.hpp
|
||||
walk.hpp
|
||||
DESTINATION
|
||||
include/ox/model
|
||||
|
12
deps/ox/src/ox/model/descread.hpp
vendored
12
deps/ox/src/ox/model/descread.hpp
vendored
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "typestore.hpp"
|
||||
#include "desctypes.hpp"
|
||||
|
||||
namespace ox {
|
||||
@ -18,24 +19,25 @@ class TypeDescReader: public ReaderBase {
|
||||
TypeStore m_typeStore;
|
||||
|
||||
public:
|
||||
TypeDescReader(const uint8_t *buff, std::size_t buffLen) noexcept;
|
||||
constexpr TypeDescReader(const uint8_t *buff, std::size_t buffLen) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
const TypeStore &typeStore() const noexcept;
|
||||
constexpr const auto &typeStore() const noexcept;
|
||||
|
||||
};
|
||||
|
||||
template<typename ReaderBase>
|
||||
TypeDescReader<ReaderBase>::TypeDescReader(const uint8_t *buff, std::size_t buffLen) noexcept: ReaderBase(buff, buffLen) {
|
||||
constexpr TypeDescReader<ReaderBase>::TypeDescReader(const uint8_t *buff, std::size_t buffLen) noexcept:
|
||||
ReaderBase(buff, buffLen) {
|
||||
}
|
||||
|
||||
template<typename ReaderBase>
|
||||
const TypeStore &TypeDescReader<ReaderBase>::typeStore() const noexcept {
|
||||
constexpr const auto &TypeDescReader<ReaderBase>::typeStore() const noexcept {
|
||||
return m_typeStore;
|
||||
}
|
||||
|
||||
template<typename ReaderBase, typename T>
|
||||
int readMCDef(const uint8_t *buff, std::size_t buffLen, T *val) noexcept {
|
||||
constexpr int readMCDef(const uint8_t *buff, std::size_t buffLen, T *val) noexcept {
|
||||
TypeDescReader<ReaderBase> reader(buff, buffLen);
|
||||
return model(&reader, val);
|
||||
}
|
||||
|
6
deps/ox/src/ox/model/desctypes.cpp
vendored
6
deps/ox/src/ox/model/desctypes.cpp
vendored
@ -10,10 +10,4 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
DescriptorField::~DescriptorField() {
|
||||
if (ownsType) {
|
||||
safeDelete(type);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
152
deps/ox/src/ox/model/desctypes.hpp
vendored
152
deps/ox/src/ox/model/desctypes.hpp
vendored
@ -11,6 +11,7 @@
|
||||
#include <ox/std/bit.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/hashmap.hpp>
|
||||
#include <ox/std/memory.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/std/vector.hpp>
|
||||
|
||||
@ -19,7 +20,6 @@
|
||||
namespace ox {
|
||||
|
||||
using FieldName = String;
|
||||
using TypeName = String;
|
||||
|
||||
enum class PrimitiveType: uint8_t {
|
||||
UnsignedInteger = 0,
|
||||
@ -34,82 +34,57 @@ enum class PrimitiveType: uint8_t {
|
||||
struct DescriptorField {
|
||||
// order of fields matters
|
||||
|
||||
static constexpr auto TypeName = "net.drinkingtea.ox.DescriptorField";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
|
||||
// only serialize type name if type has already been serialized
|
||||
struct DescriptorType *type = nullptr;
|
||||
// do not serialize type
|
||||
const struct DescriptorType *type = nullptr;
|
||||
String fieldName;
|
||||
int subscriptLevels = 0;
|
||||
|
||||
// do not serialize the following
|
||||
TypeName typeName; // gives reference to type for lookup if type is null
|
||||
bool ownsType = false;
|
||||
String typeName; // gives reference to type for lookup if type is null
|
||||
|
||||
constexpr DescriptorField() noexcept = default;
|
||||
|
||||
/**
|
||||
* Allow for explicit copying.
|
||||
*/
|
||||
constexpr DescriptorField(const DescriptorField &other) noexcept {
|
||||
type = other.type;
|
||||
fieldName = other.fieldName;
|
||||
subscriptLevels = other.subscriptLevels;
|
||||
typeName = other.typeName;
|
||||
ownsType = false; // is copy, only owns type if move
|
||||
constexpr DescriptorField(const DescriptorType *pType, String pFieldName,
|
||||
int pSubscriptLevels, String pTypeName) noexcept:
|
||||
type(pType),
|
||||
fieldName(pFieldName),
|
||||
subscriptLevels(pSubscriptLevels),
|
||||
typeName(pTypeName) {
|
||||
}
|
||||
|
||||
constexpr DescriptorField(DescriptorType *type, const String &fieldName, int subscriptLevels, const TypeName &typeName, bool ownsType) noexcept {
|
||||
this->type = type;
|
||||
this->fieldName = fieldName;
|
||||
this->subscriptLevels = subscriptLevels;
|
||||
this->typeName = typeName;
|
||||
this->ownsType = ownsType;
|
||||
constexpr DescriptorField(const DescriptorField &other) noexcept:
|
||||
type(other.type),
|
||||
fieldName(other.fieldName),
|
||||
subscriptLevels(other.subscriptLevels),
|
||||
typeName(other.typeName) {
|
||||
}
|
||||
|
||||
constexpr DescriptorField(DescriptorField &&other) noexcept {
|
||||
type = other.type;
|
||||
fieldName = other.fieldName;
|
||||
subscriptLevels = other.subscriptLevels;
|
||||
typeName = other.typeName;
|
||||
ownsType = other.ownsType;
|
||||
|
||||
constexpr DescriptorField(DescriptorField &&other) noexcept:
|
||||
type(other.type),
|
||||
fieldName(other.fieldName),
|
||||
subscriptLevels(other.subscriptLevels),
|
||||
typeName(std::move(other.typeName)) {
|
||||
other.type = {};
|
||||
other.fieldName = "";
|
||||
other.subscriptLevels = {};
|
||||
other.typeName = "";
|
||||
other.ownsType = {};
|
||||
}
|
||||
|
||||
~DescriptorField();
|
||||
constexpr ~DescriptorField() noexcept = default;
|
||||
|
||||
const DescriptorField &operator=(const DescriptorField &other) noexcept {
|
||||
type = other.type;
|
||||
fieldName = other.fieldName;
|
||||
subscriptLevels = other.subscriptLevels;
|
||||
typeName = other.typeName;
|
||||
ownsType = other.ownsType;
|
||||
return *this;
|
||||
}
|
||||
constexpr DescriptorField &operator=(const DescriptorField &other) noexcept = delete;
|
||||
|
||||
const DescriptorField &operator=(DescriptorField &&other) noexcept {
|
||||
type = std::move(other.type);
|
||||
other.type = {};
|
||||
fieldName = std::move(other.fieldName);
|
||||
subscriptLevels = std::move(other.subscriptLevels);
|
||||
other.subscriptLevels = {};
|
||||
typeName = std::move(other.typeName);
|
||||
ownsType = std::move(other.ownsType);
|
||||
other.ownsType = {};
|
||||
return *this;
|
||||
}
|
||||
constexpr DescriptorField &operator=(DescriptorField &&other) noexcept = delete;
|
||||
|
||||
};
|
||||
|
||||
using FieldList = Vector<DescriptorField>;
|
||||
|
||||
struct DescriptorType {
|
||||
|
||||
static constexpr auto TypeName = "net.drinkingtea.ox.DescriptorType";
|
||||
static constexpr auto TypeVersion = 1;
|
||||
TypeName typeName = "";
|
||||
|
||||
String typeName;
|
||||
PrimitiveType primitiveType = PrimitiveType::UnsignedInteger;
|
||||
// fieldList only applies to structs
|
||||
FieldList fieldList;
|
||||
@ -118,23 +93,33 @@ struct DescriptorType {
|
||||
int64_t length = 0;
|
||||
bool preloadable = false;
|
||||
|
||||
DescriptorType() = default;
|
||||
constexpr DescriptorType() noexcept = default;
|
||||
|
||||
DescriptorType(const TypeName &tn, PrimitiveType t, int b): typeName(tn), primitiveType(t), length(b) {
|
||||
constexpr explicit DescriptorType(String tn) noexcept: typeName(std::move(tn)) {
|
||||
}
|
||||
|
||||
DescriptorType(const TypeName &tn, PrimitiveType t, const FieldList &fl): typeName(tn), primitiveType(t), fieldList(fl) {
|
||||
constexpr DescriptorType(String tn, PrimitiveType t, int b) noexcept:
|
||||
typeName(std::move(tn)),
|
||||
primitiveType(t),
|
||||
length(b) {
|
||||
}
|
||||
|
||||
constexpr DescriptorType(String tn, PrimitiveType t, FieldList fl) noexcept:
|
||||
typeName(std::move(tn)),
|
||||
primitiveType(t),
|
||||
fieldList(std::move(fl)) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
constexpr Error model(T *io, DescriptorType *type) noexcept {
|
||||
io->template setTypeInfo<T>("net.drinkingtea.ox.DescriptorType", 5);
|
||||
io->template setTypeInfo<DescriptorType>();
|
||||
oxReturnError(io->field("typeName", &type->typeName));
|
||||
auto pt = std::bit_cast<uint8_t>(type->primitiveType);
|
||||
auto pt = static_cast<uint8_t>(type->primitiveType);
|
||||
oxReturnError(io->field("primitiveType", &pt));
|
||||
type->primitiveType = std::bit_cast<PrimitiveType>(pt);
|
||||
type->primitiveType = static_cast<PrimitiveType>(pt);
|
||||
oxReturnError(io->field("fieldList", &type->fieldList));
|
||||
oxReturnError(io->field("length", &type->length));
|
||||
oxReturnError(io->field("preloadable", &type->preloadable));
|
||||
@ -142,47 +127,34 @@ constexpr Error model(T *io, DescriptorType *type) noexcept {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error modelWrite(T *io, DescriptorField *field) noexcept {
|
||||
io->setTypeInfo("ox::DescriptorField", 4);
|
||||
if (field->ownsType) {
|
||||
String empty = "";
|
||||
oxReturnError(io->field("typeName", &empty));
|
||||
oxReturnError(io->field("type", field->type));
|
||||
} else {
|
||||
oxReturnError(io->field("typeName", &field->type->typeName));
|
||||
oxReturnError(io->field("type", static_cast<decltype(field->type)>(nullptr)));
|
||||
}
|
||||
constexpr Error model(T *io, DescriptorField *field) noexcept {
|
||||
io->template setTypeInfo<DescriptorField>(DescriptorField::TypeName, 4);
|
||||
oxReturnError(io->field("typeName", &field->typeName));
|
||||
oxReturnError(io->field("fieldName", &field->fieldName));
|
||||
oxReturnError(io->field("subscriptLevels", &field->subscriptLevels));
|
||||
// defaultValue is unused now, but leave placeholder for backwards compatibility
|
||||
int DefaultValue = 0;
|
||||
oxReturnError(io->field("defaultValue", &DefaultValue));
|
||||
int defaultValue = 0;
|
||||
oxReturnError(io->field("defaultValue", &defaultValue));
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
template<typename ReaderBase>
|
||||
class TypeDescReader;
|
||||
|
||||
template<typename T>
|
||||
Error modelRead(T *io, DescriptorField *field) noexcept {
|
||||
auto &typeStore = io->typeStore();
|
||||
io->setTypeInfo("ox::DescriptorField", 4);
|
||||
constexpr Error model(TypeDescReader<T> *io, DescriptorField *field) noexcept {
|
||||
io->template setTypeInfo<DescriptorField>(DescriptorField::TypeName, 4);
|
||||
oxReturnError(io->field("typeName", &field->typeName));
|
||||
if (field->typeName == "") {
|
||||
field->ownsType = true;
|
||||
if (field->type == nullptr) {
|
||||
field->type = new DescriptorType;
|
||||
}
|
||||
oxReturnError(io->field("type", field->type));
|
||||
typeStore[field->type->typeName] = field->type;
|
||||
} else {
|
||||
// should be empty, so discard
|
||||
DescriptorType t;
|
||||
oxReturnError(io->field("type", &t));
|
||||
field->type = typeStore[field->typeName];
|
||||
}
|
||||
auto &typeStore = io->typeStore();
|
||||
auto &[type, err] = typeStore->at(field->typeName).value;
|
||||
oxReturnError(err);
|
||||
field->type = type.get();
|
||||
oxReturnError(io->field("fieldName", &field->fieldName));
|
||||
oxReturnError(io->field("subscriptLevels", &field->subscriptLevels));
|
||||
// defaultValue is unused now, but placeholder for backwards compatibility
|
||||
oxReturnError(io->field("defaultValue", nullptr));
|
||||
int defaultValue = 0;
|
||||
oxReturnError(io->field("defaultValue", &defaultValue));
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
using TypeStore = HashMap<String, DescriptorType*>;
|
||||
|
||||
}
|
||||
|
106
deps/ox/src/ox/model/descwrite.cpp
vendored
106
deps/ox/src/ox/model/descwrite.cpp
vendored
@ -47,116 +47,102 @@ static_assert([] {
|
||||
return detail::indirectionLevels(i) == 1;
|
||||
}(), "indirectionLevels broken: indirectionLevels(int[])");
|
||||
|
||||
TypeDescWriter::TypeDescWriter(TypeStore *typeStore) noexcept {
|
||||
if (!typeStore) {
|
||||
m_typeStoreOwnerRef = new TypeStore;
|
||||
typeStore = m_typeStoreOwnerRef;
|
||||
}
|
||||
m_typeStore = typeStore;
|
||||
}
|
||||
|
||||
TypeDescWriter::~TypeDescWriter() noexcept {
|
||||
// does not own it's elements
|
||||
safeDelete(m_typeStoreOwnerRef);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(int8_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:int8_t";
|
||||
const DescriptorType *TypeDescWriter::type(int8_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:int8_t";
|
||||
constexpr auto PT = PrimitiveType::SignedInteger;
|
||||
constexpr auto Bytes = 1;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(int16_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:int16_t";
|
||||
const DescriptorType *TypeDescWriter::type(int16_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:int16_t";
|
||||
constexpr auto PT = PrimitiveType::SignedInteger;
|
||||
constexpr auto Bytes = 2;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(int32_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:int32_t";
|
||||
const DescriptorType *TypeDescWriter::type(int32_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:int32_t";
|
||||
constexpr auto PT = PrimitiveType::SignedInteger;
|
||||
constexpr auto Bytes = 4;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(int64_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:int64_t";
|
||||
const DescriptorType *TypeDescWriter::type(int64_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:int64_t";
|
||||
constexpr auto PT = PrimitiveType::SignedInteger;
|
||||
constexpr auto Bytes = 8;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(uint8_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:uint8_t";
|
||||
const DescriptorType *TypeDescWriter::type(uint8_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:uint8_t";
|
||||
constexpr auto PT = PrimitiveType::UnsignedInteger;
|
||||
constexpr auto Bytes = 1;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(uint16_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:uint16_t";
|
||||
const DescriptorType *TypeDescWriter::type(uint16_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:uint16_t";
|
||||
constexpr auto PT = PrimitiveType::UnsignedInteger;
|
||||
constexpr auto Bytes = 2;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(uint32_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:uint32_t";
|
||||
const DescriptorType *TypeDescWriter::type(uint32_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:uint32_t";
|
||||
constexpr auto PT = PrimitiveType::UnsignedInteger;
|
||||
constexpr auto Bytes = 4;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(uint64_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:uint64_t";
|
||||
const DescriptorType *TypeDescWriter::type(uint64_t*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:uint64_t";
|
||||
constexpr auto PT = PrimitiveType::UnsignedInteger;
|
||||
constexpr auto Bytes = 8;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(char*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:string";
|
||||
const DescriptorType *TypeDescWriter::type(char*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:string";
|
||||
constexpr auto PT = PrimitiveType::String;
|
||||
return getType(TypeName, PT, 0, alreadyExisted);
|
||||
return getType(String, PT, 0, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(SerStr, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:string";
|
||||
const DescriptorType *TypeDescWriter::type(SerStr, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:string";
|
||||
constexpr auto PT = PrimitiveType::String;
|
||||
return getType(TypeName, PT, 0, alreadyExisted);
|
||||
return getType(String, PT, 0, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(String*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:string";
|
||||
const DescriptorType *TypeDescWriter::type(String*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:string";
|
||||
constexpr auto PT = PrimitiveType::String;
|
||||
return getType(TypeName, PT, 0, alreadyExisted);
|
||||
return getType(String, PT, 0, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::type(bool*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto TypeName = "B:bool";
|
||||
const DescriptorType *TypeDescWriter::type(bool*, bool *alreadyExisted) noexcept {
|
||||
constexpr auto String = "B:bool";
|
||||
constexpr auto PT = PrimitiveType::Bool;
|
||||
constexpr auto Bytes = 0;
|
||||
return getType(TypeName, PT, Bytes, alreadyExisted);
|
||||
return getType(String, PT, Bytes, alreadyExisted);
|
||||
}
|
||||
|
||||
DescriptorType *TypeDescWriter::getType(const TypeName &tn, PrimitiveType pt, int b, bool *alreadyExisted) noexcept {
|
||||
if (m_typeStore->contains(tn)) {
|
||||
const DescriptorType *TypeDescWriter::getType(const String &tn, PrimitiveType pt, int b, bool *alreadyExisted) noexcept {
|
||||
auto t = m_typeStore->get(tn);
|
||||
if (!t.error) {
|
||||
*alreadyExisted = true;
|
||||
auto type = m_typeStore->operator[](tn);
|
||||
auto type = t.value;
|
||||
oxAssert(type != nullptr, "TypeDescWriter::getType returning null DescriptorType");
|
||||
return type;
|
||||
} else {
|
||||
*alreadyExisted = false;
|
||||
auto &t = m_typeStore->operator[](tn);
|
||||
if (!t) {
|
||||
t = new DescriptorType;
|
||||
}
|
||||
t->typeName = tn;
|
||||
t->primitiveType = pt;
|
||||
t->length = b;
|
||||
return t;
|
||||
auto dt = ox::make_unique<DescriptorType>(tn);
|
||||
dt->primitiveType = pt;
|
||||
dt->length = b;
|
||||
const auto out = dt.get();
|
||||
m_typeStore->set(tn, std::move(dt));
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
|
114
deps/ox/src/ox/model/descwrite.hpp
vendored
114
deps/ox/src/ox/model/descwrite.hpp
vendored
@ -22,6 +22,7 @@
|
||||
#include "optype.hpp"
|
||||
#include "typenamecatcher.hpp"
|
||||
#include "types.hpp"
|
||||
#include "typestore.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
@ -42,28 +43,26 @@ static constexpr int indirectionLevels(T *t) noexcept {
|
||||
class TypeDescWriter {
|
||||
|
||||
private:
|
||||
TypeStore *m_typeStoreOwnerRef = nullptr;
|
||||
TypeStore *m_typeStore = nullptr;
|
||||
DescriptorType *m_type = nullptr;
|
||||
|
||||
public:
|
||||
explicit TypeDescWriter(TypeStore *typeStore = nullptr) noexcept;
|
||||
|
||||
~TypeDescWriter() noexcept;
|
||||
explicit constexpr TypeDescWriter(TypeStore *typeStore = nullptr) noexcept;
|
||||
|
||||
template<typename T>
|
||||
Error field(const char *name, T *val, std::size_t valLen) noexcept;
|
||||
constexpr Error field(const char *name, T *val, std::size_t valLen) noexcept;
|
||||
|
||||
template<typename T>
|
||||
Error field(const char *name, T val) noexcept;
|
||||
constexpr Error field(const char *name, T val) noexcept;
|
||||
|
||||
template<typename T>
|
||||
Error field(const char *name, T *val) noexcept;
|
||||
constexpr Error field(const char *name, T *val) noexcept;
|
||||
|
||||
template<typename T = std::nullptr_t>
|
||||
void setTypeInfo(const char *name = T::TypeName, int fields = countFields<T>()) noexcept;
|
||||
constexpr void setTypeInfo(const char *name = T::TypeName, int fields = countFields<T>()) noexcept;
|
||||
|
||||
[[nodiscard]] DescriptorType *definition() noexcept {
|
||||
[[nodiscard]]
|
||||
constexpr DescriptorType *definition() noexcept {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
@ -72,45 +71,48 @@ class TypeDescWriter {
|
||||
}
|
||||
|
||||
private:
|
||||
DescriptorType *type(int8_t *val, bool *alreadyExisted) noexcept;
|
||||
DescriptorType *type(int16_t *val, bool *alreadyExisted) noexcept;
|
||||
DescriptorType *type(int32_t *val, bool *alreadyExisted) noexcept;
|
||||
DescriptorType *type(int64_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(int8_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(int16_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(int32_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(int64_t *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
DescriptorType *type(uint8_t *val, bool *alreadyExisted) noexcept;
|
||||
DescriptorType *type(uint16_t *val, bool *alreadyExisted) noexcept;
|
||||
DescriptorType *type(uint32_t *val, bool *alreadyExisted) noexcept;
|
||||
DescriptorType *type(uint64_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(uint8_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(uint16_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(uint32_t *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(uint64_t *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
DescriptorType *type(bool *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(bool *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
DescriptorType *type(char *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(char *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
DescriptorType *type(SerStr val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(SerStr val, bool *alreadyExisted) noexcept;
|
||||
|
||||
DescriptorType *type(String *val, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *type(String *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
template<std::size_t sz>
|
||||
DescriptorType *type(BString<sz> *val, bool *alreadyExisted) noexcept;
|
||||
constexpr const DescriptorType *type(BString<sz> *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
template<typename T>
|
||||
DescriptorType *type(T *val, bool *alreadyExisted) noexcept;
|
||||
constexpr const DescriptorType *type(T *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
template<typename T>
|
||||
DescriptorType *type(Vector<T> *val, bool *alreadyExisted) noexcept;
|
||||
constexpr const DescriptorType *type(Vector<T> *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
template<typename T>
|
||||
DescriptorType *type(HashMap<String, T> *val, bool *alreadyExisted) noexcept;
|
||||
constexpr const DescriptorType *type(HashMap<String, T> *val, bool *alreadyExisted) noexcept;
|
||||
|
||||
template<typename U>
|
||||
DescriptorType *type(UnionView<U> val, bool *alreadyExisted) noexcept;
|
||||
constexpr const DescriptorType *type(UnionView<U> val, bool *alreadyExisted) noexcept;
|
||||
|
||||
DescriptorType *getType(const TypeName &tn, PrimitiveType t, int b, bool *alreadyExisted) noexcept;
|
||||
const DescriptorType *getType(const String &tn, PrimitiveType t, int b, bool *alreadyExisted) noexcept;
|
||||
};
|
||||
|
||||
constexpr TypeDescWriter::TypeDescWriter(TypeStore *typeStore) noexcept: m_typeStore(typeStore) {
|
||||
}
|
||||
|
||||
// array handler
|
||||
template<typename T>
|
||||
Error TypeDescWriter::field(const char *name, T *val, std::size_t) noexcept {
|
||||
constexpr Error TypeDescWriter::field(const char *name, T *val, std::size_t) noexcept {
|
||||
if (m_type) {
|
||||
constexpr typename remove_pointer<decltype(val)>::type *p = nullptr;
|
||||
bool alreadyExisted = false;
|
||||
@ -119,47 +121,47 @@ Error TypeDescWriter::field(const char *name, T *val, std::size_t) noexcept {
|
||||
if (t == nullptr) {
|
||||
type(p, &alreadyExisted);
|
||||
}
|
||||
m_type->fieldList.emplace_back(t, name, detail::indirectionLevels(val), alreadyExisted ? t->typeName : "", !alreadyExisted);
|
||||
m_type->fieldList.emplace_back(t, name, detail::indirectionLevels(val), alreadyExisted ? t->typeName : "");
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error TypeDescWriter::field(const char *name, T val) noexcept {
|
||||
constexpr Error TypeDescWriter::field(const char *name, T val) noexcept {
|
||||
if (m_type) {
|
||||
bool alreadyExisted = false;
|
||||
const auto t = type(val, &alreadyExisted);
|
||||
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 : "", !alreadyExisted);
|
||||
m_type->fieldList.emplace_back(t, name, 0, alreadyExisted ? t->typeName : "");
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Error TypeDescWriter::field(const char *name, T *val) noexcept {
|
||||
constexpr Error TypeDescWriter::field(const char *name, T *val) noexcept {
|
||||
if (m_type) {
|
||||
bool alreadyExisted = false;
|
||||
const auto t = type(val, &alreadyExisted);
|
||||
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 : "", !alreadyExisted);
|
||||
m_type->fieldList.emplace_back(t, name, 0, t->typeName);
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
DescriptorType *TypeDescWriter::type(BString<sz> *val, bool *alreadyExisted) noexcept {
|
||||
constexpr const DescriptorType *TypeDescWriter::type(BString<sz> *val, bool *alreadyExisted) noexcept {
|
||||
return type(SerStr(val), alreadyExisted);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) noexcept {
|
||||
const auto name = getModelTypeName(val);
|
||||
if (m_typeStore->contains(name)) {
|
||||
constexpr const DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) noexcept {
|
||||
auto [t, err] = m_typeStore->template get<T>();
|
||||
if (!err) {
|
||||
*alreadyExisted = true;
|
||||
return m_typeStore->operator[](name);
|
||||
return t;
|
||||
} else {
|
||||
TypeDescWriter dw(m_typeStore);
|
||||
oxLogError(model(&dw, val));
|
||||
@ -169,29 +171,24 @@ DescriptorType *TypeDescWriter::type(T *val, bool *alreadyExisted) noexcept {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
DescriptorType *TypeDescWriter::type(Vector<T> *val, bool *alreadyExisted) noexcept {
|
||||
constexpr const DescriptorType *TypeDescWriter::type(Vector<T> *val, bool *alreadyExisted) noexcept {
|
||||
return type(val->data(), alreadyExisted);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
DescriptorType *TypeDescWriter::type(HashMap<String, T>*, bool *alreadyExisted) noexcept {
|
||||
constexpr const DescriptorType *TypeDescWriter::type(HashMap<String, T>*, bool *alreadyExisted) noexcept {
|
||||
return type(static_cast<T*>(nullptr), alreadyExisted);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
DescriptorType *TypeDescWriter::type(UnionView<U> val, bool *alreadyExisted) noexcept {
|
||||
constexpr const DescriptorType *TypeDescWriter::type(UnionView<U> val, bool *alreadyExisted) noexcept {
|
||||
return type(val.get(), alreadyExisted);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void TypeDescWriter::setTypeInfo(const char *name, int) noexcept {
|
||||
auto &t = m_typeStore->operator[](name);
|
||||
if (!t) {
|
||||
t = new DescriptorType;
|
||||
}
|
||||
m_type = t;
|
||||
m_type->typeName = name;
|
||||
if (is_union_v<T>) {
|
||||
constexpr void TypeDescWriter::setTypeInfo(const char *name, int) noexcept {
|
||||
m_type = m_typeStore->getInit(name);
|
||||
if constexpr(is_union_v<T>) {
|
||||
m_type->primitiveType = PrimitiveType::Union;
|
||||
} else {
|
||||
m_type->primitiveType = PrimitiveType::Struct;
|
||||
@ -200,21 +197,16 @@ void TypeDescWriter::setTypeInfo(const char *name, int) noexcept {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Result<UniquePtr<DescriptorType>> buildTypeDef(T *val) noexcept {
|
||||
TypeDescWriter writer;
|
||||
Result<DescriptorType*> buildTypeDef(TypeStore *typeStore, T *val) noexcept {
|
||||
TypeDescWriter writer(typeStore);
|
||||
oxReturnError(model(&writer, val));
|
||||
return UniquePtr<DescriptorType>{writer.definition()};
|
||||
return writer.definition();
|
||||
}
|
||||
|
||||
Error writeTypeDef(uint8_t *buff, std::size_t buffLen, auto *val, std::size_t *sizeOut = nullptr) noexcept {
|
||||
oxRequire(def, buildTypeDef(val));
|
||||
return writeType(buff, buffLen, def.get(), sizeOut);
|
||||
}
|
||||
|
||||
Result<Buffer> writeTypeDef(auto *val) noexcept {
|
||||
Buffer buff(units::MB);
|
||||
oxReturnError(writeTypeDef(buff.data(), buff.size(), val));
|
||||
return std::move(buff);
|
||||
auto writeTypeDefOC(auto *val) noexcept {
|
||||
TypeStore typeStore;
|
||||
oxRequire(def, buildTypeDef(&typeStore, val));
|
||||
return writeOC(def.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
9
deps/ox/src/ox/model/fieldcounter.hpp
vendored
9
deps/ox/src/ox/model/fieldcounter.hpp
vendored
@ -49,10 +49,19 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
1
deps/ox/src/ox/model/model.hpp
vendored
1
deps/ox/src/ox/model/model.hpp
vendored
@ -16,4 +16,5 @@
|
||||
#include "modelops.hpp"
|
||||
#include "typenamecatcher.hpp"
|
||||
#include "types.hpp"
|
||||
#include "typestore.hpp"
|
||||
#include "walk.hpp"
|
||||
|
9
deps/ox/src/ox/model/modelops.hpp
vendored
9
deps/ox/src/ox/model/modelops.hpp
vendored
@ -13,6 +13,7 @@
|
||||
#include <ox/std/types.hpp>
|
||||
#include <ox/std/utility.hpp>
|
||||
|
||||
#include "fieldcounter.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
namespace ox {
|
||||
@ -51,7 +52,7 @@ class MemberList {
|
||||
}
|
||||
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) noexcept {
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = countFields<T>()) noexcept {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -171,7 +172,7 @@ class Mover {
|
||||
}
|
||||
|
||||
template<typename T = void>
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = T::Fields) noexcept {
|
||||
constexpr void setTypeInfo(const char* = T::TypeName, int = countFields<T>()) noexcept {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -261,7 +262,7 @@ class Equals {
|
||||
|
||||
template<typename T>
|
||||
constexpr void moveModel(T *dst, T *src) noexcept {
|
||||
constexpr auto size = T::Fields;
|
||||
constexpr auto size = countFields<T>();
|
||||
detail::MemberList<size> dstFields;
|
||||
detail::Mover<size> mover(&dstFields);
|
||||
oxIgnoreError(model(&dstFields, dst));
|
||||
@ -270,7 +271,7 @@ constexpr void moveModel(T *dst, T *src) noexcept {
|
||||
|
||||
template<typename T>
|
||||
constexpr void copyModel(T *dst, const T *src) noexcept {
|
||||
constexpr auto size = T::Fields;
|
||||
constexpr auto size = countFields<T>();
|
||||
detail::MemberList<size> dstFields;
|
||||
detail::Copier<size> copier(&dstFields);
|
||||
oxIgnoreError(model(&dstFields, dst));
|
||||
|
1
deps/ox/src/ox/model/typenamecatcher.hpp
vendored
1
deps/ox/src/ox/model/typenamecatcher.hpp
vendored
@ -129,7 +129,6 @@ constexpr Str getModelTypeName(T *val) noexcept {
|
||||
template<typename T>
|
||||
consteval auto requireModelTypeName() noexcept {
|
||||
constexpr auto name = getModelTypeName<T>();
|
||||
static_assert(ox_strcmp(name, "") != 0, "TypeName is required");
|
||||
return name;
|
||||
}
|
||||
|
||||
|
6
deps/ox/src/ox/model/types.hpp
vendored
6
deps/ox/src/ox/model/types.hpp
vendored
@ -76,6 +76,12 @@ class SerStr {
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
explicit constexpr SerStr(char *str, char **tgt, int cap = -1) noexcept {
|
||||
m_tgt = tgt;
|
||||
m_str = str;
|
||||
m_cap = cap;
|
||||
}
|
||||
|
||||
template<std::size_t cap>
|
||||
explicit constexpr SerStr(char (&str)[cap]) noexcept {
|
||||
m_str = str;
|
||||
|
96
deps/ox/src/ox/model/typestore.hpp
vendored
Normal file
96
deps/ox/src/ox/model/typestore.hpp
vendored
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2015 - 2022 gary@drinkingtea.net
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/hashmap.hpp>
|
||||
#include <ox/std/memory.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
|
||||
#include "typenamecatcher.hpp"
|
||||
#include "desctypes.hpp"
|
||||
|
||||
namespace ox {
|
||||
|
||||
class TypeStore {
|
||||
private:
|
||||
HashMap<String, UniquePtr<DescriptorType>> m_cache;
|
||||
|
||||
public:
|
||||
constexpr TypeStore() noexcept = default;
|
||||
|
||||
constexpr virtual ~TypeStore() noexcept = default;
|
||||
|
||||
constexpr Result<DescriptorType*> get(const auto &name) const noexcept {
|
||||
oxRequire(out, m_cache.at(name));
|
||||
return out->get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Result<DescriptorType*> get() const noexcept {
|
||||
constexpr auto name = requireModelTypeName<T>();
|
||||
oxRequire(out, m_cache.at(name));
|
||||
return out->get();
|
||||
}
|
||||
|
||||
constexpr DescriptorType *getInit(const auto &name) noexcept {
|
||||
auto [out, err] = m_cache.at(name);
|
||||
if (err) {
|
||||
auto &out = m_cache[name];
|
||||
out = ox::make_unique<DescriptorType>(name);
|
||||
return out.get();
|
||||
}
|
||||
return out->get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr DescriptorType *getInit() noexcept {
|
||||
constexpr auto name = requireModelTypeName<T>();
|
||||
return getInit(name);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr Result<DescriptorType*> getLoad() noexcept {
|
||||
constexpr auto nameCstr = requireModelTypeName<T>();
|
||||
const String name = nameCstr;
|
||||
auto [val, err] = m_cache.at(name);
|
||||
if (err) {
|
||||
oxRequireM(dt, loadDescriptor(name));
|
||||
auto &out = m_cache[name];
|
||||
out = std::move(dt);
|
||||
return out.get();
|
||||
}
|
||||
return val->get();
|
||||
}
|
||||
|
||||
constexpr void set(const String &name, UniquePtr<DescriptorType> dt) noexcept {
|
||||
m_cache[name] = std::move(dt);
|
||||
}
|
||||
|
||||
constexpr void set(const String &name, DescriptorType *dt) noexcept {
|
||||
m_cache[name] = UniquePtr<DescriptorType>(dt);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto typeList() const noexcept {
|
||||
auto keys = m_cache.keys();
|
||||
ox::Vector<DescriptorType*> descs;
|
||||
for (const auto &k : keys) {
|
||||
descs.emplace_back(m_cache.at(k).value->get());
|
||||
}
|
||||
return descs;
|
||||
}
|
||||
|
||||
protected:
|
||||
constexpr virtual Result<UniquePtr<DescriptorType>> loadDescriptor(const ox::String&) noexcept {
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
2
deps/ox/src/ox/model/walk.hpp
vendored
2
deps/ox/src/ox/model/walk.hpp
vendored
@ -23,7 +23,7 @@ class DataWalker {
|
||||
Vector<const DescriptorType*> m_typeStack;
|
||||
T m_fieldHandler;
|
||||
Vector<FieldName> m_path;
|
||||
Vector<TypeName> m_typePath;
|
||||
Vector<String> m_typePath;
|
||||
|
||||
public:
|
||||
DataWalker(DescriptorType *type, T fieldHandler) noexcept;
|
||||
|
19
deps/ox/src/ox/oc/test/tests.cpp
vendored
19
deps/ox/src/ox/oc/test/tests.cpp
vendored
@ -16,7 +16,6 @@
|
||||
|
||||
union TestUnion {
|
||||
static constexpr auto TypeName = "TestUnion";
|
||||
static constexpr auto Fields = 3;
|
||||
bool Bool;
|
||||
uint32_t Int = 5;
|
||||
char String[32];
|
||||
@ -24,7 +23,6 @@ union TestUnion {
|
||||
|
||||
struct TestStructNest {
|
||||
static constexpr auto TypeName = "TestStructNest";
|
||||
static constexpr auto Fields = 3;
|
||||
bool Bool = false;
|
||||
uint32_t Int = 0;
|
||||
ox::BString<32> String = "";
|
||||
@ -32,7 +30,6 @@ struct TestStructNest {
|
||||
|
||||
struct TestStruct {
|
||||
static constexpr auto TypeName = "TestStruct";
|
||||
static constexpr auto Fields = 17;
|
||||
bool Bool = false;
|
||||
int32_t Int = 0;
|
||||
int32_t Int1 = 0;
|
||||
@ -44,7 +41,6 @@ struct TestStruct {
|
||||
int32_t Int7 = 0;
|
||||
int32_t Int8 = 0;
|
||||
TestUnion Union;
|
||||
char *CString = nullptr;
|
||||
ox::BString<32> String = "";
|
||||
uint32_t List[4] = {0, 0, 0, 0};
|
||||
ox::HashMap<ox::String, int> Map;
|
||||
@ -55,8 +51,7 @@ struct TestStruct {
|
||||
|
||||
TestStruct(TestStruct &&other) noexcept;
|
||||
|
||||
~TestStruct() noexcept {
|
||||
delete[] CString;
|
||||
constexpr ~TestStruct() noexcept {
|
||||
}
|
||||
|
||||
constexpr TestStruct &operator=(TestStruct&&) noexcept;
|
||||
@ -95,7 +90,6 @@ constexpr ox::Error model(T *io, TestStruct *obj) noexcept {
|
||||
oxReturnError(io->field("Int7", &obj->Int7));
|
||||
oxReturnError(io->field("Int8", &obj->Int8));
|
||||
oxReturnError(io->field("Union", ox::UnionView{&obj->Union, 1}));
|
||||
oxReturnError(io->field("CString", ox::SerStr(&obj->CString)));
|
||||
oxReturnError(io->field("String", &obj->String));
|
||||
oxReturnError(io->field("List", obj->List, 4));
|
||||
oxReturnError(io->field("Map", &obj->Map));
|
||||
@ -132,8 +126,6 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
testIn.Int = 42;
|
||||
testIn.Union.Int = 52;
|
||||
testIn.String = "Test String 1";
|
||||
testIn.CString = new char[ox_strlen("c-string") + 1];
|
||||
ox_strcpy(testIn.CString, "c-string");
|
||||
testIn.List[0] = 1;
|
||||
testIn.List[1] = 2;
|
||||
testIn.List[2] = 3;
|
||||
@ -160,7 +152,6 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
oxAssert(testIn.Int6 == testOut.Int6, "Int6 value mismatch");
|
||||
oxAssert(testIn.Int7 == testOut.Int7, "Int7 value mismatch");
|
||||
oxAssert(testIn.Int8 == testOut.Int8, "Int8 value mismatch");
|
||||
oxAssert(ox_strcmp(testIn.CString, testOut.CString) == 0, "CString value mismatch");
|
||||
oxAssert(testIn.Union.Int == testOut.Union.Int, "Union.Int value mismatch");
|
||||
oxAssert(testIn.String == testOut.String, "String value mismatch");
|
||||
oxAssert(testIn.List[0] == testOut.List[0], "List[0] value mismatch");
|
||||
@ -197,10 +188,12 @@ const std::map<std::string_view, ox::Error(*)()> tests = {
|
||||
|
||||
auto [oc, ocErr] = ox::writeOC(&testIn);
|
||||
oxAssert(ocErr, "Data generation failed");
|
||||
auto type = ox::buildTypeDef(&testIn);
|
||||
ox::TypeStore typeStore;
|
||||
auto type = ox::buildTypeDef(&typeStore, &testIn);
|
||||
oxAssert(type.error, "Descriptor write failed");
|
||||
oxReturnError(ox::walkModel<ox::OrganicClawReader>(type.value.get(), oc.data(), oc.size(),
|
||||
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::TypeName>&, const ox::DescriptorField &f, ox::OrganicClawReader *rdr) -> ox::Error {
|
||||
oxReturnError(ox::walkModel<ox::OrganicClawReader>(type.value, oc.data(), oc.size(),
|
||||
[](const ox::Vector<ox::FieldName>&, const ox::Vector<ox::String>&, const ox::DescriptorField &f,
|
||||
ox::OrganicClawReader *rdr) -> ox::Error {
|
||||
auto fieldName = f.fieldName.c_str();
|
||||
switch (f.type->primitiveType) {
|
||||
case ox::PrimitiveType::UnsignedInteger:
|
||||
|
4
deps/ox/src/ox/std/assert.hpp
vendored
4
deps/ox/src/ox/std/assert.hpp
vendored
@ -36,7 +36,7 @@ constexpr void assertFunc(const char *file, int line, bool pass, [[maybe_unused]
|
||||
if (!pass) {
|
||||
if (!std::is_constant_evaluated()) {
|
||||
#ifdef OX_USE_STDLIB
|
||||
oxErrf("\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
||||
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
||||
printStackTrace(2);
|
||||
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
||||
std::abort();
|
||||
@ -53,7 +53,7 @@ constexpr void assertFunc(const char *file, int line, const Error &err, const ch
|
||||
if (err) {
|
||||
if (!std::is_constant_evaluated()) {
|
||||
#if defined(OX_USE_STDLIB)
|
||||
oxErrf("\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
|
||||
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
|
||||
if (err.msg) {
|
||||
oxErrf("\tError Message:\t{}\n", err.msg);
|
||||
}
|
||||
|
4
deps/ox/src/ox/std/error.hpp
vendored
4
deps/ox/src/ox/std/error.hpp
vendored
@ -135,6 +135,10 @@ struct [[nodiscard]] Result {
|
||||
constexpr Result(const Result<U> &other) noexcept: value(other.value), error(other.error) {
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
constexpr Result(const Result<U> &&other) noexcept: value(std::move(other.value)), error(std::move(other.error)) {
|
||||
}
|
||||
|
||||
constexpr Result(const Error &error) noexcept: error(error) {
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user