ldraw::Id is now templated for extra type safety

Mon, 09 Mar 2020 14:21:54 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 09 Mar 2020 14:21:54 +0200
changeset 73
97df974b5ed5
parent 72
7c27cda03747
child 74
6b51e7b7c459

ldraw::Id is now templated for extra type safety

src/colors.h file | annotate | diff | comparison | revisions
src/document.cpp file | annotate | diff | comparison | revisions
src/gl/common.h file | annotate | diff | comparison | revisions
src/gl/compiler.cpp file | annotate | diff | comparison | revisions
src/gl/compiler.h file | annotate | diff | comparison | revisions
src/gl/partrenderer.cpp file | annotate | diff | comparison | revisions
src/gl/partrenderer.h file | annotate | diff | comparison | revisions
src/linetypes/object.h file | annotate | diff | comparison | revisions
src/linetypes/triangle.h file | annotate | diff | comparison | revisions
src/main.cpp file | annotate | diff | comparison | revisions
src/main.h file | annotate | diff | comparison | revisions
src/model.cpp file | annotate | diff | comparison | revisions
src/model.h file | annotate | diff | comparison | revisions
src/modeleditcontext.cpp file | annotate | diff | comparison | revisions
src/modeleditcontext.h file | annotate | diff | comparison | revisions
src/ui/canvas.cpp file | annotate | diff | comparison | revisions
src/ui/canvas.h file | annotate | diff | comparison | revisions
--- a/src/colors.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/colors.h	Mon Mar 09 14:21:54 2020 +0200
@@ -49,34 +49,37 @@
 	QMap<qint32, ColorDefinition> definitions;
 };
 
-inline bool operator==(const ldraw::Color& one, const ldraw::Color& other)
-{
-	return one.index == other.index;
-}
-
-inline bool operator!=(const ldraw::Color& one, const ldraw::Color& other)
-{
-	return one.index != other.index;
-}
-
-inline bool operator<(const ldraw::Color& one, const ldraw::Color& other)
+namespace ldraw
 {
-	return one.index < other.index;
-}
+	inline bool operator==(const ldraw::Color& one, const ldraw::Color& other)
+	{
+		return one.index == other.index;
+	}
 
-inline bool operator<=(const ldraw::Color& one, const ldraw::Color& other)
-{
-	return one.index <= other.index;
-}
+	inline bool operator!=(const ldraw::Color& one, const ldraw::Color& other)
+	{
+		return one.index != other.index;
+	}
+
+	inline bool operator<(const ldraw::Color& one, const ldraw::Color& other)
+	{
+		return one.index < other.index;
+	}
 
-inline bool operator>(const ldraw::Color& one, const ldraw::Color& other)
-{
-	return one.index > other.index;
-}
+	inline bool operator<=(const ldraw::Color& one, const ldraw::Color& other)
+	{
+		return one.index <= other.index;
+	}
 
-inline bool operator>=(const ldraw::Color& one, const ldraw::Color& other)
-{
-	return one.index >= other.index;
+	inline bool operator>(const ldraw::Color& one, const ldraw::Color& other)
+	{
+		return one.index > other.index;
+	}
+
+	inline bool operator>=(const ldraw::Color& one, const ldraw::Color& other)
+	{
+		return one.index >= other.index;
+	}
 }
 
 namespace ldraw
--- a/src/document.cpp	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/document.cpp	Mon Mar 09 14:21:54 2020 +0200
@@ -41,11 +41,11 @@
 	this->setMouseTracking(true);
 	connect(this->ui.splitter, &QSplitter::splitterMoved, this, &Document::splitterChanged);
 	connect(this->renderer, &Canvas::newStatusText, this, &Document::newStatusText);
