Tue, 21 Sep 2021 16:00:15 +0300
Begin work with serialization
--- a/src/colors.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/colors.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -127,3 +127,13 @@ return colorTable[color].faceColor; } } + +QDataStream& operator<<(QDataStream& stream, ldraw::Color color) +{ + return stream << color.index; +} + +QDataStream& operator>>(QDataStream& stream, ldraw::Color& color) +{ + return stream >> color.index; +}
--- a/src/colors.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/colors.h Tue Sep 21 16:00:15 2021 +0300 @@ -105,3 +105,5 @@ } double luma(const QColor& color); +QDataStream& operator<<(QDataStream&, ldraw::Color); +QDataStream& operator>>(QDataStream&, ldraw::Color&);
--- a/src/linetypes/comment.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/comment.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -7,3 +7,8 @@ font.setItalic(true); return font; } + +ldraw::Object::Type ldraw::Comment::typeIdentifier() const +{ + return Type::Comment; +}
--- a/src/linetypes/comment.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/comment.h Tue Sep 21 16:00:15 2021 +0300 @@ -11,4 +11,5 @@ { using MetaCommand::MetaCommand; QFont textRepresentationFont() const override; + Type typeIdentifier() const override; };
--- a/src/linetypes/conditionaledge.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/conditionaledge.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -6,5 +6,10 @@ utility::vertexToStringParens(this->points[0]), utility::vertexToStringParens(this->points[1]), utility::vertexToStringParens(this->points[2]), - utility::vertexToStringParens(this->points[3])); + utility::vertexToStringParens(this->points[3])); } + +ldraw::Object::Type ldraw::ConditionalEdge::typeIdentifier() const +{ + return Type::ConditionalEdge; +}
--- a/src/linetypes/conditionaledge.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/conditionaledge.h Tue Sep 21 16:00:15 2021 +0300 @@ -11,4 +11,5 @@ public: using PolygonObject<4>::PolygonObject; QString textRepresentation() const override; + Type typeIdentifier() const override; };
--- a/src/linetypes/edge.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/edge.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -15,3 +15,8 @@ Q_UNUSED(context) polygons.push_back(gl::edgeLine(this->points[0], this->points[1], this->colorIndex, this->id)); } + +ldraw::Object::Type ldraw::Edge::typeIdentifier() const +{ + return Type::EdgeLine; +}
--- a/src/linetypes/edge.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/edge.h Tue Sep 21 16:00:15 2021 +0300 @@ -12,4 +12,5 @@ using PolygonObject::PolygonObject; QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override; + Type typeIdentifier() const override; };
--- a/src/linetypes/errorline.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/errorline.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -41,3 +41,8 @@ { return QBrush{Qt::red}; } + +ldraw::Object::Type ldraw::ErrorLine::typeIdentifier() const +{ + return Type::ErrorLine; +}
--- a/src/linetypes/errorline.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/errorline.h Tue Sep 21 16:00:15 2021 +0300 @@ -15,6 +15,7 @@ QString textRepresentation() const override; QBrush textRepresentationForeground() const override; QBrush textRepresentationBackground() const override; + Type typeIdentifier() const override; QString text; QString message; protected:
--- a/src/linetypes/metacommand.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/metacommand.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -26,3 +26,8 @@ return this->storedText; } +ldraw::Object::Type ldraw::MetaCommand::typeIdentifier() const +{ + return Type::MetaCommand; +} +
--- a/src/linetypes/metacommand.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/metacommand.h Tue Sep 21 16:00:15 2021 +0300 @@ -14,6 +14,7 @@ QVariant getProperty(Property property) const override; QString textRepresentation() const override; QString storedText = ""; + Type typeIdentifier() const override; protected: void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override; };
--- a/src/linetypes/object.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/object.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -74,6 +74,27 @@ throw BadPointIndex{}; } +/** + * @brief Serializes the object into a stream of bytes for internal storage. + * @param stream Data stream to serialize into + */ +QDataStream& ldraw::Object::serialize(QDataStream &stream) const +{ + return stream << static_cast<int>(this->typeIdentifier()); +} + +/** + * @brief Deserializes the object from a stream of bytes coming from internal storage. + * @param stream Data stream to serialize from. + * @note @c ldraw::Object::serialize will insert a type enumerator. Before calling this function, + * this enumerator is assumed to have been handled as the object class needs to be initialized based + * on the value of this enumerator. + */ +QDataStream& ldraw::Object::deserialize(QDataStream &stream) +{ + return stream; +} + ldraw::ColoredObject::ColoredObject(const Color color_index) : colorIndex{color_index} { @@ -101,7 +122,32 @@ Object::setProperty(result, pair); } +/** + * @brief @overload @c ldraw::Object::serialize + * @param stream + * @return stream + */ +QDataStream& ldraw::ColoredObject::serialize(QDataStream& stream) const +{ + return Object::serialize(stream) << this->colorIndex; +} + +/** + * @brief @overload @c ldraw::Object::deserialize + * @param stream + * @return stream + */ +QDataStream& ldraw::ColoredObject::deserialize(QDataStream& stream) +{ + return Object::serialize(stream) >> this->colorIndex; +} + QString ldraw::Empty::textRepresentation() const { return ""; } + +ldraw::Object::Type ldraw::Empty::typeIdentifier() const +{ + return Type::Empty; +}
--- a/src/linetypes/object.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/object.h Tue Sep 21 16:00:15 2021 +0300 @@ -33,6 +33,21 @@ Success = 0, PropertyNotHandled }; + /** + * @brief Enumerates different object types + */ + enum class Type + { + Empty, + Comment, + MetaCommand, + ErrorLine, + SubfileReference, + EdgeLine, + ConditionalEdge, + Triangle, + Quadrilateral, + }; friend bool handled(SetPropertyResult result) { return result == SetPropertyResult::Success; @@ -57,6 +72,10 @@ virtual void invert() {} virtual int numPoints() const { return 0; } virtual const glm::vec3& getPoint(int index) const; + virtual QDataStream& serialize(QDataStream& stream) const; + virtual QDataStream& deserialize(QDataStream& stream); + virtual Type typeIdentifier() const = 0; + protected: template<Property property, typename Function> void handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function); @@ -87,6 +106,8 @@ ColoredObject(const Color colorIndex = ldraw::mainColor); bool hasColor() const override final; QVariant getProperty(Property id) const override; + QDataStream &serialize(QDataStream& stream) const override; + QDataStream& deserialize(QDataStream& stream) override; Color colorIndex = ldraw::mainColor; protected: void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override; @@ -98,4 +119,5 @@ class ldraw::Empty : public Object { QString textRepresentation() const override; + Type typeIdentifier() const override; };
--- a/src/linetypes/polygonobject.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/polygonobject.h Tue Sep 21 16:00:15 2021 +0300 @@ -66,5 +66,22 @@ } ColoredObject::setProperty(result, pair); } + QDataStream &serialize(QDataStream& stream) const override + { + for (const glm::vec3& point : this->points) + { + stream << point; + } + return stream; + } + QDataStream& deserialize(QDataStream& stream) override + { + for (glm::vec3& point : this->points) + { + stream >> point; + } + return stream; + } +protected: std::array<glm::vec3, N> points; };
--- a/src/linetypes/quadrilateral.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/quadrilateral.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -29,3 +29,8 @@ // -> 2 1 0 3 std::swap(this->points[0], this->points[2]); } + +ldraw::Object::Type ldraw::Quadrilateral::typeIdentifier() const +{ + return Type::Quadrilateral; +}
--- a/src/linetypes/quadrilateral.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/quadrilateral.h Tue Sep 21 16:00:15 2021 +0300 @@ -13,4 +13,5 @@ QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override; void invert() override; + Type typeIdentifier() const override; };
--- a/src/linetypes/subfilereference.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/subfilereference.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -87,3 +87,18 @@ { return documents->findModelByName(this->referenceName); } + +ldraw::Object::Type ldraw::SubfileReference::typeIdentifier() const +{ + return Type::SubfileReference; +} + +QDataStream& ldraw::SubfileReference::serialize(QDataStream &stream) const +{ + return stream << this->transformation << this->referenceName << this->isInverted; +} + +QDataStream& ldraw::SubfileReference::deserialize(QDataStream &stream) +{ + return stream >> this->transformation >> this->referenceName >> this->isInverted; +}
--- a/src/linetypes/subfilereference.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/subfilereference.h Tue Sep 21 16:00:15 2021 +0300 @@ -22,6 +22,9 @@ glm::vec3 position() const; void invert() override; Model* resolve(DocumentManager* documents) const; + Type typeIdentifier() const override; + QDataStream& serialize(QDataStream& stream) const override; + QDataStream& deserialize(QDataStream& stream) override; glm::mat4 transformation; QString referenceName; bool isInverted = false;
--- a/src/linetypes/triangle.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/triangle.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -27,3 +27,8 @@ // -> 1 0 2 std::swap(this->points[0], this->points[1]); } + +ldraw::Object::Type ldraw::Triangle::typeIdentifier() const +{ + return Type::Triangle; +}
--- a/src/linetypes/triangle.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/linetypes/triangle.h Tue Sep 21 16:00:15 2021 +0300 @@ -13,5 +13,6 @@ QString textRepresentation() const override; void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const override; void invert() override; + Type typeIdentifier() const override; };
--- a/src/main.cpp Fri Sep 17 22:43:22 2021 +0300 +++ b/src/main.cpp Tue Sep 21 16:00:15 2021 +0300 @@ -37,3 +37,12 @@ mainwindow.show(); return app.exec(); } + +QDataStream& operator<<(QDataStream& stream, const glm::vec3& vec) +{ + return stream << vec.x << vec.y << vec.z; +} +QDataStream& operator>>(QDataStream& stream, glm::vec3& vec) +{ + return stream >> vec.x >> vec.y >> vec.z; +}
--- a/src/main.h Fri Sep 17 22:43:22 2021 +0300 +++ b/src/main.h Tue Sep 21 16:00:15 2021 +0300 @@ -223,3 +223,41 @@ MapItemsIterator<K, const V, typename QMap<K, V>::iterator> >{map}; } + +/** + * Iterates a @c glm::mat + */ +template<int X, int Y, typename T, glm::qualifier Q, typename Fn> +void iter_matrix(const glm::mat<X, Y, T, Q>& matrix, Fn&& fn) +{ + for (int i = 0; i < X; ++i) + { + for (int j = 0; j < Y; ++j) + { + fn(i, j, matrix[i][j]); + } + } +} + +QDataStream& operator<<(QDataStream&, const glm::vec3&); +QDataStream& operator>>(QDataStream&, glm::vec3&); + +template<int X, int Y, typename T, glm::qualifier Q, typename Fn> +QDataStream& operator<<(QDataStream& stream, const glm::mat<X, Y, T, Q>& mat) +{ + iter_matrix(mat, [&stream](int, int, float x) + { + stream << x; + }); + return stream; +} + +template<int X, int Y, typename T, glm::qualifier Q, typename Fn> +QDataStream& operator>>(QDataStream& stream, glm::mat<X, Y, T, Q>& mat) +{ + iter_matrix(mat, [&stream](int, int, float x) + { + stream >> x; + }); + return stream; +}