From 61660f890e7a680c1498ee6d062f35d2f67502d2 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 17 Mar 2014 11:39:16 -0700 Subject: [PATCH] Working on metadata for metatypes. --- .../metavoxels/src/AttributeRegistry.cpp | 3 + libraries/metavoxels/src/AttributeRegistry.h | 4 ++ libraries/metavoxels/src/Bitstream.h | 6 +- tools/mtc/src/main.cpp | 64 +++++++++++++++---- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/libraries/metavoxels/src/AttributeRegistry.cpp b/libraries/metavoxels/src/AttributeRegistry.cpp index ccb6d3970e..634e7d3b57 100644 --- a/libraries/metavoxels/src/AttributeRegistry.cpp +++ b/libraries/metavoxels/src/AttributeRegistry.cpp @@ -17,6 +17,9 @@ REGISTER_META_OBJECT(SharedObjectAttribute) REGISTER_META_OBJECT(SharedObjectSetAttribute) REGISTER_META_OBJECT(SpannerSetAttribute) +static int attributePointerMetaTypeId = qRegisterMetaType(); +static int ownedAttributeValueMetaTypeId = qRegisterMetaType(); + AttributeRegistry* AttributeRegistry::getInstance() { static AttributeRegistry registry; return ®istry; diff --git a/libraries/metavoxels/src/AttributeRegistry.h b/libraries/metavoxels/src/AttributeRegistry.h index b6a415bef7..f3dd9f4632 100644 --- a/libraries/metavoxels/src/AttributeRegistry.h +++ b/libraries/metavoxels/src/AttributeRegistry.h @@ -29,6 +29,8 @@ class MetavoxelStreamState; typedef SharedObjectPointerTemplate AttributePointer; +Q_DECLARE_METATYPE(AttributePointer) + /// Maintains information about metavoxel attribute types. class AttributeRegistry { public: @@ -150,6 +152,8 @@ public: OwnedAttributeValue& operator=(const OwnedAttributeValue& other); }; +Q_DECLARE_METATYPE(OwnedAttributeValue) + /// Represents a registered attribute. class Attribute : public SharedObject { Q_OBJECT diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index f4e8d19ce3..f52db029b6 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -537,7 +537,11 @@ template int registerStreamableMetaType() { } /// Flags a class as streamable (use as you would Q_OBJECT). -#define STREAMABLE public: static const int Type; private: +#define STREAMABLE public: \ + static const int Type; \ + static int getFieldCount(); \ + void setFieldValue(int index, const QVariant& value); \ + private: /// Flags a field or base class as streaming. #define STREAM diff --git a/tools/mtc/src/main.cpp b/tools/mtc/src/main.cpp index 248c2ddd2d..598b7b10d0 100644 --- a/tools/mtc/src/main.cpp +++ b/tools/mtc/src/main.cpp @@ -24,10 +24,16 @@ public: QStringList bases; }; +class Field { +public: + QString type; + QString name; +}; + class Streamable { public: Class clazz; - QStringList fields; + QList fields; }; void processInput(QTextStream& in, QList* streamables) { @@ -66,8 +72,10 @@ void processInput(QTextStream& in, QList* streamables) { } else if (match.startsWith("STREAM")) { match.chop(1); // get rid of the semicolon - match = match.trimmed(); // and any space before it - currentStreamable.fields.append(match.mid(match.lastIndexOf(' ') + 1)); + match = match.mid(match.indexOf(' ') + 1).trimmed(); // and STREAM, and any space before it + int index = match.lastIndexOf(' '); + Field field = { match.left(index).simplified(), match.mid(index + 1) }; + currentStreamable.fields.append(field); } else { // match.startsWith("class") classExp.exactMatch(match); @@ -90,12 +98,42 @@ void generateOutput (QTextStream& out, const QList& streamables) { foreach (const Streamable& str, streamables) { const QString& name = str.clazz.name; + out << "const int " << name << "::Type = registerStreamableMetaType<" << name << ">();\n"; + + out << "int " << name << "::getFieldCount() {\n"; + out << " return " << str.fields.size(); + foreach(const QString& base, str.clazz.bases) { + out << " + " << base << "::getFieldCount()"; + } + out << ";\n"; + out << "}\n"; + + out << "void " << name << "::setFieldValue(int index, const QVariant& value) {\n"; + if (!str.clazz.bases.isEmpty()) { + out << " int nextIndex;\n"; + } + foreach (const QString& base, str.clazz.bases) { + out << " if ((nextIndex = index - " << base << "::getFieldCount()) < 0) {\n"; + out << " " << base << "::setFieldValue(index, value);\n"; + out << " return;\n"; + out << " }\n"; + out << " index = nextIndex;\n"; + } + out << " switch (index) {\n"; + for (int i = 0; i < str.fields.size(); i++) { + out << " case " << i << ":\n"; + out << " this->" << str.fields.at(i).name << " = value.value<" << str.fields.at(i).type << ">();\n"; + out << " break;\n"; + } + out << " }\n"; + out << "}\n"; + out << "Bitstream& operator<<(Bitstream& out, const " << name << "& obj) {\n"; foreach (const QString& base, str.clazz.bases) { out << " out << static_cast(obj);\n"; } - foreach (const QString& field, str.fields) { - out << " out << obj." << field << ";\n"; + foreach (const Field& field, str.fields) { + out << " out << obj." << field.name << ";\n"; } out << " return out;\n"; out << "}\n"; @@ -104,8 +142,8 @@ void generateOutput (QTextStream& out, const QList& streamables) { foreach (const QString& base, str.clazz.bases) { out << " in >> static_cast<" << base << "&>(obj);\n"; } - foreach (const QString& field, str.fields) { - out << " in >> obj." << field << ";\n"; + foreach (const Field& field, str.fields) { + out << " in >> obj." << field.name << ";\n"; } out << " return in;\n"; out << "}\n"; @@ -124,12 +162,12 @@ void generateOutput (QTextStream& out, const QList& streamables) { out << "static_cast(first) == static_cast(second)"; first = false; } - foreach (const QString& field, str.fields) { + foreach (const Field& field, str.fields) { if (!first) { out << " &&\n"; out << " "; } - out << "first." << field << " == second." << field; + out << "first." << field.name << " == second." << field.name; first = false; } } @@ -150,19 +188,17 @@ void generateOutput (QTextStream& out, const QList& streamables) { out << "static_cast(first) != static_cast(second)"; first = false; } - foreach (const QString& field, str.fields) { + foreach (const Field& field, str.fields) { if (!first) { out << " ||\n"; out << " "; } - out << "first." << field << " != second." << field; + out << "first." << field.name << " != second." << field.name; first = false; } } out << ";\n"; - out << "}\n"; - - out << "const int " << name << "::Type = registerStreamableMetaType<" << name << ">();\n\n"; + out << "}\n\n"; } }