-	connect(this->renderer, &Canvas::selectionChanged, [&](const QSet<ldraw::Id>& newSelection)
+	connect(this->renderer, &Canvas::selectionChanged, [&](const QSet<ldraw::id_t>& newSelection)
 	{
 		QItemSelectionModel* selectionModel = this->ui.listView->selectionModel();
 		QItemSelection selection;
-		for (ldraw::Id id : newSelection)
+		for (ldraw::id_t id : newSelection)
 		{
 			QModelIndex index = this->model->lookup(id);
 			if (index != QModelIndex{})
@@ -61,7 +61,7 @@
 		auto resolveIndex = [this](const QModelIndex& index){ return this->model->resolve(index); };
 		auto resolve = [resolveIndex](const QItemSelection& selection)
 		{
-			return fn::map<QSet<ldraw::Id>>(selection.indexes(), resolveIndex);
+			return fn::map<QSet<ldraw::id_t>>(selection.indexes(), resolveIndex);
 		};
 		this->renderer->handleSelectionChange(resolve(selected), resolve(deselected));
 	});
--- a/src/gl/common.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/gl/common.h	Mon Mar 09 14:21:54 2020 +0200
@@ -77,7 +77,7 @@
 	Type type;
 	glm::vec3 vertices[4];
 	ldraw::Color color;
-	ldraw::Id id;
+	ldraw::id_t id;
 
 	/**
 	 * @return amount of vertices used for geometry
@@ -113,7 +113,7 @@
 
 namespace gl
 {
-	inline Polygon edgeLine(const glm::vec3& v_1, const glm::vec3& v_2, ldraw::Color color, ldraw::Id id)
+	inline Polygon edgeLine(const glm::vec3& v_1, const glm::vec3& v_2, ldraw::Color color, ldraw::id_t id)
 	{
 		return {Polygon::EdgeLine, {v_1, v_2}, color, id};
 	}
@@ -123,7 +123,7 @@
 		const glm::vec3& v_2,
 		const glm::vec3& v_3,
 		ldraw::Color color,
-		ldraw::Id id)
+		ldraw::id_t id)
 	{
 		return {Polygon::Triangle, {v_1, v_2, v_3}, color, id};
 	}
@@ -134,7 +134,7 @@
 		const glm::vec3& v_3,
 		const glm::vec3& v_4,
 		ldraw::Color color,
-		ldraw::Id id)
+		ldraw::id_t id)
 	{
 		return {Polygon::Quadrilateral, {v_1, v_2, v_3, v_4}, color, id};
 	}
@@ -145,7 +145,7 @@
 		const glm::vec3& control_1,
 		const glm::vec3& control_2,
 		ldraw::Color color,
-		ldraw::Id id)
+		ldraw::id_t id)
 	{
 		return {Polygon::ConditionalEdge, {v_1, v_2, control_1, control_2}, color, id};
 	}
--- a/src/gl/compiler.cpp	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/gl/compiler.cpp	Mon Mar 09 14:21:54 2020 +0200
@@ -237,7 +237,7 @@
 	return gl::ArrayClass::Lines;
 }
 
-ldraw::Id gl::Compiler::idFromColor(const std::array<GLbyte, 3>& data)
+ldraw::id_t gl::Compiler::idFromColor(const std::array<GLbyte, 3>& data)
 {
 	return {data[0] * std::int32_t{0x10000} + data[1] * std::int32_t{0x100} + data[2]};
 }
@@ -311,7 +311,7 @@
 	object.vertexArray.release();
 }
 
-void gl::Compiler::setSelectedObjects(const QSet<ldraw::Id> ids)
+void gl::Compiler::setSelectedObjects(const QSet<ldraw::id_t> ids)
 {
 	for (int i = 0; i < gl::NUM_ARRAY_CLASSES; i += 1)
 	{
--- a/src/gl/compiler.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/gl/compiler.h	Mon Mar 09 14:21:54 2020 +0200
@@ -61,9 +61,9 @@
 	void bindVertexArray(gl::ArrayClass arrayClass);
 	void releaseVertexArray(gl::ArrayClass arrayClass);
 	void buildShaders(int arrayId);
-	void setSelectedObjects(const QSet<ldraw::Id> ids);
+	void setSelectedObjects(const QSet<ldraw::id_t> ids);
 
-	static ldraw::Id idFromColor(const std::array<GLbyte, 3>& data);
+	static ldraw::id_t idFromColor(const std::array<GLbyte, 3>& data);
 
 	template<typename T>
 	void setUniform(const char* uniformName, T&& value)
@@ -90,7 +90,7 @@
 	bool initialized = false;
 	BoundingBox boundingBox;
 	const ldraw::ColorTable& colorTable;
-	ldraw::Id hovered = ldraw::NULL_ID;
+	ldraw::id_t hovered = ldraw::NULL_ID;
 	struct
 	{
 		QOpenGLShaderProgram* program = nullptr;
--- a/src/gl/partrenderer.cpp	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/gl/partrenderer.cpp	Mon Mar 09 14:21:54 2020 +0200
@@ -330,7 +330,7 @@
 		viewportVector);
 }
 
-ldraw::Id PartRenderer::pick(const QPoint& where)
+ldraw::id_t PartRenderer::pick(const QPoint& where)
 {
 	const gl::RenderStyle oldRenderStyle = this->renderPreferences.style;
 	this->renderPreferences.style = gl::RenderStyle::PickScene;
--- a/src/gl/partrenderer.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/gl/partrenderer.h	Mon Mar 09 14:21:54 2020 +0200
@@ -23,7 +23,7 @@
 	~PartRenderer() override;
 	void setRenderPreferences(const gl::RenderPreferences& newPreferences);
 protected:
-	ldraw::Id pick(const QPoint& where);
+	ldraw::id_t pick(const QPoint& where);
 	void initializeGL() override;
 	void resizeGL(int width, int height) override;
 	void paintGL() override;
@@ -33,7 +33,7 @@
 	DocumentManager* const documents;
 	const ldraw::ColorTable& colorTable;
 	gl::Compiler* const compiler;
-	ldraw::Id highlighted = ldraw::NULL_ID;
+	ldraw::id_t highlighted = ldraw::NULL_ID;
 	std::optional<glm::vec3> screenToModelCoordinates(const QPoint& point, const geom::Plane& plane) const;
 	QPointF modelToScreenCoordinates(const glm::vec3& point) const;
 	geom::Line<3> cameraLine(const QPoint& point) const;
--- a/src/linetypes/object.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/linetypes/object.h	Mon Mar 09 14:21:54 2020 +0200
@@ -53,7 +53,7 @@
 	Object();
 	Object(const Object&) = delete;
 	virtual ~Object();
-	const Id id;
+	const id_t id;
 	//virtual void toString(QTextStream &out) = 0;
 	virtual bool hasColor() const;
 	virtual QVariant getProperty(Property id) const;
--- a/src/linetypes/triangle.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/linetypes/triangle.h	Mon Mar 09 14:21:54 2020 +0200
@@ -1,3 +1,4 @@
+#pragma once
 #include "object.h"
 
 namespace ldraw
--- a/src/main.cpp	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/main.cpp	Mon Mar 09 14:21:54 2020 +0200
@@ -21,6 +21,8 @@
 #include "mainwindow.h"
 #include "version.h"
 
+#include "linetypes/quadrilateral.h"
+
 int main(int argc, char *argv[])
 {
 	::glutInit(&argc, argv);
--- a/src/main.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/main.h	Mon Mar 09 14:21:54 2020 +0200
@@ -35,25 +35,65 @@
 
 namespace ldraw
 {
+	class Object;
+
 	// Uniquely identifies a model body object
+	template<typename T>
 	struct Id
 	{
 		std::int32_t value;
-		constexpr bool operator<(ldraw::Id other) const
+		template<typename A, typename B>
+		static constexpr bool is_base_or_base_of = std::disjunction_v<std::is_base_of<A, B>, std::is_base_of<B, A>>;
+		template<typename R, typename = std::enable_if_t<is_base_or_base_of<T, R>>>
+		constexpr bool operator<(ldraw::Id<R> other) const
 		{
 			return this->value < other.value;
 		}
-		friend constexpr unsigned int qHash(ldraw::Id id)
+		friend constexpr unsigned int qHash(ldraw::Id<T> id)
 		{
 			return qHash(id.value);
 		}
-		friend bool operator==(ldraw::Id one, ldraw::Id other)
+		// Allow comparing ids as long as they are related
+		template<typename R, typename = std::enable_if_t<is_base_or_base_of<T, R>>>
+		friend bool operator==(ldraw::Id<T> one, ldraw::Id<R> other)
 		{
 			return one.value == other.value;
 		}
+		// Allow upcasting
+		template<typename R, typename = std::enable_if_t<std::is_base_of_v<R, T>>>
+		constexpr operator Id<R>() const
+		{
+			return Id<R>{this->value};
+		}
 	};
-	using id_t = Id;
-	constexpr id_t NULL_ID = id_t{0};
+
+	using id_t = Id<Object>;
+	using triangleid_t = Id<class Triangle>;
+	using quadrilateralid_t = Id<class Quadrilateral>;
+	using edgeid_t = Id<class EdgeLine>;
+	using conditionaledgeid_t = Id<class ConditionalEdge>;
+	using subfileid_t = Id<class SubfileReference>;
+
+	constexpr struct
+	{
+		template<typename T>
+		constexpr operator Id<T>() const
+		{
+			return Id<T>{0};
+		}
+	} NULL_ID = {};
+
+	template<typename T>
+	inline bool operator==(Id<T> one, decltype(NULL_ID))
+	{
+		return one.value == 0;
+	}
+
+	template<typename T>
+	inline bool operator<(Id<T> one, decltype(NULL_ID))
+	{
+		return one.value < 0;
+	}
 }
 
 constexpr std::size_t operator""_z(const unsigned long long int x)
--- a/src/model.cpp	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/model.cpp	Mon Mar 09 14:21:54 2020 +0200
@@ -88,7 +88,7 @@
 	return this->cachedPolygons;
 }
 
-QModelIndex Model::lookup(ldraw::Id id) const
+QModelIndex Model::lookup(ldraw::id_t id) const
 {
 	// FIXME: This linear search will probably cause performance issues
 	for (std::size_t i = 0; i < this->body.size(); i += 1)
@@ -101,7 +101,7 @@
 	return {};
 }
 
-ldraw::Id Model::resolve(const QModelIndex& index) const
+ldraw::id_t Model::resolve(const QModelIndex& index) const
 {
 	return this->objectAt(index)->id;
 }
--- a/src/model.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/model.h	Mon Mar 09 14:21:54 2020 +0200
@@ -44,19 +44,33 @@
 	const QString& getName() const;
 	QVariant getObjectProperty(const int index, const ldraw::Property property) const;
 	std::vector<gl::Polygon> getPolygons(class DocumentManager* documents) const;
-	QModelIndex lookup(ldraw::Id id) const;
-	ldraw::Id resolve(const QModelIndex& index) const;
+	QModelIndex lookup(ldraw::id_t id) const;
+	ldraw::id_t resolve(const QModelIndex& index) const;
+	template<typename R>
+	ldraw::Id<R> checkType(ldraw::id_t id) const;
+	template<typename R>
+	const R* get(ldraw::Id<R> id) const;
 signals:
-	void objectAdded(ldraw::Id id, int position);
+	void objectAdded(ldraw::id_t id, int position);
 private:
 	using ModelObjectPointer = std::unique_ptr<ldraw::Object>;
 	template<typename T, typename... Args>
-	ldraw::Id append(Args&&... args);
+	ldraw::Id<T> append(Args&&... args);
 	void append(ModelObjectPointer&& object);
 	template<typename T, typename... Args>
-	ldraw::Id insert(int position, Args&&... args);
+	ldraw::Id<T> insert(int position, Args&&... args);
 	ldraw::Object* objectAt(const QModelIndex& index);
 	const ldraw::Object* objectAt(const QModelIndex& index) const;
+	template<typename T>
+	T* objectAt(ldraw::Id<T> id)
+	{
+		return static_cast<T*>(this->objectAt(this->lookup(id)));
+	}
+	template<typename T>
+	const T* objectAt(ldraw::Id<T> id) const
+	{
+		return static_cast<const T*>(this->objectAt(this->lookup(id)));
+	}
 	void getObjectPolygons(
 		const int index,
 		std::vector<gl::Polygon>& polygons_out,
@@ -65,13 +79,31 @@
 	QString path;
 	LDHeader header;
 	std::vector<ModelObjectPointer> body;
-	std::map<ldraw::Id, ldraw::Object*> objectsById;
+	std::map<ldraw::id_t, ldraw::Object*> objectsById;
 	mutable std::vector<gl::Polygon> cachedPolygons;
 	mutable bool needRecache = true;
 };
 
+/**
+ * \brief Checks type of object behind id
+ * Checks whether the specified id refers to an object of the specified type.
+ * \returns id casted to subclass if appropriate, null id otherwise
+ */
+template<typename R>
+ldraw::Id<R> Model::checkType(ldraw::id_t id) const
+{
+	if (dynamic_cast<const R*>(this->objectAt(this->lookup(id))) != nullptr)
+	{
+		return ldraw::Id<R>{id.value};
+	}
+	else
+	{
+		return ldraw::NULL_ID;
+	}
+}
+
 template<typename T, typename... Args>
-ldraw::Id Model::append(Args&&... args)
+ldraw::Id<T> Model::append(Args&&... args)
 {
 	emit layoutAboutToBeChanged();
 	this->body.push_back(std::make_unique<T>(args...));
@@ -79,11 +111,11 @@
 	this->objectsById[pointer->id] = pointer;
 	emit objectAdded(pointer->id, this->body.size() - 1);
 	emit layoutChanged();
-	return pointer->id;
+	return ldraw::Id<T>{pointer->id};
 }
 
 template<typename T, typename... Args>
-ldraw::Id Model::insert(int position, Args&&... args)
+ldraw::Id<T> Model::insert(int position, Args&&... args)
 {
 	emit layoutAboutToBeChanged();
 	this->body.insert(position, std::make_unique<T>(args...));
@@ -91,5 +123,11 @@
 	this->objectsById[pointer->id] = pointer;
 	emit objectAdded(pointer->id, position);
 	emit layoutChanged();
-	return pointer->id;
+	return ldraw::Id<T>{pointer->id};
 }
+
+template<typename R>
+const R* Model::get(ldraw::Id<R> id) const
+{
+	return this->objectAt(id);
+}
--- a/src/modeleditcontext.cpp	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/modeleditcontext.cpp	Mon Mar 09 14:21:54 2020 +0200
@@ -19,15 +19,15 @@
 #include "modeleditcontext.h"
 
 Model::EditContext::EditContext(Model& model) :
-	model{model}
+	storedModel{model}
 {
 }
 
-ldraw::Id Model::EditContext::append(std::unique_ptr<ldraw::Object>&& object)
+ldraw::id_t Model::EditContext::append(std::unique_ptr<ldraw::Object>&& object)
 {
-	const ldraw::Id id = object->id;
-	this->model.objectsById[id] = object.get();
-	this->model.append(std::move(object));
+	const ldraw::id_t id = object->id;
+	this->model().objectsById[id] = object.get();
+	this->model().append(std::move(object));
 	return id;
 }
 
@@ -39,12 +39,32 @@
 	object->setProperty(property, value);
 }
 
-void Model::EditContext::invertObject(ldraw::Id id)
+void Model::EditContext::invertObject(ldraw::id_t id)
 {
-	auto it = this->model.objectsById.find(id);
-	if (it != this->model.objectsById.end())
+	auto it = this->model().objectsById.find(id);
+	if (it != this->model().objectsById.end())
 	{
 		ldraw::Object* object = it->second;
 		object->invert();
 	}
 }
+
+Model& Model::EditContext::model()
+{
+	return this->storedModel;
+}
+
+auto ldraw::splitQuadrilateral(
+	Model::EditContext& editor,
+	ldraw::quadrilateralid_t quadrilateral_id,
+	ldraw::QuadrilateralSplit splitType
+) -> std::optional<std::pair<ldraw::triangleid_t, ldraw::triangleid_t>>
+{
+	std::optional<std::pair<ldraw::triangleid_t, ldraw::triangleid_t>> result;
+	const ldraw::Quadrilateral* quadrilateral = editor.model().get(quadrilateral_id);
+	if (quadrilateral != nullptr)
+	{
+
+	}
+	return result;
+}
--- a/src/modeleditcontext.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/modeleditcontext.h	Mon Mar 09 14:21:54 2020 +0200
@@ -19,34 +19,54 @@
 #pragma once
 #include "model.h"
 #include "linetypes/object.h"
+#include "linetypes/quadrilateral.h"
+#include "linetypes/triangle.h"
 
 class Model::EditContext
 {
 public:
 	template<typename T, typename... Args>
-	ldraw::Id append(Args&&... args);
-	ldraw::Id append(std::unique_ptr<ldraw::Object>&& object);
+	ldraw::id_t append(Args&&... args);
+	ldraw::id_t append(std::unique_ptr<ldraw::Object>&& object);
 	template<typename T, typename... Args>
-	ldraw::Id insert(int position, Args&&... args);
+	ldraw::id_t insert(int position, Args&&... args);
 	void setObjectProperty(
 		ldraw::Object* object,
 		ldraw::Property property,
 		const QVariant &value);
-	void invertObject(ldraw::Id id);
+	void invertObject(ldraw::id_t id);
+	Model& model();
 private:
 	EditContext(Model& model);
 	friend class Model;
-	Model& model;
+	Model& storedModel;
 };
 
 template<typename T, typename... Args>
-ldraw::Id Model::EditContext::append(Args&&... args)
+ldraw::id_t Model::EditContext::append(Args&&... args)
 {
-	return this->model.append<T>(args...);
+	return this->storedModel.append<T>(args...);
 }
 
 template<typename T, typename... Args>
-ldraw::Id Model::EditContext::insert(int position, Args&&... args)
+ldraw::id_t Model::EditContext::insert(int position, Args&&... args)
+{
+	return this->storedModel.insert<T>(position, args...);
+}
+
+namespace ldraw
 {
-	return this->model.insert<T>(position, args...);
+	/// Determines how quadrilaterals are split into triangles
+	enum class QuadrilateralSplit
+	{
+		Split123_134,
+		Split124_234
+	};
+
+	// Splits the specified quadrilateral into triangles.
+	// If it is not a quadrilateral then no action is performed
+	auto splitQuadrilateral(Model::EditContext& editor,
+		quadrilateralid_t quadrilateral_id,
+		QuadrilateralSplit splitType = QuadrilateralSplit::Split123_134
+	) -> std::optional<std::pair<triangleid_t, triangleid_t>>;
 }
--- a/src/ui/canvas.cpp	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/ui/canvas.cpp	Mon Mar 09 14:21:54 2020 +0200
@@ -12,7 +12,7 @@
 	this->setMouseTracking(true);
 }
 
