# HG changeset patch # User Teemu Piippo # Date 1561010075 -10800 # Node ID 265b2e95a8e87c422b5667bfabe07f7ace49344b # Parent 241d3e452b32b4f926a4353824499f3fcf0bfc05 uuid things diff -r 241d3e452b32 -r 265b2e95a8e8 src/basics.cpp --- a/src/basics.cpp Fri Dec 28 00:03:47 2018 +0200 +++ b/src/basics.cpp Thu Jun 20 08:54:35 2019 +0300 @@ -269,3 +269,29 @@ { return not (one == other); } + +QString Uuid::toString() const +{ + const std::uint32_t octet_1 = (a & 0xffffffff00000000) >> 32; + const std::uint16_t octet_2 = (a & 0x00000000ffff0000) >> 16; + const std::uint16_t octet_3 = (a & 0x000000000000ffff); + const std::uint16_t octet_4 = (b & 0xffff000000000000) >> 48; + const std::uint64_t octet_5 = (b & 0xffffffffffff0000); + char buffer[32 + 4 + 1]; + std::sprintf(buffer, "%08x-%04x-%04x-%04x-%012lx", octet_1, octet_2, octet_3, octet_4, octet_5); + return buffer; +} + +Uuid& Uuid::operator++() +{ + if (b == std::numeric_limits::max()) + { + b = 0; + a += 1; + } + else + { + b += 1; + } + return *this; +} diff -r 241d3e452b32 -r 265b2e95a8e8 src/basics.h --- a/src/basics.h Fri Dec 28 00:03:47 2018 +0200 +++ b/src/basics.h Thu Jun 20 08:54:35 2019 +0300 @@ -46,6 +46,22 @@ class LDObject; +class Uuid +{ +public: + constexpr Uuid() : a{0}, b{0} {} + Uuid(Uuid&&) = default; + Uuid(const Uuid&) = default; + QString toString() const; + Uuid& operator++(); + +private: + quint64 a; + quint64 b; +}; + +constexpr Uuid NULL_UUID = {}; + enum Axis { X, diff -r 241d3e452b32 -r 265b2e95a8e8 src/editHistory.cpp --- a/src/editHistory.cpp Fri Dec 28 00:03:47 2018 +0200 +++ b/src/editHistory.cpp Thu Jun 20 08:54:35 2019 +0300 @@ -137,10 +137,10 @@ return m_parent; } -AddHistoryEntry::AddHistoryEntry(const QModelIndex& index, EditHistory* parent) : +AddHistoryEntry::AddHistoryEntry(const Uuid& id, const int row, EditHistory* parent) : AbstractHistoryEntry {parent}, - m_row {index.row()}, - m_code {Serializer::store(parent->document()->lookup(index))} {} + m_row {row}, + m_code {Serializer::store(parent->document()->lookup(id))} {} void AddHistoryEntry::undo() { @@ -164,13 +164,13 @@ } EditHistoryEntry::EditHistoryEntry( - const QModelIndex& index, + const int row, const Serializer::Archive& oldState, const Serializer::Archive& newState, EditHistory* parent ) : AbstractHistoryEntry {parent}, - row {index.row()}, + row {row}, oldState {oldState}, newState {newState} {} @@ -183,32 +183,3 @@ { parent()->document()->setObjectAt(row, newState); } - -MoveHistoryEntry::MoveHistoryEntry(int top, int bottom, int destination, EditHistory* parent) : - AbstractHistoryEntry {parent}, - top {top}, - bottom {bottom}, - destination {destination} {} - -void MoveHistoryEntry::undo() -{ - bool downwards = (destination < top); - parent()->document()->moveRows( - {}, - downwards ? (destination) : (destination - (bottom - top) - 1), - bottom - top + 1, - {}, - downwards ? (bottom + 1) : top - ); -} - -void MoveHistoryEntry::redo() -{ - parent()->document()->moveRows( - {}, - top, - bottom - top + 1, - {}, - destination - ); -} diff -r 241d3e452b32 -r 265b2e95a8e8 src/editHistory.h --- a/src/editHistory.h Fri Dec 28 00:03:47 2018 +0200 +++ b/src/editHistory.h Thu Jun 20 08:54:35 2019 +0300 @@ -81,7 +81,7 @@ class AddHistoryEntry : public AbstractHistoryEntry { public: - AddHistoryEntry (const QModelIndex& index, EditHistory* parent); + AddHistoryEntry (const Uuid& id, const int row, EditHistory* parent); void undo() override; void redo() override; @@ -101,8 +101,7 @@ class EditHistoryEntry : public AbstractHistoryEntry { public: - EditHistoryEntry( - const QModelIndex& index, + EditHistoryEntry(const int row, const Serializer::Archive& oldCode, const Serializer::Archive& newCode, EditHistory* parent @@ -115,16 +114,3 @@ Serializer::Archive oldState; Serializer::Archive newState; }; - -class MoveHistoryEntry : public AbstractHistoryEntry -{ -public: - MoveHistoryEntry(int top, int bottom, int destination, EditHistory* parent); - void undo() override; - void redo() override; - -private: - int top; - int bottom; - int destination; -}; diff -r 241d3e452b32 -r 265b2e95a8e8 src/glcompiler.cpp --- a/src/glcompiler.cpp Fri Dec 28 00:03:47 2018 +0200 +++ b/src/glcompiler.cpp Thu Jun 20 08:54:35 2019 +0300 @@ -256,7 +256,7 @@ /* * Stages the given object for compilation. */ -void gl::Compiler::stageForCompilation(const QModelIndex& index) +void gl::Compiler::stageForCompilation(const Uuid& index) { m_staged.insert(index); } @@ -264,7 +264,7 @@ /* * Removes an object from the set of objects to be compiled. */ -void gl::Compiler::unstage(const QModelIndex& index) +void gl::Compiler::unstage(const Uuid& index) { m_staged.remove(index); } @@ -324,7 +324,7 @@ /* * Removes the data related to the given object. */ -void gl::Compiler::dropObjectInfo(const QModelIndex& index) +void gl::Compiler::dropObjectInfo(const Uuid& index) { if (m_objectInfo.contains(index)) { @@ -339,7 +339,7 @@ /* * Makes the compiler forget about the given object completely. */ -void gl::Compiler::forgetObject(QModelIndex index) +void gl::Compiler::forgetObject(const Uuid& index) { dropObjectInfo(index); unstage(index); @@ -348,15 +348,15 @@ /* * Compiles a single object. */ -void gl::Compiler::compileObject(const QModelIndex& index) +void gl::Compiler::compileObject(const Uuid& id) { - LDObject* object = m_renderer->model()->lookup(index); + LDObject* object = m_renderer->model()->lookup(id); if (object == nullptr) return; ObjectVboData info; - dropObjectInfo(index); + dropObjectInfo(id); switch (object->type()) { @@ -497,7 +497,7 @@ if (this->needBoundingBoxRebuild) { this->boundingBox = {}; - QMapIterator iterator {m_objectInfo}; + QMapIterator iterator {m_objectInfo}; while (iterator.hasNext()) { @@ -646,3 +646,8 @@ this->setSelectionModel(nullptr); emit sceneChanged(); } + +void gl::Compiler::objectRemoved(const Uuid& id) +{ + this->m_objectInfo.remove(id); +} diff -r 241d3e452b32 -r 265b2e95a8e8 src/glcompiler.h --- a/src/glcompiler.h Fri Dec 28 00:03:47 2018 +0200 +++ b/src/glcompiler.h Thu Jun 20 08:54:35 2019 +0300 @@ -66,18 +66,18 @@ void compileStaged(); void compilePolygon(LDPolygon& poly, const QModelIndex& polygonOwnerIndex, ObjectVboData& objectInfo); - Q_SLOT void compileObject(const QModelIndex &index); + Q_SLOT void compileObject(const Uuid& index); QColor getColorForPolygon(const LDPolygon& polygon, const QModelIndex& polygonOwnerIndex, VboSubclass complement); QColor indexColorForID (qint32 id) const; void needMerge(); Q_SLOT void recompile(); - void dropObjectInfo (const QModelIndex &index); - Q_SLOT void forgetObject(QModelIndex index); - void stageForCompilation(const QModelIndex &index); - void unstage (const QModelIndex &index); + void dropObjectInfo (const Uuid& index); + Q_SLOT void forgetObject(const Uuid& index); + void stageForCompilation(const Uuid& index); + void unstage (const Uuid& index); - QMap m_objectInfo; - QSet m_staged; // Objects that need to be compiled + QMap m_objectInfo; + QSet m_staged; // Objects that need to be compiled GLuint m_vbo[NumVbos]; bool m_vboChanged[NumVbos] = {true}; bool needBoundingBoxRebuild = true; @@ -92,6 +92,7 @@ void handleDataChange(const QModelIndex& topLeft, const QModelIndex &bottomRight); void handleObjectHighlightingChanged(const QModelIndex& oldIndex, const QModelIndex& newIndex); void clearSelectionModel(); + void objectRemoved(const Uuid &id); }; #define CHECK_GL_ERROR() { checkGLError(__FILE__, __LINE__); } diff -r 241d3e452b32 -r 265b2e95a8e8 src/glrenderer.cpp --- a/src/glrenderer.cpp Fri Dec 28 00:03:47 2018 +0200 +++ b/src/glrenderer.cpp Thu Jun 20 08:54:35 2019 +0300 @@ -184,7 +184,7 @@ /* * Returns the object currently highlighted by the cursor. */ -QPersistentModelIndex gl::Renderer::objectAtCursor() const +const Uuid& gl::Renderer::objectAtCursor() const { return m_objectAtCursor; } diff -r 241d3e452b32 -r 265b2e95a8e8 src/glrenderer.h --- a/src/glrenderer.h Fri Dec 28 00:03:47 2018 +0200 +++ b/src/glrenderer.h Thu Jun 20 08:54:35 2019 +0300 @@ -87,7 +87,7 @@ const Model* model() const; QPoint const& mousePosition() const; QPointF const& mousePositionF() const; - QPersistentModelIndex objectAtCursor() const; + const Uuid& objectAtCursor() const; QItemSelection pick(const QRect& range); QModelIndex pick(int mouseX, int mouseY); void resetAllAngles(); @@ -133,7 +133,7 @@ private: const Model* const m_model; gl::Compiler* m_compiler; - QPersistentModelIndex m_objectAtCursor; + Uuid m_objectAtCursor; gl::CameraIcon m_cameraIcons[7]; QTimer* m_toolTipTimer; Qt::MouseButtons m_lastButtons; diff -r 241d3e452b32 -r 265b2e95a8e8 src/lddocument.cpp --- a/src/lddocument.cpp Fri Dec 28 00:03:47 2018 +0200 +++ b/src/lddocument.cpp Thu Jun 20 08:54:35 2019 +0300 @@ -37,15 +37,6 @@ this, SLOT(handleNewObject(QModelIndex)) ); - - connect( - this, - &Model::rowsMoved, - [&](const QModelIndex&, int start, int end, const QModelIndex&, int row) - { - history()->add(start, end, row); - } - ); connect( this, SIGNAL(aboutToRemoveObject(QModelIndex)), @@ -386,7 +377,7 @@ return true; } -void LDDocument::handleNewObject(const QModelIndex& index) +void LDDocument::handleNewObject(const Uuid& index) { LDObject* object = lookup(index); history()->add(index); @@ -408,11 +399,10 @@ history()->add(index, before, after); redoVertices(); emit objectModified(object); - emit dataChanged(index, index); } } -void LDDocument::handleImminentObjectRemoval(const QModelIndex& index) +void LDDocument::handleImminentObjectRemoval(const Uuid& index) { LDObject* object = lookup(index); diff -r 241d3e452b32 -r 265b2e95a8e8 src/lddocument.h --- a/src/lddocument.h Fri Dec 28 00:03:47 2018 +0200 +++ b/src/lddocument.h Thu Jun 20 08:54:35 2019 +0300 @@ -145,8 +145,8 @@ private slots: void objectChanged(const LDObjectState &before, const LDObjectState &after); - void handleNewObject(const QModelIndex& index); - void handleImminentObjectRemoval(const QModelIndex& index); + void handleNewObject(const Uuid& index); + void handleImminentObjectRemoval(const Uuid& index); }; // Parses a string line containing an LDraw object and returns the object parsed. diff -r 241d3e452b32 -r 265b2e95a8e8 src/linetypes/modelobject.cpp --- a/src/linetypes/modelobject.cpp Fri Dec 28 00:03:47 2018 +0200 +++ b/src/linetypes/modelobject.cpp Thu Jun 20 08:54:35 2019 +0300 @@ -33,15 +33,13 @@ #include "empty.h" #include "circularprimitive.h" -// List of all LDObjects -QMap g_allObjects; - -enum { MAX_LDOBJECT_IDS = (1 << 24) }; +static Uuid id_counter; // ============================================================================= // LDObject constructors // LDObject::LDObject() : + id {++id_counter}, m_isHidden {false} { m_randomColor = QColor::fromHsv (rand() % 360, rand() % 256, rand() % 96 + 128); diff -r 241d3e452b32 -r 265b2e95a8e8 src/linetypes/modelobject.h --- a/src/linetypes/modelobject.h Fri Dec 28 00:03:47 2018 +0200 +++ b/src/linetypes/modelobject.h Thu Jun 20 08:54:35 2019 +0300 @@ -93,6 +93,8 @@ static LDObject* newFromType(LDObjectType type); + const Uuid id; + signals: void modified(const LDObjectState& before, const LDObjectState& after); diff -r 241d3e452b32 -r 265b2e95a8e8 src/model.cpp --- a/src/model.cpp Fri Dec 28 00:03:47 2018 +0200 +++ b/src/model.cpp Thu Jun 20 08:54:35 2019 +0300 @@ -48,6 +48,7 @@ beginInsertRows({}, row, row); _objects.insert(row, object); + _objectsById[object->id] = object; if (this->pickingColorCursor <= 0xffffff) { @@ -417,17 +418,14 @@ /* * Looks up an object by the given index. */ -LDObject* Model::lookup(const QModelIndex &index) const +LDObject* Model::lookup(const Uuid& id) const { - if (index.row() >= 0 and index.row() < size()) - return this->objects()[index.row()]; - else - return nullptr; + return _objectsById.value(id, nullptr); } -QColor Model::pickingColorForObject(const QModelIndex& objectIndex) const +QColor Model::pickingColorForObject(const Uuid& id) const { - return QColor::fromRgba(this->pickingColors.value(this->lookup(objectIndex)) | 0xff000000); + return QColor::fromRgba(this->pickingColors.value(this->lookup(id)) | 0xff000000); } QModelIndex Model::objectByPickingColor(const QColor& color) const diff -r 241d3e452b32 -r 265b2e95a8e8 src/model.h --- a/src/model.h Fri Dec 28 00:03:47 2018 +0200 +++ b/src/model.h Thu Jun 20 08:54:35 2019 +0300 @@ -73,7 +73,7 @@ /* * This class represents a LDraw model, consisting of a vector of objects. It manages LDObject ownership. */ -class Model : public QAbstractListModel +class Model : public QObject { Q_OBJECT @@ -104,26 +104,16 @@ bool isEmpty() const; class DocumentManager* documentManager() const; IndexGenerator indices() const; - LDObject* lookup(const QModelIndex& index) const; - QColor pickingColorForObject(const QModelIndex& objectIndex) const; + LDObject* lookup(const Uuid& index) const; + QColor pickingColorForObject(const Uuid& id) const; QModelIndex objectByPickingColor(const QColor& color) const; Winding winding() const; void setWinding(Winding winding); - - bool moveRows( - const QModelIndex& sourceParent, - int sourceRow, - int count, - const QModelIndex& destinationParent, - int destinationChild - ) override; - - int rowCount(const QModelIndex& parent) const override; - QVariant data(const QModelIndex& index, int role) const override; + int rowOf(const Uuid& id); signals: - void objectAdded(const QModelIndex& object); - void aboutToRemoveObject(const QModelIndex& index); + void objectAdded(const Uuid& object); + void aboutToRemoveObject(const Uuid& index, const LDObject* object); void objectModified(LDObject* object); void windingChanged(Winding newWinding); void modelChanged(); @@ -132,6 +122,7 @@ template T* constructObject(Args&& ...args); QVector _objects; + QMap _objectsById; QMap pickingColors; QRgb pickingColorCursor = 0x000001; class DocumentManager* _manager;