src/model.h

changeset 1186
eae8b3bce545
parent 1159
6ad8cdcd88d9
child 1187
46dc716238fd
equal deleted inserted replaced
1185:c2e0db52ea07 1186:eae8b3bce545
17 */ 17 */
18 18
19 #pragma once 19 #pragma once
20 #include "main.h" 20 #include "main.h"
21 #include "linetypes/modelobject.h" 21 #include "linetypes/modelobject.h"
22 #include "types/resourcevector.h"
22 23
23 /* 24 /*
24 * This class represents a LDraw model, consisting of a vector of objects. It manages LDObject ownership. 25 * This class represents a LDraw model, consisting of a vector of objects. It manages LDObject ownership.
25 */ 26 */
26 class Model : public QObject 27 class Model : public QObject
27 { 28 {
28 Q_OBJECT 29 Q_OBJECT
29 30
30 public: 31 public:
32 using Filter = std::function<bool(LDObject*)>;
33 using Callback = std::function<void(LDObject*, int)>;
34
31 Model(class DocumentManager* manager); 35 Model(class DocumentManager* manager);
32 Model(const Model& other) = delete; 36 Model(const Model& other) = delete;
33 ~Model();
34 37
35 void addObject(LDObject* object); 38 bool swapObjects(LDObject* one, LDObject* other);
36 virtual void insertObject(int position, LDObject* object);
37 virtual bool swapObjects(LDObject* one, LDObject* other);
38 virtual bool setObjectAt(int idx, LDObject* obj);
39 template<typename T, typename... Args> T* emplace(Args&& ...args); 39 template<typename T, typename... Args> T* emplace(Args&& ...args);
40 template<typename T, typename... Args> T* emplaceAt(int position, Args&& ...args); 40 template<typename T, typename... Args> T* emplaceAt(int position, Args&& ...args);
41 template<typename T, typename... Args> T* emplaceReplacement(LDObject* object, Args&& ...args); 41 template<typename T, typename... Args> T* emplaceReplacement(LDObject* object, Args&& ...args);
42 template<typename T, typename... Args> T* emplaceReplacementAt(int position, Args&& ...args);
43 void removeAt(int position); 42 void removeAt(int position);
44 void remove(LDObject* object); 43 void remove(LDObject* object);
45 void replace(LDObject *object, Model& model); 44 void replace(LDObject *object, Model& model);
46 void clear(); 45 void clear();
47 void merge(Model& other, int position = -1); 46 void merge(Model& other, int position = -1, Filter filter = nullptr, Callback callback = nullptr);
48 int size() const; 47 int size() const;
49 const QVector<LDObject*>& objects() const; 48 const ResourceVector<LDObject>& objects() const;
50 LDObject* getObject(int position) const; 49 LDObject* getObject(int position) const;
51 void recountTriangles(); 50 void recountTriangles();
52 int triangleCount() const; 51 int triangleCount() const;
53 QVector<LDObject*>::iterator begin(); 52 LDObject* const* begin();
54 QVector<LDObject*>::iterator end(); 53 LDObject* const* end();
55 bool isEmpty() const; 54 bool isEmpty() const;
56 class DocumentManager* documentManager() const; 55 class DocumentManager* documentManager() const;
57 LDObject* insertFromString(int position, QString line); 56 LDObject* insertFromString(int position, QString line);
58 LDObject* addFromString(QString line); 57 LDObject* addFromString(QString line);
59 LDObject* replaceWithFromString(LDObject* object, QString line); 58 LDObject* replaceWithFromString(LDObject* object, QString line);
60 59
61 signals: 60 signals:
62 void objectAdded(LDObject* object); 61 void objectAdded(LDObject* object, int position);
63 void aboutToRemoveObject(LDObject* object); 62 void aboutToRemoveObject(LDObject* object, int position);
64 void objectModified(LDObject* object); 63 void objectModified(LDObject* object);
64 void objectsSwapped(LDObject* one, LDObject* other);
65 65
66 protected: 66 protected:
67 template<typename T, typename... Args> T* constructObject(Args&& ...args); 67 template<typename T, typename... Args> T* constructObject(Args&& ...args);
68 void withdraw(LDObject* object);
69 virtual LDObject* withdrawAt(int position);
70 68
71 QVector<LDObject*> _objects; 69 ResourceVector<LDObject> _objects;
72 class DocumentManager* _manager; 70 class DocumentManager* _manager;
73 mutable int _triangleCount = 0; 71 mutable int _triangleCount = 0;
74 mutable bool _needsTriangleRecount; 72 mutable bool _needsTriangleRecount;
73
74 private:
75 void finalizeNewObject(int position, LDObject* object);
76 ResourceVector<LDObject>& mutableObjects();
75 }; 77 };
76 78
77 int countof(Model& model); 79 int countof(Model& model);
78 80
79 /* 81 /*
90 * model->emplace<LDLine>(v1, v2); 92 * model->emplace<LDLine>(v1, v2);
91 */ 93 */
92 template<typename T, typename... Args> 94 template<typename T, typename... Args>
93 T* Model::emplace(Args&& ...args) 95 T* Model::emplace(Args&& ...args)
94 { 96 {
95 T* object = constructObject<T>(args...); 97 T* object = _objects.append<T>(args..., this);
96 addObject(object); 98 finalizeNewObject(size() - 1, object);
97 return object; 99 return object;
98 } 100 }
99 101
100 /* 102 /*
101 * Like emplace<>() but also takes a position as the first argument and emplaces the object at the given position instead of the 103 * Like emplace<>() but also takes a position as the first argument and emplaces the object at the given position instead of the
102 * end of the model. 104 * end of the model.
103 */ 105 */
104 template<typename T, typename... Args> 106 template<typename T, typename... Args>
105 T* Model::emplaceAt(int position, Args&& ...args) 107 T* Model::emplaceAt(int position, Args&& ...args)
106 { 108 {
107 T* object = constructObject<T>(args...); 109 T* object = _objects.insert<T>(position, args..., this);
108 insertObject(position, object); 110 finalizeNewObject(position, object);
109 return object; 111 return object;
110 } 112 }
111 113
112 /* 114 /*
113 * Like emplace<>() but instead of inserting the constructed object, the new object replaces the object given in the first parameter. 115 * Like emplace<>() but instead of inserting the constructed object, the new object replaces the object given in the first parameter.
117 T* Model::emplaceReplacement(LDObject* object, Args&& ...args) 119 T* Model::emplaceReplacement(LDObject* object, Args&& ...args)
118 { 120 {
119 if (object->model() == this) 121 if (object->model() == this)
120 { 122 {
121 int position = object->lineNumber(); 123 int position = object->lineNumber();
122 T* replacement = constructObject<T>(args...); 124 removeAt(position);
123 setObjectAt(position, replacement); 125 T* replacement = _objects.insert<T>(position, args..., this);
126 finalizeNewObject(position, replacement);
124 return replacement; 127 return replacement;
125 } 128 }
126 else 129 else
130 {
127 return nullptr; 131 return nullptr;
132 }
128 } 133 }
129
130 /*
131 * Like emplaceAt<>() but instead of inserting the constructed object, it replaces the document at the given spot instead.
132 * The replaced object is deleted in the process.
133 */
134 template<typename T, typename... Args>
135 T* Model::emplaceReplacementAt(int position, Args&& ...args)
136 {
137 T* replacement = constructObject<T>(args...);
138 setObjectAt(position, replacement);
139 return replacement;
140 }
141
142 /*
143 * Constructs an LDObject such that it gets this model as its model pointer.
144 */
145 template<typename T, typename... Args>
146 T* Model::constructObject(Args&& ...args)
147 {
148 static_assert (std::is_base_of<LDObject, T>::value, "Can only use this function with LDObject-derivatives");
149 T* object = new T {args..., this};
150
151 // Set default color. Relying on virtual functions, this cannot be done in the c-tor.
152 // TODO: store -1 as the default color
153 if (object->isColored())
154 object->setColor(object->defaultColor());
155
156 return object;
157 }

mercurial