diff -r 14e51640c189 -r 7abaf1d64719 src/linetypes/propertygenerics.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/linetypes/propertygenerics.h Mon May 11 12:18:59 2020 +0300 @@ -0,0 +1,153 @@ +#pragma once +#include "main.h" +#include "colors.h" + +class Vec3Editor; +class MatrixEditor; + +namespace ldraw +{ + enum class Property; + struct PropertyKeyValue; + template + struct PropertyTraits + { + static constexpr bool defined = false; + }; +} + +/** + * Different properties + */ +enum class ldraw::Property +{ + Color, // Color of the object + Text, // Text contained in a comment + Point0, // First vertex in a polygon or edge line + Point1, // Second vertex in a polygon or edge line + Point2, // Third vertex in a polygon + Point3, // Fourth vertex in a quadrilateral + Transformation, // 4x4 transformation matrix of a subfile reference + ReferenceName, // Subfile reference name + IsInverted, // Whether or not the object has been inverted with BFC INVERTNEXT + ErrorMessage // For error lines, why parsing failed +}; + +Q_DECLARE_METATYPE(ldraw::Property) + +// Mapping of properties to types +#define LDFORGE_DEFINE_PROPERTY_TYPE(PROPERTY, TYPE) \ + namespace ldraw \ + { \ + template<> struct PropertyTraits \ + { \ + using type = TYPE; \ + static constexpr std::array name{#PROPERTY}; \ + static constexpr bool defined = true; \ + }; \ + } + +LDFORGE_DEFINE_PROPERTY_TYPE(Color, ldraw::Color) +LDFORGE_DEFINE_PROPERTY_TYPE(Text, QString) +LDFORGE_DEFINE_PROPERTY_TYPE(Point0, glm::vec3) +LDFORGE_DEFINE_PROPERTY_TYPE(Point1, glm::vec3) +LDFORGE_DEFINE_PROPERTY_TYPE(Point2, glm::vec3) +LDFORGE_DEFINE_PROPERTY_TYPE(Point3, glm::vec3) +LDFORGE_DEFINE_PROPERTY_TYPE(Transformation, glm::mat4) +LDFORGE_DEFINE_PROPERTY_TYPE(ReferenceName, QString) +LDFORGE_DEFINE_PROPERTY_TYPE(IsInverted, bool) +LDFORGE_DEFINE_PROPERTY_TYPE(ErrorMessage, QString) + +#define LDRAW_OBJECT_HANDLE_SET_PROPERTY(PROPERTY, HANDLER) \ + {this->handle(result, pair, \ + [&](const ldraw::PropertyType& value) HANDLER);} + +// Generics +namespace ldraw +{ + template + using PropertyType = typename PropertyTraits::type; + + template + inline const char* PROPERTY_NAME = PropertyTraits::name; + + struct PropertyKeyValue + { + Property key; + QVariant value; + }; + + constexpr Property pointProperty(int n) + { + Q_ASSERT(n >= 0 and n < 4); + return static_cast(static_cast(Property::Point0) + n); + } + + struct PropertyTrait + { + ldraw::Property property; + std::array name; + int type; + }; + + namespace detail + { + template + constexpr int propertyCountHelper() + { + if constexpr (ldraw::PropertyTraits(N)>::defined) + { + return propertyCountHelper(); + } + else + { + return N; + } + } + + template + constexpr PropertyTrait getPropertyTrait() + { + constexpr auto property = static_cast(k); + using trait = ldraw::PropertyTraits; + return PropertyTrait{ + property, + trait::name, + qMetaTypeId() + }; + } + + template + auto getPropertyTraits(std::integer_sequence) + { + return std::array{getPropertyTrait()...}; + } + } + + constexpr int NUM_PROPERTIES = detail::propertyCountHelper<0>(); + inline const auto& traits() + { + static std::array result = + detail::getPropertyTraits(std::make_integer_sequence()); + return result; + } + + inline const auto& traits(ldraw::Property property) + { + return traits()[static_cast(property)]; + } + + template + constexpr auto makeIndexArray(std::index_sequence) + { + return std::array{static_cast(Ints)...}; + } + + constexpr auto ALL_PROPERTIES = makeIndexArray(std::make_index_sequence{}); + + template + bool testPropertyType(ldraw::Property property) + { + return qMetaTypeId() == ldraw::traits(property).type; + } +}