src/linetypes/propertygenerics.h

changeset 200
ca23936b455b
parent 199
6988973515d2
child 201
5d201ee4a9c3
equal deleted inserted replaced
199:6988973515d2 200:ca23936b455b
1 #pragma once
2 #include "main.h"
3 #include "colors.h"
4
5 class Vec3Editor;
6 class MatrixEditor;
7
8 namespace ldraw
9 {
10 enum CircularPrimitiveType
11 {
12 Circle,
13 Disc
14 };
15 enum class Property;
16 struct PropertyKeyValue;
17 template<Property property>
18 struct PropertyTraits
19 {
20 static constexpr bool defined = false;
21 };
22 }
23
24 Q_DECLARE_METATYPE(ldraw::CircularPrimitiveType)
25
26 /**
27 * Different properties
28 */
29 enum class ldraw::Property
30 {
31 Color, // Color of the object
32 Text, // Text contained in a comment
33 Point0, // First vertex in a polygon or edge line
34 Point1, // Second vertex in a polygon or edge line
35 Point2, // Third vertex in a polygon
36 Point3, // Fourth vertex in a quadrilateral
37 Transformation, // 4x4 transformation matrix of a subfile reference
38 ReferenceName, // Subfile reference name
39 IsInverted, // Whether or not the object has been inverted with BFC INVERTNEXT
40 ErrorMessage, // For error lines, why parsing failed
41 CircularPrimitiveType, // Type of circular primitive (circle, disc, ...)
42 Segments, // Amount of circular segments this primitive covers (numerator)
43 Divisions, // Amount of segments in the circle this primitive fits in (8, 16, 48, ...)
44 };
45
46 Q_DECLARE_METATYPE(ldraw::Property)
47
48 // Mapping of properties to types
49 #define LDFORGE_DEFINE_PROPERTY_TYPE(PROPERTY, TYPE) \
50 namespace ldraw \
51 { \
52 template<> struct PropertyTraits<ldraw::Property::PROPERTY> \
53 { \
54 using type = TYPE; \
55 static constexpr std::array<char, 256> name{#PROPERTY}; \
56 static constexpr bool defined = true; \
57 }; \
58 }
59
60 LDFORGE_DEFINE_PROPERTY_TYPE(Color, ldraw::Color)
61 LDFORGE_DEFINE_PROPERTY_TYPE(Text, QString)
62 LDFORGE_DEFINE_PROPERTY_TYPE(Point0, glm::vec3)
63 LDFORGE_DEFINE_PROPERTY_TYPE(Point1, glm::vec3)
64 LDFORGE_DEFINE_PROPERTY_TYPE(Point2, glm::vec3)
65 LDFORGE_DEFINE_PROPERTY_TYPE(Point3, glm::vec3)
66 LDFORGE_DEFINE_PROPERTY_TYPE(Transformation, glm::mat4)
67 LDFORGE_DEFINE_PROPERTY_TYPE(ReferenceName, QString)
68 LDFORGE_DEFINE_PROPERTY_TYPE(IsInverted, bool)
69 LDFORGE_DEFINE_PROPERTY_TYPE(ErrorMessage, QString)
70 LDFORGE_DEFINE_PROPERTY_TYPE(CircularPrimitiveType, ldraw::CircularPrimitiveType)
71 LDFORGE_DEFINE_PROPERTY_TYPE(Segments, int)
72 LDFORGE_DEFINE_PROPERTY_TYPE(Divisions, int)
73
74 #define LDRAW_OBJECT_HANDLE_SET_PROPERTY(PROPERTY, HANDLER) \
75 {this->handle<ldraw::Property::PROPERTY>(result, pair, \
76 [&](const ldraw::PropertyType<ldraw::Property::PROPERTY>& value) HANDLER);}
77
78 // Generics
79 namespace ldraw
80 {
81 template<ldraw::Property property>
82 using PropertyType = typename PropertyTraits<property>::type;
83
84 template<ldraw::Property property>
85 inline const char* PROPERTY_NAME = PropertyTraits<property>::name;
86
87 constexpr int MAX_POINTS = 4;
88
89 struct PropertyKeyValue
90 {
91 Property key;
92 QVariant value;
93 };
94
95 constexpr Property pointProperty(int n)
96 {
97 Q_ASSERT(n >= 0 and n < MAX_POINTS);
98 return static_cast<Property>(static_cast<int>(Property::Point0) + n);
99 }
100
101 struct PropertyTrait
102 {
103 ldraw::Property property;
104 std::array<char, 256> name;
105 int type;
106 };
107
108 namespace detail
109 {
110 template<int N>
111 constexpr int propertyCountHelper()
112 {
113 if constexpr (ldraw::PropertyTraits<static_cast<Property>(N)>::defined)
114 {
115 return propertyCountHelper<N + 1>();
116 }
117 else
118 {
119 return N;
120 }
121 }
122
123 template<int k>
124 constexpr PropertyTrait getPropertyTrait()
125 {
126 constexpr auto property = static_cast<ldraw::Property>(k);
127 using trait = ldraw::PropertyTraits<property>;
128 return PropertyTrait{
129 property,
130 trait::name,
131 qMetaTypeId<typename trait::type>()
132 };
133 }
134
135 template<int... Ints>
136 auto getPropertyTraits(std::integer_sequence<int, Ints...>)
137 {
138 return std::array<PropertyTrait, sizeof...(Ints)>{getPropertyTrait<Ints>()...};
139 }
140 }
141
142 constexpr int NUM_PROPERTIES = detail::propertyCountHelper<0>();
143 inline const auto& traits()
144 {
145 static std::array<PropertyTrait, NUM_PROPERTIES> result =
146 detail::getPropertyTraits(std::make_integer_sequence<int, NUM_PROPERTIES>());
147 return result;
148 }
149
150 inline const auto& traits(ldraw::Property property)
151 {
152 return traits()[static_cast<int>(property)];
153 }
154
155 template<typename T, std::size_t... Ints>
156 constexpr auto makeIndexArray(std::index_sequence<Ints...>)
157 {
158 return std::array{static_cast<T>(Ints)...};
159 }
160
161 constexpr auto ALL_PROPERTIES = makeIndexArray<Property>(std::make_index_sequence<NUM_PROPERTIES>{});
162
163 template<typename T>
164 bool testPropertyType(ldraw::Property property)
165 {
166 return qMetaTypeId<T>() == ldraw::traits(property).type;
167 }
168 }

mercurial