diff --git a/deps/ox/src/ox/mc/deftypes.hpp b/deps/ox/src/ox/mc/deftypes.hpp index d0ede925..2298314f 100644 --- a/deps/ox/src/ox/mc/deftypes.hpp +++ b/deps/ox/src/ox/mc/deftypes.hpp @@ -29,10 +29,15 @@ enum class PrimitiveType: uint8_t { using FieldName = String; struct Field { + // order of fields matters + // only serialize type name if type has already been serialized const struct Type *type = nullptr; FieldName fieldName; int subscriptLevels = 0; + + // do not serialize the following + bool serializeType = false; }; using TypeName = String; @@ -61,11 +66,10 @@ template int ioOp(T *io, Field *field) { int32_t err = 0; io->setTypeInfo("ox::mc::Field", 5); - if (field->type) { - err |= io->op("typeName", &field->type->typeName); + if (field->serializeType) { + err |= io->op("typeName", ""); err |= io->op("type", &field->type); } else { - // TODO: lookup type err |= io->op("typeName", &field->type->typeName); err |= io->op("type", static_casttype)>(nullptr)); } diff --git a/deps/ox/src/ox/mc/defwriter.cpp b/deps/ox/src/ox/mc/defwriter.cpp index 8e26b049..c7ddb0c5 100644 --- a/deps/ox/src/ox/mc/defwriter.cpp +++ b/deps/ox/src/ox/mc/defwriter.cpp @@ -26,67 +26,67 @@ MetalClawDefWriter::~MetalClawDefWriter() { } } -constexpr mc::Type *MetalClawDefWriter::type(int8_t*) { +constexpr mc::Type *MetalClawDefWriter::type(int8_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:int8_t"; constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto Bytes = 8; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(int16_t*) { +constexpr mc::Type *MetalClawDefWriter::type(int16_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:int16_t"; constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto Bytes = 16; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(int32_t*) { +constexpr mc::Type *MetalClawDefWriter::type(int32_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:int32_t"; constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto Bytes = 32; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(int64_t*) { +constexpr mc::Type *MetalClawDefWriter::type(int64_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:int64_t"; constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto Bytes = 64; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(uint8_t*) { +constexpr mc::Type *MetalClawDefWriter::type(uint8_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:uint8_t"; constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto Bytes = 8; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(uint16_t*) { +constexpr mc::Type *MetalClawDefWriter::type(uint16_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:uint16_t"; constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto Bytes = 16; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(uint32_t*) { +constexpr mc::Type *MetalClawDefWriter::type(uint32_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:uint32_t"; constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto Bytes = 32; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(uint64_t*) { +constexpr mc::Type *MetalClawDefWriter::type(uint64_t*, bool *alreadyExisted) { constexpr auto TypeName = "B:uint64_t"; constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto Bytes = 64; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::type(bool*) { +constexpr mc::Type *MetalClawDefWriter::type(bool*, bool *alreadyExisted) { constexpr auto TypeName = "B:bool"; constexpr auto PT = mc::PrimitiveType::Bool; constexpr auto Bytes = 0; - return getPrimitive(TypeName, PT, Bytes); + return getPrimitive(TypeName, PT, Bytes, alreadyExisted); } constexpr void MetalClawDefWriter::setTypeInfo(const char *name, int) { @@ -95,16 +95,18 @@ constexpr void MetalClawDefWriter::setTypeInfo(const char *name, int) { m_type->primitiveType = mc::PrimitiveType::Struct; } -constexpr mc::Type *MetalClawDefWriter::type(const char*) { +constexpr mc::Type *MetalClawDefWriter::type(const char*, bool *alreadyExisted) { constexpr auto TypeName = "B:string"; constexpr auto PT = mc::PrimitiveType::String; - return getPrimitive(TypeName, PT); + return getPrimitive(TypeName, PT, 0, alreadyExisted); } -constexpr mc::Type *MetalClawDefWriter::getPrimitive(mc::TypeName tn, mc::PrimitiveType pt, int b) { +constexpr mc::Type *MetalClawDefWriter::getPrimitive(mc::TypeName tn, mc::PrimitiveType pt, int b, bool *alreadyExisted) { if (m_typeStore->contains(tn)) { + *alreadyExisted = true; return &m_typeStore->at(tn); } else { + *alreadyExisted = false; auto t = &m_typeStore->at(tn); t->typeName = tn; t->primitiveType = pt; diff --git a/deps/ox/src/ox/mc/defwriter.hpp b/deps/ox/src/ox/mc/defwriter.hpp index 894d68e3..58330328 100644 --- a/deps/ox/src/ox/mc/defwriter.hpp +++ b/deps/ox/src/ox/mc/defwriter.hpp @@ -52,6 +52,8 @@ class MetalClawDefWriter { mc::TypeStore *m_typeStoreOwnerRef = nullptr; mc::TypeStore *m_typeStore = nullptr; mc::Type *m_type = nullptr; + // indicates whether or not m_type already existed in the TypeStore + bool m_typeAlreayExisted = false; public: explicit MetalClawDefWriter(mc::TypeStore *typeStore = nullptr); @@ -77,27 +79,27 @@ class MetalClawDefWriter { } private: - constexpr mc::Type *type(int8_t *val); - constexpr mc::Type *type(int16_t *val); - constexpr mc::Type *type(int32_t *val); - constexpr mc::Type *type(int64_t *val); + constexpr mc::Type *type(int8_t *val, bool *alreadyExisted); + constexpr mc::Type *type(int16_t *val, bool *alreadyExisted); + constexpr mc::Type *type(int32_t *val, bool *alreadyExisted); + constexpr mc::Type *type(int64_t *val, bool *alreadyExisted); - constexpr mc::Type *type(uint8_t *val); - constexpr mc::Type *type(uint16_t *val); - constexpr mc::Type *type(uint32_t *val); - constexpr mc::Type *type(uint64_t *val); + constexpr mc::Type *type(uint8_t *val, bool *alreadyExisted); + constexpr mc::Type *type(uint16_t *val, bool *alreadyExisted); + constexpr mc::Type *type(uint32_t *val, bool *alreadyExisted); + constexpr mc::Type *type(uint64_t *val, bool *alreadyExisted); - constexpr mc::Type *type(bool *val); + constexpr mc::Type *type(bool *val, bool *alreadyExisted); - constexpr mc::Type *type(const char *val); + constexpr mc::Type *type(const char *val, bool *alreadyExisted); template - constexpr mc::Type *type(ox::BString *val); + constexpr mc::Type *type(ox::BString *val, bool *alreadyExisted); template - mc::Type *type(T *val); + mc::Type *type(T *val, bool *alreadyExisted); - constexpr mc::Type *getPrimitive(mc::TypeName tn, mc::PrimitiveType t, int b = 0); + constexpr mc::Type *getPrimitive(mc::TypeName tn, mc::PrimitiveType t, int b, bool *alreadyExisted); }; // array handler @@ -105,9 +107,10 @@ template ox::Error MetalClawDefWriter::op(const char *name, T *val, std::size_t) { if (m_type) { constexpr typename RemoveIndirection::type *p = nullptr; - const auto t = type(p); - m_type->fieldList.push_back(mc::Field{t, name, subscriptLevels(val)}); - return 0; + bool alreadyExisted = false; + const auto t = type(p, &alreadyExisted); + m_type->fieldList.push_back(mc::Field{t, name, subscriptLevels(val), !alreadyExisted}); + return OxError(0); } return OxError(1); } @@ -125,23 +128,25 @@ ox::Error MetalClawDefWriter::op(const char *name, ox::BString *val) { template constexpr ox::Error MetalClawDefWriter::op(const char *name, T *val) { if (m_type) { - const auto t = type(val); - m_type->fieldList.push_back(mc::Field{t, name}); - return 0; + bool alreadyExisted = false; + const auto t = type(val, &alreadyExisted); + m_type->fieldList.push_back(mc::Field{t, name, 0, !alreadyExisted}); + return OxError(0); } return OxError(1); } template -mc::Type *MetalClawDefWriter::type(T *val) { +mc::Type *MetalClawDefWriter::type(T *val, bool *alreadyExisted) { MetalClawDefWriter dw(m_typeStore); oxLogError(ioOp(&dw, val)); + *alreadyExisted = dw.m_typeAlreayExisted; return dw.m_type; } template -constexpr mc::Type *MetalClawDefWriter::type(ox::BString *val) { - return type(val->c_str()); +constexpr mc::Type *MetalClawDefWriter::type(ox::BString *val, bool *alreadyExisted) { + return type(val->c_str(), alreadyExisted); } }