18 |
18 |
19 #pragma once |
19 #pragma once |
20 #include "src/basics.h" |
20 #include "src/basics.h" |
21 #include "src/model.h" |
21 #include "src/model.h" |
22 |
22 |
23 class Parser : public QObject |
23 struct TextRange |
24 { |
24 { |
25 Q_OBJECT |
25 int start; |
26 public: |
26 int length; |
27 Parser(QTextStream& stream, QObject* parent = nullptr); |
|
28 void parseBody(Model &model); |
|
29 private: |
|
30 QString readLine(); |
|
31 QTextStream& stream; |
|
32 }; |
27 }; |
33 |
28 |
34 ModelElement parseLDrawLine(QString line); |
29 |
|
30 enum class Attribute { |
|
31 LineType, |
|
32 Color, |
|
33 X1, |
|
34 Y1, |
|
35 Z1, |
|
36 X2, |
|
37 Y2, |
|
38 Z2, |
|
39 X3, |
|
40 Y3, |
|
41 Z3, |
|
42 X4, |
|
43 Y4, |
|
44 Z4, |
|
45 Name, |
|
46 Text |
|
47 }; |
|
48 |
|
49 template<typename T, Attribute... Attribs> |
|
50 struct LineType |
|
51 { |
|
52 static constexpr Attribute attributes[] = {Attribs...}; |
|
53 QString content; |
|
54 TextRange positions[countof(attributes)]; |
|
55 T value; |
|
56 }; |
|
57 |
|
58 using LineType0 = LineType<Comment, Attribute::Text>; |
|
59 using LineType1 = LineType<Colored<SubfileReference>, |
|
60 Attribute::LineType, |
|
61 Attribute::Color, |
|
62 Attribute::X1, |
|
63 Attribute::Y1, |
|
64 Attribute::Z1, |
|
65 Attribute::X2, |
|
66 Attribute::Y2, |
|
67 Attribute::Z2, |
|
68 Attribute::X3, |
|
69 Attribute::Y3, |
|
70 Attribute::Z3, |
|
71 Attribute::X4, |
|
72 Attribute::Y4, |
|
73 Attribute::Z4, |
|
74 Attribute::Name>; |
|
75 using LineType2 = LineType<Colored<LineSegment>, |
|
76 Attribute::LineType, |
|
77 Attribute::Color, |
|
78 Attribute::X1, |
|
79 Attribute::Y1, |
|
80 Attribute::Z1, |
|
81 Attribute::X2, |
|
82 Attribute::Y2, |
|
83 Attribute::Z2>; |
|
84 using LineType3 = LineType<Colored<Triangle>, |
|
85 Attribute::LineType, |
|
86 Attribute::Color, |
|
87 Attribute::X1, |
|
88 Attribute::Y1, |
|
89 Attribute::Z1, |
|
90 Attribute::X2, |
|
91 Attribute::Y2, |
|
92 Attribute::Z2, |
|
93 Attribute::X3, |
|
94 Attribute::Y3, |
|
95 Attribute::Z3>; |
|
96 using LineType4 = LineType<Colored<Quadrilateral>, |
|
97 Attribute::LineType, |
|
98 Attribute::Color, |
|
99 Attribute::X1, |
|
100 Attribute::Y1, |
|
101 Attribute::Z1, |
|
102 Attribute::X2, |
|
103 Attribute::Y2, |
|
104 Attribute::Z2, |
|
105 Attribute::X3, |
|
106 Attribute::Y3, |
|
107 Attribute::Z3, |
|
108 Attribute::X4, |
|
109 Attribute::Y4, |
|
110 Attribute::Z4>; |
|
111 using LineType5 = LineType<Colored<ConditionalEdge>, |
|
112 Attribute::LineType, |
|
113 Attribute::Color, |
|
114 Attribute::X1, |
|
115 Attribute::Y1, |
|
116 Attribute::Z1, |
|
117 Attribute::X2, |
|
118 Attribute::Y2, |
|
119 Attribute::Z2, |
|
120 Attribute::X3, |
|
121 Attribute::Y3, |
|
122 Attribute::Z3, |
|
123 Attribute::X4, |
|
124 Attribute::Y4, |
|
125 Attribute::Z4>; |
|
126 |
|
127 template<typename T, Attribute Attrib> |
|
128 constexpr int findAttributeIndex() |
|
129 { |
|
130 constexpr auto it = std::find( |
|
131 std::begin(T::attributes), |
|
132 std::end(T::attributes), |
|
133 Attrib |
|
134 ); |
|
135 static_assert(it != std::end(T::attributes), "Attribute not found"); |
|
136 return it - std::begin(T::attributes); |
|
137 } |
|
138 |
|
139 template<typename T, Attribute Attrib> |
|
140 constexpr int attribIndex = findAttributeIndex<T, Attrib>(); |
|
141 static_assert(attribIndex<LineType3, Attribute::X1> == 2); |
|
142 using ParsedLine = std::variant<LineType0, LineType1, LineType2, LineType3, LineType4, LineType5>; |
|
143 opt<ParsedLine> parse(const QString& line); |