src/linetypes/object.h

Sat, 05 Mar 2022 12:47:10 +0200

author
Teemu Piippo <teemu@hecknology.net>
date
Sat, 05 Mar 2022 12:47:10 +0200
changeset 159
1a04364d20b5
parent 158
5bd755eaa5a8
child 177
f69d53c053df
permissions
-rw-r--r--

fix crash when loading a file
`object` is moved so we cannot access it after moving

#pragma once
#include <QPointF>
#include <QString>
#include <QStringView>
#include "main.h"
#include "colors.h"
#include "gl/common.h"
#include "linetypes/propertygenerics.h"

class Model;

namespace ldraw
{
	struct GetPolygonsContext;
	class Object;
	class ColoredObject;
	class Empty;
	class UnhandledProperty;
}

class DocumentManager;

struct ldraw::GetPolygonsContext
{
	::ModelId modelId;
	::DocumentManager* documents;
};

class ldraw::Object
{
public:
	enum class SetPropertyResult
	{
		Success = 0,
		PropertyNotHandled
	};
	/**
	 * @brief Enumerates different object types
	 */
	enum class Type
	{
		Empty,
		Comment,
		MetaCommand,
		ErrorLine,
		SubfileReference,
		EdgeLine,
		ConditionalEdge,
		Triangle,
		Quadrilateral,
	};
	friend bool handled(SetPropertyResult result)
	{
		return result == SetPropertyResult::Success;
	}
	class BadPointIndex : public std::exception
	{
	};
	Object();
	Object(const Object&) = delete;
	virtual ~Object();
	const id_t id;
	virtual bool hasColor() const;
	virtual QVariant getProperty(Property id) const;
	template<ldraw::Property property>
	PropertyType<property> getProperty() const;
	template<ldraw::Property property>
	SetPropertyResult setProperty(const PropertyType<property>& value);
	SetPropertyResult setProperty(const PropertyKeyValue& pair);
	virtual QString textRepresentation() const = 0;
	virtual QBrush textRepresentationForeground() const;
	virtual QBrush textRepresentationBackground() const;
	virtual QFont textRepresentationFont() const;
	virtual void getPolygons(std::vector<gl::Polygon>& polygons, GetPolygonsContext* context) const;
	virtual void invert() {}
	virtual int numPoints() const { return 0; }
	virtual const glm::vec3& getPoint(int index) const;
	virtual QDataStream& serialize(QDataStream& stream) const;
	virtual QDataStream& deserialize(QDataStream& stream);
	virtual Type typeIdentifier() const = 0;
	virtual QString toLDrawCode() const = 0;
	virtual QString iconName() const;

protected:
	template<Property property, typename Function>
	void handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function);
	virtual void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair);
};

/**
 * @brief Tests whether the object is exactly of the specified type
 * @tparam R Type of LDraw line type object to test for
 * @param object Object to test
 * @returns whether the type of the object specified by @c id is the same type as R. Returns false if it is a subclass.
 */
template<typename R>
bool isA(const ldraw::Object* object)
{
	const std::type_info& a = typeid(*object);
	const std::type_info& b = typeid(R);
	return a == b;
}

template<ldraw::Property property>
ldraw::Object::SetPropertyResult ldraw::Object::setProperty(const ldraw::PropertyType<property>& value)
{
	SetPropertyResult result = SetPropertyResult::PropertyNotHandled;
	this->setProperty(&result, PropertyKeyValue{property, QVariant::fromValue(value)});
	return result;
}

template<ldraw::Property property, typename Function>
void ldraw::Object::handle(SetPropertyResult* result, const PropertyKeyValue& pair, Function function)
{
	if (pair.key == property)
	{
		function(pair.value.value<ldraw::PropertyType<property>>());
		*result = SetPropertyResult::Success;
	}
}

template<ldraw::Property property>
ldraw::PropertyType<property> ldraw::Object::getProperty() const
{
	return this->getProperty(property).value<ldraw::PropertyType<property>>();
}

class ldraw::ColoredObject : public Object
{
public:
	ColoredObject(const Color colorIndex = ldraw::MAIN_COLOR);
	bool hasColor() const override final;
	QVariant getProperty(Property id) const override;
	QDataStream &serialize(QDataStream& stream) const override;
	QDataStream& deserialize(QDataStream& stream) override;
	Color colorIndex = ldraw::MAIN_COLOR;
protected:
	void setProperty(SetPropertyResult* result, const PropertyKeyValue& pair) override;
};

/**
 * @brief Represents an empty line.
 */
class ldraw::Empty : public Object
{
	QString textRepresentation() const override;
	Type typeIdentifier() const override;
	QString toLDrawCode() const override;
};

mercurial