diff -r ed73c4f48ca4 -r 4a754362f660 src/model.h
--- a/src/model.h Sat Feb 04 14:24:16 2017 +0200
+++ b/src/model.h Sat Feb 04 14:44:39 2017 +0200
@@ -1,7 +1,28 @@
+/*
+ * LDForge: LDraw parts authoring CAD
+ * Copyright (C) 2013 - 2017 Teemu Piippo
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
#pragma once
#include "main.h"
#include "ldObject.h"
+/*
+ * This class represents a LDraw model, consisting of a vector of objects. It manages LDObject ownership.
+ */
class Model
{
public:
@@ -9,10 +30,14 @@
Model(const Model& other) = delete;
~Model();
- virtual void addObject(LDObject* object);
+ void addObject(LDObject* object);
virtual void insertObject(int position, LDObject* object);
virtual bool swapObjects(LDObject* one, LDObject* other);
virtual bool setObjectAt(int idx, LDObject* obj);
+ template T* emplace(Args&& ...args);
+ template T* emplaceAt(int position, Args&& ...args);
+ template T* emplaceReplacement(LDObject* object, Args&& ...args);
+ template T* emplaceReplacementAt(int position, Args&& ...args);
void removeAt(int position);
void remove(LDObject* object);
void replace(LDObject *object, Model& model);
@@ -31,59 +56,8 @@
LDObject* addFromString(QString line);
LDObject* replaceWithFromString(LDObject* object, QString line);
- template
- T* emplace(Args&& ...args)
- {
- T* object = constructObject(args...);
- addObject(object);
- return object;
- }
-
- template
- T* emplaceAt(int position, Args&& ...args)
- {
- T* object = constructObject(args...);
- insertObject(position, object);
- return object;
- }
-
- template
- T* emplaceReplacement(LDObject* object, Args&& ...args)
- {
- if (object->model() == this)
- {
- int position = object->lineNumber();
- T* replacement = constructObject(args...);
- setObjectAt(position, replacement);
- return replacement;
- }
- else
- return nullptr;
- }
-
- template
- T* emplaceReplacementAt(int position, Args&& ...args)
- {
- T* replacement = constructObject(args...);
- setObjectAt(position, replacement);
- return replacement;
- }
-
protected:
- template
- T* constructObject(Args&& ...args)
- {
- static_assert (std::is_base_of::value, "Can only use this function with LDObject-derivatives");
- T* object = new T {args..., this};
-
- // Set default color. Relying on virtual functions, this cannot be done in the c-tor.
- // TODO: store -1 as the default color
- if (object->isColored())
- object->setColor(object->defaultColor());
-
- return object;
- }
-
+ template T* constructObject(Args&& ...args);
void withdraw(LDObject* object);
virtual LDObject* withdrawAt(int position);
@@ -94,3 +68,83 @@
};
int countof(Model& model);
+
+/*
+ * Given an LDObject type as the template parameter, and any number of variadic parameters, constructs an LDObject derivative
+ * and inserts it into this model. The variadic parameters and this model pointer are passed to the constructor. The constructed object
+ * is added to the end of the model.
+ *
+ * For instance, the LDLine contains a constructor as such:
+ *
+ * LDLine(Vertex v1, Vertex v2, Model* model);
+ *
+ * This constructor can be invoked as such:
+ *
+ * model->emplace(v1, v2);
+ */
+template
+T* Model::emplace(Args&& ...args)
+{
+ T* object = constructObject(args...);
+ addObject(object);
+ return object;
+}
+
+/*
+ * Like emplace<>() but also takes a position as the first argument and emplaces the object at the given position instead of the
+ * end of the model.
+ */
+template
+T* Model::emplaceAt(int position, Args&& ...args)
+{
+ T* object = constructObject(args...);
+ insertObject(position, object);
+ return object;
+}
+
+/*
+ * Like emplace<>() but instead of inserting the constructed object, the new object replaces the object given in the first parameter.
+ * If the old object cannot be replaced, the new object will not be constructed at all.
+ */
+template
+T* Model::emplaceReplacement(LDObject* object, Args&& ...args)
+{
+ if (object->model() == this)
+ {
+ int position = object->lineNumber();
+ T* replacement = constructObject(args...);
+ setObjectAt(position, replacement);
+ return replacement;
+ }
+ else
+ return nullptr;
+}
+
+/*
+ * Like emplaceAt<>() but instead of inserting the constructed object, it replaces the document at the given spot instead.
+ * The replaced object is deleted in the process.
+ */
+template
+T* Model::emplaceReplacementAt(int position, Args&& ...args)
+{
+ T* replacement = constructObject(args...);
+ setObjectAt(position, replacement);
+ return replacement;
+}
+
+/*
+ * Constructs an LDObject such that it gets this model as its model pointer.
+ */
+template
+T* Model::constructObject(Args&& ...args)
+{
+ static_assert (std::is_base_of::value, "Can only use this function with LDObject-derivatives");
+ T* object = new T {args..., this};
+
+ // Set default color. Relying on virtual functions, this cannot be done in the c-tor.
+ // TODO: store -1 as the default color
+ if (object->isColored())
+ object->setColor(object->defaultColor());
+
+ return object;
+}
\ No newline at end of file