Wrote documentation to the Model class.

Sat, 04 Feb 2017 14:44:39 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 04 Feb 2017 14:44:39 +0200
changeset 1091
4a754362f660
parent 1090
ed73c4f48ca4
child 1092
7a50a7f6b492

Wrote documentation to the Model class.

src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
--- a/src/model.cpp	Sat Feb 04 14:24:16 2017 +0200
+++ b/src/model.cpp	Sat Feb 04 14:44:39 2017 +0200
@@ -1,3 +1,21 @@
+/*
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
 #include "model.h"
 #include "ldObject.h"
 #include "documentmanager.h"
@@ -11,21 +29,33 @@
 		delete _objects[i];
 }
 
+/*
+ * Takes an existing object and migrates it to the end of this model. The object is removed from its old model in the process.
+ */
 void Model::addObject(LDObject *object)
 {
 	insertObject(size(), object);
 }
 
+/*
+ * Returns the amount of objects in this model.
+ */
 int Model::size() const
 {
 	return _objects.size();
 }
 
+/*
+ * Returns the vector of objects in this model.
+ */
 const QVector<LDObject*>& Model::objects() const
 {
 	return _objects;
 }
 
+/*
+ * Takes an existing object and migrates it to this model, at the specified position.
+ */
 void Model::insertObject(int position, LDObject* object)
 {
 	if (object->model() and object->model() != this)
@@ -35,9 +65,11 @@
 	_objects.insert(position, object);
 	_needsTriangleRecount = true;
 	object->setDocument(this);
-	print("Object %1 added to position %2", object->id(), position);
 }
 
+/*
+ * Swaps one object with another, assuming they both are in this model.
+ */
 bool Model::swapObjects(LDObject* one, LDObject* other)
 {
 	int a = _objects.indexOf(one);
@@ -55,6 +87,9 @@
 	}
 }
 
+/*
+ * Assigns a new object to the specified position in the model. The object that already is in the position is deleted in the process.
+ */
 bool Model::setObjectAt(int idx, LDObject* obj)
 {
 	if (idx < 0 or idx >= countof(_objects))
@@ -69,6 +104,9 @@
 	}
 }
 
+/*
+ * Returns the object at the specified position, or null if not found.
+ */
 LDObject* Model::getObject(int position) const
 {
 	if (position >= 0 and position < countof(_objects))
@@ -77,20 +115,28 @@
 		return nullptr;
 }
 
+/*
+ * Removes the given object from the model.
+ */
 void Model::remove(LDObject* object)
 {
 	int position = object->lineNumber();
-	printf("Going to remove %d from %p at %d (there are %d objects)\n", object->id(), this, position, countof(objects()));
 	if (_objects[position] == object)
 		removeAt(position);
 }
 
+/*
+ * Removes the object at the provided position.
+ */
 void Model::removeAt(int position)
 {
 	LDObject* object = withdrawAt(position);
 	delete object;
 }
 
+/*
+ * Replaces the given object with the contents of a model.
+ */
 void Model::replace(LDObject *object, Model &model)
 {
 	if (object->model() == this)
@@ -104,11 +150,17 @@
 	}
 }
 
+/*
+ * Signals the model to recount its triangles.
+ */
 void Model::recountTriangles()
 {
 	_needsTriangleRecount = true;
 }
 
+/*
+ * Returns the triangle count in the model.
+ */
 int Model::triangleCount() const
 {
 	if (_needsTriangleRecount)
@@ -124,6 +176,9 @@
 	return _triangleCount;
 }
 
+/*
+ * Merges the given model into this model, starting at the given position. The other model is emptied in the process.
+ */
 void Model::merge(Model& other, int position)
 {
 	if (position < 0)
@@ -142,34 +197,45 @@
 	other.clear();
 }
 
+/*
+ * Returns the begin-iterator into this model, so that models can be used in foreach-loops.
+ */
 QVector<LDObject*>::iterator Model::begin()
 {
 	return _objects.begin();
 }
 
+/*
+ * Returns the end-iterator into this mode, so that models can be used in foreach-loops.
+ */
 QVector<LDObject*>::iterator Model::end()
 {
 	return _objects.end();
 }
 
