src/model.h

Sun, 29 Jan 2017 15:05:14 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sun, 29 Jan 2017 15:05:14 +0200
changeset 1073
a0a0d581309b
child 1074
a62f810ca26f
permissions
-rw-r--r--

Major overhaul of object→document relationship: added the Model class which models the object buffer. Each object is to be included in a model (an invariant that currently does not hold). A document is a subclass of a model. The LDObject is also now agnostic about selection, and the selection is now a set. A lot of things are probably broken now but it's a major step forward.
The LDObject::destroy method is also now gone. The model decides when objects are destroyed and calls the destructor directly. The end result removes a lot of cruft and adds structure to LDObject relations.

Notes:
- Inlining does not currently work (nothing simply gets inlined in)
- More work is required to ensure that each object actually goes into a model

#pragma once
#include "main.h"
#include "ldObject.h"

class Model
{
public:
	Model();
	Model(const Model& other) = delete;
	~Model();

	virtual 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);
	void removeAt(int position);
	void remove(LDObject* object);
	void replace(LDObject *object, Model& model);
	void clear();
	void merge(Model& other, int position = -1);
	void replace(LDObject* object, LDObject* newObject);
	int size() const;
	const QVector<LDObject*>& objects() const;
	LDObject* getObject(int position) const;
	void recountTriangles();
	int triangleCount() const;
	QVector<LDObject*>::iterator begin();
	QVector<LDObject*>::iterator end();

	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;
	}

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;
	}

	void withdraw(LDObject* object);
	virtual LDObject* withdrawAt(int position);

	QVector<LDObject*> _objects;
	mutable int _triangleCount = 0;
	mutable bool _needsTriangleRecount;
};

mercurial