[ox/mc] Fix DefWriter to properly detect when to write Types

This commit is contained in:
Gary Talent 2019-02-12 06:20:05 +00:00
parent c8f39af001
commit c7e9a95a3f
3 changed files with 57 additions and 46 deletions

View File

@ -29,10 +29,15 @@ enum class PrimitiveType: uint8_t {
using FieldName = String; using FieldName = String;
struct Field { struct Field {
// order of fields matters
// only serialize type name if type has already been serialized // only serialize type name if type has already been serialized
const struct Type *type = nullptr; const struct Type *type = nullptr;
FieldName fieldName; FieldName fieldName;
int subscriptLevels = 0; int subscriptLevels = 0;
// do not serialize the following
bool serializeType = false;
}; };
using TypeName = String; using TypeName = String;
@ -61,11 +66,10 @@ template<typename T>
int ioOp(T *io, Field *field) { int ioOp(T *io, Field *field) {
int32_t err = 0; int32_t err = 0;
io->setTypeInfo("ox::mc::Field", 5); io->setTypeInfo("ox::mc::Field", 5);
if (field->type) { if (field->serializeType) {
err |= io->op("typeName", &field->type->typeName); err |= io->op("typeName", "");
err |= io->op("type", &field->type); err |= io->op("type", &field->type);
} else { } else {
// TODO: lookup type
err |= io->op("typeName", &field->type->typeName); err |= io->op("typeName", &field->type->typeName);
err |= io->op("type", static_cast<decltype(&field->type)>(nullptr)); err |= io->op("type", static_cast<decltype(&field->type)>(nullptr));
} }

View File

@ -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 TypeName = "B:int8_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto Bytes = 8; 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 TypeName = "B:int16_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto Bytes = 16; 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 TypeName = "B:int32_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto Bytes = 32; 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 TypeName = "B:int64_t";
constexpr auto PT = mc::PrimitiveType::SignedInteger; constexpr auto PT = mc::PrimitiveType::SignedInteger;
constexpr auto Bytes = 64; 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 TypeName = "B:uint8_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 8; 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 TypeName = "B:uint16_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 16; 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 TypeName = "B:uint32_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 32; 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 TypeName = "B:uint64_t";
constexpr auto PT = mc::PrimitiveType::UnsignedInteger; constexpr auto PT = mc::PrimitiveType::UnsignedInteger;
constexpr auto Bytes = 64; 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 TypeName = "B:bool";
constexpr auto PT = mc::PrimitiveType::Bool; constexpr auto PT = mc::PrimitiveType::Bool;
constexpr auto Bytes = 0; constexpr auto Bytes = 0;
return getPrimitive(TypeName, PT, Bytes); return getPrimitive(TypeName, PT, Bytes, alreadyExisted);
} }
constexpr void MetalClawDefWriter::setTypeInfo(const char *name, int) { 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; 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 TypeName = "B:string";
constexpr auto PT = mc::PrimitiveType::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)) { if (m_typeStore->contains(tn)) {
*alreadyExisted = true;
return &m_typeStore->at(tn); return &m_typeStore->at(tn);
} else { } else {
*alreadyExisted = false;
auto t = &m_typeStore->at(tn); auto t = &m_typeStore->at(tn);
t->typeName = tn; t->typeName = tn;
t->primitiveType = pt; t->primitiveType = pt;

View File

@ -52,6 +52,8 @@ class MetalClawDefWriter {
mc::TypeStore *m_typeStoreOwnerRef = nullptr; mc::TypeStore *m_typeStoreOwnerRef = nullptr;
mc::TypeStore *m_typeStore = nullptr; mc::TypeStore *m_typeStore = nullptr;
mc::Type *m_type = nullptr; mc::Type *m_type = nullptr;
// indicates whether or not m_type already existed in the TypeStore
bool m_typeAlreayExisted = false;
public: public:
explicit MetalClawDefWriter(mc::TypeStore *typeStore = nullptr); explicit MetalClawDefWriter(mc::TypeStore *typeStore = nullptr);
@ -77,27 +79,27 @@ class MetalClawDefWriter {
} }
private: private:
constexpr mc::Type *type(int8_t *val); constexpr mc::Type *type(int8_t *val, bool *alreadyExisted);
constexpr mc::Type *type(int16_t *val); constexpr mc::Type *type(int16_t *val, bool *alreadyExisted);
constexpr mc::Type *type(int32_t *val); constexpr mc::Type *type(int32_t *val, bool *alreadyExisted);
constexpr mc::Type *type(int64_t *val); constexpr mc::Type *type(int64_t *val, bool *alreadyExisted);
constexpr mc::Type *type(uint8_t *val); constexpr mc::Type *type(uint8_t *val, bool *alreadyExisted);
constexpr mc::Type *type(uint16_t *val); constexpr mc::Type *type(uint16_t *val, bool *alreadyExisted);
constexpr mc::Type *type(uint32_t *val); constexpr mc::Type *type(uint32_t *val, bool *alreadyExisted);
constexpr mc::Type *type(uint64_t *val); 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<std::size_t L> template<std::size_t L>
constexpr mc::Type *type(ox::BString<L> *val); constexpr mc::Type *type(ox::BString<L> *val, bool *alreadyExisted);
template<typename T> template<typename T>
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 // array handler
@ -105,9 +107,10 @@ template<typename T>
ox::Error MetalClawDefWriter::op(const char *name, T *val, std::size_t) { ox::Error MetalClawDefWriter::op(const char *name, T *val, std::size_t) {
if (m_type) { if (m_type) {
constexpr typename RemoveIndirection<decltype(val)>::type *p = nullptr; constexpr typename RemoveIndirection<decltype(val)>::type *p = nullptr;
const auto t = type(p); bool alreadyExisted = false;
m_type->fieldList.push_back(mc::Field{t, name, subscriptLevels(val)}); const auto t = type(p, &alreadyExisted);
return 0; m_type->fieldList.push_back(mc::Field{t, name, subscriptLevels(val), !alreadyExisted});
return OxError(0);
} }
return OxError(1); return OxError(1);
} }
@ -125,23 +128,25 @@ ox::Error MetalClawDefWriter::op(const char *name, ox::BString<L> *val) {
template<typename T> template<typename T>
constexpr ox::Error MetalClawDefWriter::op(const char *name, T *val) { constexpr ox::Error MetalClawDefWriter::op(const char *name, T *val) {
if (m_type) { if (m_type) {
const auto t = type(val); bool alreadyExisted = false;
m_type->fieldList.push_back(mc::Field{t, name}); const auto t = type(val, &alreadyExisted);
return 0; m_type->fieldList.push_back(mc::Field{t, name, 0, !alreadyExisted});
return OxError(0);
} }
return OxError(1); return OxError(1);
} }
template<typename T> template<typename T>
mc::Type *MetalClawDefWriter::type(T *val) { mc::Type *MetalClawDefWriter::type(T *val, bool *alreadyExisted) {
MetalClawDefWriter dw(m_typeStore); MetalClawDefWriter dw(m_typeStore);
oxLogError(ioOp(&dw, val)); oxLogError(ioOp(&dw, val));
*alreadyExisted = dw.m_typeAlreayExisted;
return dw.m_type; return dw.m_type;
} }
template<std::size_t L> template<std::size_t L>
constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L> *val) { constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L> *val, bool *alreadyExisted) {
return type(val->c_str()); return type(val->c_str(), alreadyExisted);
} }
} }