+/*
+ * Removes all objects in this model.
+ */
 void Model::clear()
 {
 	for (int i = _objects.size() - 1; i >= 0; i -= 1)
 		removeAt(i);
 
-	_needsTriangleRecount = true;
+	_triangleCount = 0;
+	_needsTriangleRecount = false;
 }
 
 /*
  * Drops the object from the model. The object becomes a free object as a result (thus violating the invariant that every object
  * has a model!). The caller must immediately add the withdrawn object to another model.
+ *
+ * This private method is only used to implement public API.
  */
 void Model::withdraw(LDObject* object)
 {
 	if (object->model() == this)
 	{
 		int position = object->lineNumber();
-		print("Withdrawing %1 from %2 at %3\n", object->id(), this, position);
 
 		if (_objects[position] == object)
 			withdrawAt(position);
@@ -187,11 +253,17 @@
 	return object;
 }
 
+/*
+ * Returns whether or not this model is empty.
+ */
 bool Model::isEmpty() const
 {
 	return _objects.isEmpty();
 }
 
+/*
+ * Returns the model's associated document manager. This pointer is used to resolve subfile references.
+ */
 DocumentManager* Model::documentManager() const
 {
 	return _manager;
@@ -434,11 +506,18 @@
 	}
 }
 
+/*
+ * Given an LDraw object string, parses it and inserts it into the model.
+ */
 LDObject* Model::addFromString(QString line)
 {
 	return insertFromString(size(), line);
 }
 
+/*
+ * Replaces the given object with a new one that is parsed from the given LDraw object string.
+ * If the parsing fails, the object is replaced with an error object.
+ */
 LDObject* Model::replaceWithFromString(LDObject* object, QString line)
 {
 	if (object and object->model() == this)
--- 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 <http://www.gnu.org/licenses/>.
+ */
+
 #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<typename T, typename... Args> T* emplace(Args&& ...args);
+	template<typename T, typename... Args> T* emplaceAt(int position, Args&& ...args);
+	template<typename T, typename... Args> T* emplaceReplacement(LDObject* object, Args&& ...args);
+	template<typename T, typename... Args> 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<typename T, typename... Args>
-	T* emplace(Args&& ...args)
-	{
-		T* object = constructObject<T>(args...);
-		addObject(object);
-		return object;
-	}
-
-	template<typename T, typename... Args>
-	T* emplaceAt(int position, Args&& ...args)
-	{
-		T* object = constructObject<T>(args...);
-		insertObject(position, object);
-		return object;
-	}
-
-	template<typename T, typename... Args>
-	T* emplaceReplacement(LDObject* object, Args&& ...args)
-	{
-		if (object->model() == this)
-		{
-			int position = object->lineNumber();
-			T* replacement = constructObject<T>(args...);
-			setObjectAt(position, replacement);
-			return replacement;
-		}
-		else
-			return nullptr;
-	}
-
-	template<typename T, typename... Args>
-	T* emplaceReplacementAt(int position, Args&& ...args)
-	{
-		T* replacement = constructObject<T>(args...);
-		setObjectAt(position, replacement);
-		return replacement;
-	}
-
 protected:
-	template<typename T, typename... Args>
-	T* constructObject(Args&& ...args)
-	{
-		static_assert (std::is_base_of<LDObject, T>::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<typename T, typename... Args> 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<LDLine>(v1, v2);
+ */
+template<typename T, typename... Args>
+T* Model::emplace(Args&& ...args)
+{
+	T* object = constructObject<T>(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<typename T, typename... Args>
+T* Model::emplaceAt(int position, Args&& ...args)
+{
+	T* object = constructObject<T>(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<typename T, typename... Args>
+T* Model::emplaceReplacement(LDObject* object, Args&& ...args)
+{
+	if (object->model() == this)
+	{
+		int position = object->lineNumber();
+		T* replacement = constructObject<T>(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<typename T, typename... Args>
+T* Model::emplaceReplacementAt(int position, Args&& ...args)
+{
+	T* replacement = constructObject<T>(args...);
+	setObjectAt(position, replacement);
+	return replacement;
+}
+
+/*
+ * Constructs an LDObject such that it gets this model as its model pointer.
+ */
+template<typename T, typename... Args>
+T* Model::constructObject(Args&& ...args)
+{
+	static_assert (std::is_base_of<LDObject, T>::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

mercurial