[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;
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<typename T>
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_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 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;

View File

@ -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<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>
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<typename T>
ox::Error MetalClawDefWriter::op(const char *name, T *val, std::size_t) {
if (m_type) {
constexpr typename RemoveIndirection<decltype(val)>::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<L> *val) {
template<typename T>
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<typename T>
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<std::size_t L>
constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L> *val) {
return type(val->c_str());
constexpr mc::Type *MetalClawDefWriter::type(ox::BString<L> *val, bool *alreadyExisted) {
return type(val->c_str(), alreadyExisted);
}
}