-void Canvas::handleSelectionChange(const QSet<ldraw::Id>& selectedIds, const QSet<ldraw::Id>& deselectedIds)
+void Canvas::handleSelectionChange(const QSet<ldraw::id_t>& selectedIds, const QSet<ldraw::id_t>& deselectedIds)
 {
 	Q_ASSERT(not selectedIds.contains(ldraw::NULL_ID));
 	this->selection.subtract(deselectedIds);
@@ -23,7 +23,7 @@
 
 void Canvas::mouseMoveEvent(QMouseEvent* event)
 {
-	const ldraw::Id id = this->pick(event->pos());
+	const ldraw::id_t id = this->pick(event->pos());
 	this->highlighted = id;
 	this->totalMouseMove += (event->pos() - this->lastMousePosition).manhattanLength();
 	this->worldPosition = this->screenToModelCoordinates(event->pos(), this->gridPlane);
--- a/src/ui/canvas.h	Fri Mar 06 23:45:44 2020 +0200
+++ b/src/ui/canvas.h	Mon Mar 09 14:21:54 2020 +0200
@@ -13,7 +13,7 @@
 		const ldraw::ColorTable& colorTable,
 		QWidget* parent = nullptr);
 public slots:
-	void handleSelectionChange(const QSet<ldraw::Id>& selectedIds, const QSet<ldraw::Id>& deselectedIds);
+	void handleSelectionChange(const QSet<ldraw::id_t>& selectedIds, const QSet<ldraw::id_t>& deselectedIds);
 protected:
 	void mouseMoveEvent(QMouseEvent* event) override;
 	void mousePressEvent(QMouseEvent* event) override;
@@ -22,7 +22,7 @@
 	void paintGL() override;
 signals:
 	void newStatusText(const QString& newStatusText);
-	void selectionChanged(const QSet<ldraw::Id>& newSelection);
+	void selectionChanged(const QSet<ldraw::id_t>& newSelection);
 private:
 	void updateGridMatrix();
 	glm::vec3 cameraVector() const;
@@ -33,5 +33,5 @@
 	glm::mat4 gridMatrix;
 	geom::Plane gridPlane;
 	int totalMouseMove = 0;
-	QSet<ldraw::Id> selection;
+	QSet<ldraw::id_t> selection;
 };

mercurial