42 QVariant data(const QModelIndex& index, int role) const override; |
42 QVariant data(const QModelIndex& index, int role) const override; |
43 QVariant getHeaderProperty(const HeaderProperty property); |
43 QVariant getHeaderProperty(const HeaderProperty property); |
44 const QString& getName() const; |
44 const QString& getName() const; |
45 QVariant getObjectProperty(const int index, const ldraw::Property property) const; |
45 QVariant getObjectProperty(const int index, const ldraw::Property property) const; |
46 std::vector<gl::Polygon> getPolygons(class DocumentManager* documents) const; |
46 std::vector<gl::Polygon> getPolygons(class DocumentManager* documents) const; |
47 QModelIndex lookup(ldraw::Id id) const; |
47 QModelIndex lookup(ldraw::id_t id) const; |
48 ldraw::Id resolve(const QModelIndex& index) const; |
48 ldraw::id_t resolve(const QModelIndex& index) const; |
|
49 template<typename R> |
|
50 ldraw::Id<R> checkType(ldraw::id_t id) const; |
|
51 template<typename R> |
|
52 const R* get(ldraw::Id<R> id) const; |
49 signals: |
53 signals: |
50 void objectAdded(ldraw::Id id, int position); |
54 void objectAdded(ldraw::id_t id, int position); |
51 private: |
55 private: |
52 using ModelObjectPointer = std::unique_ptr<ldraw::Object>; |
56 using ModelObjectPointer = std::unique_ptr<ldraw::Object>; |
53 template<typename T, typename... Args> |
57 template<typename T, typename... Args> |
54 ldraw::Id append(Args&&... args); |
58 ldraw::Id<T> append(Args&&... args); |
55 void append(ModelObjectPointer&& object); |
59 void append(ModelObjectPointer&& object); |
56 template<typename T, typename... Args> |
60 template<typename T, typename... Args> |
57 ldraw::Id insert(int position, Args&&... args); |
61 ldraw::Id<T> insert(int position, Args&&... args); |
58 ldraw::Object* objectAt(const QModelIndex& index); |
62 ldraw::Object* objectAt(const QModelIndex& index); |
59 const ldraw::Object* objectAt(const QModelIndex& index) const; |
63 const ldraw::Object* objectAt(const QModelIndex& index) const; |
|
64 template<typename T> |
|
65 T* objectAt(ldraw::Id<T> id) |
|
66 { |
|
67 return static_cast<T*>(this->objectAt(this->lookup(id))); |
|
68 } |
|
69 template<typename T> |
|
70 const T* objectAt(ldraw::Id<T> id) const |
|
71 { |
|
72 return static_cast<const T*>(this->objectAt(this->lookup(id))); |
|
73 } |
60 void getObjectPolygons( |
74 void getObjectPolygons( |
61 const int index, |
75 const int index, |
62 std::vector<gl::Polygon>& polygons_out, |
76 std::vector<gl::Polygon>& polygons_out, |
63 ldraw::GetPolygonsContext* context) const; |
77 ldraw::GetPolygonsContext* context) const; |
64 bool modified = false; |
78 bool modified = false; |
65 QString path; |
79 QString path; |
66 LDHeader header; |
80 LDHeader header; |
67 std::vector<ModelObjectPointer> body; |
81 std::vector<ModelObjectPointer> body; |
68 std::map<ldraw::Id, ldraw::Object*> objectsById; |
82 std::map<ldraw::id_t, ldraw::Object*> objectsById; |
69 mutable std::vector<gl::Polygon> cachedPolygons; |
83 mutable std::vector<gl::Polygon> cachedPolygons; |
70 mutable bool needRecache = true; |
84 mutable bool needRecache = true; |
71 }; |
85 }; |
72 |
86 |
|
87 /** |
|
88 * \brief Checks type of object behind id |
|
89 * Checks whether the specified id refers to an object of the specified type. |
|
90 * \returns id casted to subclass if appropriate, null id otherwise |
|
91 */ |
|
92 template<typename R> |
|
93 ldraw::Id<R> Model::checkType(ldraw::id_t id) const |
|
94 { |
|
95 if (dynamic_cast<const R*>(this->objectAt(this->lookup(id))) != nullptr) |
|
96 { |
|
97 return ldraw::Id<R>{id.value}; |
|
98 } |
|
99 else |
|
100 { |
|
101 return ldraw::NULL_ID; |
|
102 } |
|
103 } |
|
104 |
73 template<typename T, typename... Args> |
105 template<typename T, typename... Args> |
74 ldraw::Id Model::append(Args&&... args) |
106 ldraw::Id<T> Model::append(Args&&... args) |
75 { |
107 { |
76 emit layoutAboutToBeChanged(); |
108 emit layoutAboutToBeChanged(); |
77 this->body.push_back(std::make_unique<T>(args...)); |
109 this->body.push_back(std::make_unique<T>(args...)); |
78 ldraw::Object* pointer = this->body.back().get(); |
110 ldraw::Object* pointer = this->body.back().get(); |
79 this->objectsById[pointer->id] = pointer; |
111 this->objectsById[pointer->id] = pointer; |
80 emit objectAdded(pointer->id, this->body.size() - 1); |
112 emit objectAdded(pointer->id, this->body.size() - 1); |
81 emit layoutChanged(); |
113 emit layoutChanged(); |
82 return pointer->id; |
114 return ldraw::Id<T>{pointer->id}; |
83 } |
115 } |
84 |
116 |
85 template<typename T, typename... Args> |
117 template<typename T, typename... Args> |
86 ldraw::Id Model::insert(int position, Args&&... args) |
118 ldraw::Id<T> Model::insert(int position, Args&&... args) |
87 { |
119 { |
88 emit layoutAboutToBeChanged(); |
120 emit layoutAboutToBeChanged(); |
89 this->body.insert(position, std::make_unique<T>(args...)); |
121 this->body.insert(position, std::make_unique<T>(args...)); |
90 ldraw::Object* pointer = this->body[position].get(); |
122 ldraw::Object* pointer = this->body[position].get(); |
91 this->objectsById[pointer->id] = pointer; |
123 this->objectsById[pointer->id] = pointer; |
92 emit objectAdded(pointer->id, position); |
124 emit objectAdded(pointer->id, position); |
93 emit layoutChanged(); |
125 emit layoutChanged(); |
94 return pointer->id; |
126 return ldraw::Id<T>{pointer->id}; |
95 } |
127 } |
|
128 |
|
129 template<typename R> |
|
130 const R* Model::get(ldraw::Id<R> id) const |
|
131 { |
|
132 return this->objectAt(id); |
|
133 } |