From 01ce144ca1f8d0ccabaa60b48b5777adc38b6c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Thu, 13 Feb 2025 15:28:55 +0100 Subject: [PATCH] Scripting: Added tiled.load to load assets without opening an editor Still WIP, has known issues are likely also undiscovered ones. --- src/libtiled/object.h | 2 ++ src/tiled/document.cpp | 13 ------------- src/tiled/document.h | 8 +------- src/tiled/editableasset.cpp | 9 ++++++++- src/tiled/editableasset.h | 8 ++++---- src/tiled/editablemap.cpp | 27 ++++++++++++++++++++------- src/tiled/editablemap.h | 8 ++++++++ src/tiled/editableobject.h | 2 +- src/tiled/editableproject.cpp | 12 ++++++++++++ src/tiled/editableproject.h | 8 ++++++++ src/tiled/editabletileset.cpp | 18 +++++++++++++++--- src/tiled/editabletileset.h | 3 +++ src/tiled/editableworld.cpp | 13 +++++++++++++ src/tiled/editableworld.h | 8 ++++++++ src/tiled/mapdocument.cpp | 9 ++------- src/tiled/mapdocument.h | 3 ++- src/tiled/projectdocument.cpp | 11 ++--------- src/tiled/projectdocument.h | 3 +-- src/tiled/scriptmodule.cpp | 25 +++++++++++++++++++++++-- src/tiled/scriptmodule.h | 1 + src/tiled/tilesetdocument.cpp | 26 ++++++++++---------------- src/tiled/tilesetdocument.h | 10 +--------- src/tiled/worlddocument.cpp | 11 ++--------- src/tiled/worlddocument.h | 8 ++------ 24 files changed, 149 insertions(+), 97 deletions(-) diff --git a/src/libtiled/object.h b/src/libtiled/object.h index 52b8592657..1cd6527454 100644 --- a/src/libtiled/object.h +++ b/src/libtiled/object.h @@ -165,6 +165,8 @@ class TILEDSHARED_EXPORT Object static void setPropertyTypes(const SharedPropertyTypes &propertyTypes); static const PropertyTypes &propertyTypes(); + QObject *editable() const { return mEditable; } + private: const TypeId mTypeId; QString mClassName; diff --git a/src/tiled/document.cpp b/src/tiled/document.cpp index 51c3fe7d4c..adca9e0b51 100644 --- a/src/tiled/document.cpp +++ b/src/tiled/document.cpp @@ -64,19 +64,6 @@ Document::~Document() manager->unregisterDocument(this); } -EditableAsset *Document::editable() -{ - if (!mEditable) - mEditable = createEditable(); - return mEditable.get(); -} - -void Document::setEditable(std::unique_ptr editable) -{ - mEditable = std::move(editable); - mEditable->setDocument(this); -} - void Document::setFileName(const QString &fileName) { if (mFileName == fileName) diff --git a/src/tiled/document.h b/src/tiled/document.h index 62c2088bfb..f74ab4e7c1 100644 --- a/src/tiled/document.h +++ b/src/tiled/document.h @@ -28,8 +28,6 @@ #include #include -#include - class QUndoStack; namespace Tiled { @@ -97,8 +95,7 @@ class Document : public QObject, QUndoStack *undoStack() const; bool isModified() const; - EditableAsset *editable(); - void setEditable(std::unique_ptr editable); + virtual EditableAsset *editable() = 0; Object *currentObject() const { return mCurrentObject; } void setCurrentObject(Object *object); @@ -154,7 +151,6 @@ class Document : public QObject, void ignoreBrokenLinksChanged(bool ignoreBrokenLinks); protected: - virtual std::unique_ptr createEditable() = 0; virtual bool isModifiedImpl() const; void updateIsModified(); @@ -168,8 +164,6 @@ class Document : public QObject, Object *mCurrentObject = nullptr; /**< Current properties object. */ Document *mCurrentObjectDocument = nullptr; - std::unique_ptr mEditable; - private: void currentObjectDocumentChanged(const ChangeEvent &change); void currentObjectDocumentDestroyed(); diff --git a/src/tiled/editableasset.cpp b/src/tiled/editableasset.cpp index f3a492bb66..015f452ef1 100644 --- a/src/tiled/editableasset.cpp +++ b/src/tiled/editableasset.cpp @@ -33,6 +33,13 @@ EditableAsset::EditableAsset(Object *object, QObject *parent) { } +EditableAsset::~EditableAsset() +{ + // Prevent owned object from trying to delete us again + if (mDocument) + setObject(nullptr); +} + QString EditableAsset::fileName() const { if (document()) @@ -134,7 +141,7 @@ void EditableAsset::setDocument(Document *document) this, &EditableAsset::modifiedChanged); } - mDocument = document; + mDocument = document->sharedFromThis(); } } // namespace Tiled diff --git a/src/tiled/editableasset.h b/src/tiled/editableasset.h index 3be675054e..6706ec8b7a 100644 --- a/src/tiled/editableasset.h +++ b/src/tiled/editableasset.h @@ -21,6 +21,7 @@ #pragma once #include "editableobject.h" +#include "document.h" #include #include @@ -58,6 +59,7 @@ class EditableAsset : public EditableObject public: EditableAsset(Object *object, QObject *parent = nullptr); + ~EditableAsset() override; QString fileName() const; bool isReadOnly() const override = 0; @@ -92,15 +94,13 @@ public slots: virtual void setDocument(Document *document); private: - friend class Document; - - Document *mDocument = nullptr; + DocumentPtr mDocument; }; inline Document *EditableAsset::document() const { - return mDocument; + return mDocument.get(); } } // namespace Tiled diff --git a/src/tiled/editablemap.cpp b/src/tiled/editablemap.cpp index 02c0b97572..3776339863 100644 --- a/src/tiled/editablemap.cpp +++ b/src/tiled/editablemap.cpp @@ -49,14 +49,12 @@ namespace Tiled { EditableMap::EditableMap(QObject *parent) - : EditableAsset(new Map(), parent) + : EditableMap(std::make_unique(), parent) { - mDetachedMap.reset(map()); } EditableMap::EditableMap(MapDocument *mapDocument, QObject *parent) : EditableAsset(mapDocument->map(), parent) - , mSelectedArea(new EditableSelectedArea(mapDocument, this)) { setDocument(mapDocument); } @@ -661,15 +659,26 @@ void EditableMap::setSelectedObjects(const QList &objects) QSharedPointer EditableMap::createDocument() { Q_ASSERT(mDetachedMap); + Q_ASSERT(!document()); auto document = MapDocumentPtr::create(std::move(mDetachedMap)); - document->setEditable(std::unique_ptr(this)); + setDocument(document.data()); - mSelectedArea = new EditableSelectedArea(document.data(), this); + return document; +} + +EditableMap *EditableMap::get(MapDocument *mapDocument) +{ + if (!mapDocument) + return nullptr; - moveOwnershipToCpp(); + auto editable = EditableMap::find(mapDocument->map()); + if (editable) + return editable; - return document; + editable = new EditableMap(mapDocument); + // editable->moveOwnershipToCpp(); + return editable; } void EditableMap::setDocument(Document *document) @@ -682,6 +691,8 @@ void EditableMap::setDocument(Document *document) EditableAsset::setDocument(document); if (auto doc = mapDocument()) { + mSelectedArea = new EditableSelectedArea(mapDocument(), this); + connect(doc, &Document::fileNameChanged, this, &EditableAsset::fileNameChanged); connect(doc, &Document::changed, this, &EditableMap::documentChanged); connect(doc, &MapDocument::layerAdded, this, &EditableMap::attachLayer); @@ -692,6 +703,8 @@ void EditableMap::setDocument(Document *document) connect(doc, &MapDocument::selectedObjectsChanged, this, &EditableMap::selectedObjectsChanged); connect(doc, &MapDocument::regionEdited, this, &EditableMap::onRegionEdited); + } else { + delete mSelectedArea; } } diff --git a/src/tiled/editablemap.h b/src/tiled/editablemap.h index 13187f3e63..f0bbf6d264 100644 --- a/src/tiled/editablemap.h +++ b/src/tiled/editablemap.h @@ -202,6 +202,9 @@ class EditableMap final : public EditableAsset QSharedPointer createDocument() override; + static EditableMap *find(Map *map); + static EditableMap *get(MapDocument *mapDocument); + signals: void currentLayerChanged(); void selectedLayersChanged(); @@ -383,4 +386,9 @@ inline MapDocument *EditableMap::mapDocument() const return static_cast(document()); } +inline EditableMap *EditableMap::find(Map *map) +{ + return static_cast(EditableObject::find(map)); +} + } // namespace Tiled diff --git a/src/tiled/editableobject.h b/src/tiled/editableobject.h index efba7a6596..c5c30aff73 100644 --- a/src/tiled/editableobject.h +++ b/src/tiled/editableobject.h @@ -169,7 +169,7 @@ inline void EditableObject::setAsset(EditableAsset *asset) inline EditableObject *EditableObject::find(Object *object) { - return object ? static_cast(object->mEditable.data()) + return object ? static_cast(object->editable()) : nullptr; } diff --git a/src/tiled/editableproject.cpp b/src/tiled/editableproject.cpp index 4de58c62b4..fea4fe6268 100644 --- a/src/tiled/editableproject.cpp +++ b/src/tiled/editableproject.cpp @@ -63,6 +63,18 @@ QSharedPointer EditableProject::createDocument() return nullptr; } +EditableProject *EditableProject::get(ProjectDocument *projectDocument) +{ + if (!projectDocument) + return nullptr; + + auto editable = find(&projectDocument->project()); + if (editable) + return editable; + + return new EditableProject(projectDocument); +} + } // namespace Tiled #include "moc_editableproject.cpp" diff --git a/src/tiled/editableproject.h b/src/tiled/editableproject.h index b34c254b5d..cc0ff31f8b 100644 --- a/src/tiled/editableproject.h +++ b/src/tiled/editableproject.h @@ -53,6 +53,9 @@ class EditableProject final : public EditableAsset Project *project() const; QSharedPointer createDocument() override; + + static EditableProject *find(Project *project); + static EditableProject *get(ProjectDocument *projectDocument); }; inline Project *EditableProject::project() const @@ -60,4 +63,9 @@ inline Project *EditableProject::project() const return static_cast(object()); } +inline EditableProject *EditableProject::find(Project *project) +{ + return static_cast(EditableObject::find(project)); +} + } // namespace Tiled diff --git a/src/tiled/editabletileset.cpp b/src/tiled/editabletileset.cpp index cdade611b5..6cadbc6300 100644 --- a/src/tiled/editabletileset.cpp +++ b/src/tiled/editabletileset.cpp @@ -226,13 +226,13 @@ EditableTileset *EditableTileset::get(Tileset *tileset) if (!tileset) return nullptr; - if (auto document = TilesetDocument::findDocumentForTileset(tileset->sharedFromThis())) - return document->editable(); - auto editable = EditableTileset::find(tileset); if (editable) return editable; + if (auto document = TilesetDocument::findDocumentForTileset(tileset->sharedFromThis())) + return new EditableTileset(document); + editable = new EditableTileset(tileset); editable->moveOwnershipToCpp(); return editable; @@ -508,6 +508,18 @@ void EditableTileset::wangSetRemoved(WangSet *wangSet) detachWangSets({ wangSet }); } +void EditableTileset::setDocument(TilesetDocument *tilesetDocument) +{ + EditableAsset::setDocument(tilesetDocument); + + connect(tilesetDocument, &Document::fileNameChanged, this, &EditableAsset::fileNameChanged); + connect(tilesetDocument, &TilesetDocument::tilesAdded, this, &EditableTileset::attachTiles); + connect(tilesetDocument, &TilesetDocument::tilesRemoved, this, &EditableTileset::detachTiles); + connect(tilesetDocument, &TilesetDocument::tileObjectGroupChanged, this, &EditableTileset::tileObjectGroupChanged); + connect(tilesetDocument->wangSetModel(), &TilesetWangSetModel::wangSetAdded, this, &EditableTileset::wangSetAdded); + connect(tilesetDocument->wangSetModel(), &TilesetWangSetModel::wangSetRemoved, this, &EditableTileset::wangSetRemoved); +} + } // namespace Tiled #include "moc_editabletileset.cpp" diff --git a/src/tiled/editabletileset.h b/src/tiled/editabletileset.h index bb864399e6..0025b0ae26 100644 --- a/src/tiled/editabletileset.h +++ b/src/tiled/editabletileset.h @@ -203,6 +203,9 @@ public slots: void wangSetAdded(Tileset *tileset, int index); void wangSetRemoved(WangSet *wangSet); + friend class TilesetDocument; + void setDocument(TilesetDocument *tilesetDocument); + bool mReadOnly = false; SharedTileset mTileset; }; diff --git a/src/tiled/editableworld.cpp b/src/tiled/editableworld.cpp index f4635345df..750f207703 100644 --- a/src/tiled/editableworld.cpp +++ b/src/tiled/editableworld.cpp @@ -34,6 +34,7 @@ namespace Tiled { EditableWorld::EditableWorld(WorldDocument *worldDocument, QObject *parent) : EditableAsset(nullptr, parent) { + setDocument(worldDocument); setObject(worldDocument->world()); setDocument(worldDocument); } @@ -159,6 +160,18 @@ void EditableWorld::documentChanged(const ChangeEvent &event) } } +EditableWorld *EditableWorld::get(WorldDocument *worldDocument) +{ + if (!worldDocument) + return nullptr; + + auto editable = find(worldDocument->world()); + if (editable) + return editable; + + return new EditableWorld(worldDocument); +} + } // namespace Tiled #include "moc_editableworld.cpp" diff --git a/src/tiled/editableworld.h b/src/tiled/editableworld.h index c35c142252..9db6f1a297 100644 --- a/src/tiled/editableworld.h +++ b/src/tiled/editableworld.h @@ -62,6 +62,9 @@ class EditableWorld final : public EditableAsset QSharedPointer createDocument() override; + static EditableWorld *find(World *world); + static EditableWorld *get(WorldDocument *worldDocument); + private: void documentChanged(const ChangeEvent &event); }; @@ -71,6 +74,11 @@ inline World *EditableWorld::world() const return static_cast(object()); } +inline EditableWorld *EditableWorld::find(World *world) +{ + return static_cast(EditableObject::find(world)); +} + inline WorldDocument *EditableWorld::worldDocument() const { return static_cast(document()); diff --git a/src/tiled/mapdocument.cpp b/src/tiled/mapdocument.cpp index 64da85f709..36c5604d95 100644 --- a/src/tiled/mapdocument.cpp +++ b/src/tiled/mapdocument.cpp @@ -134,11 +134,6 @@ MapDocument::~MapDocument() { // Clear any previously found issues in this document IssuesModel::instance().removeIssuesWithContext(this); - - // Needs to be deleted before the Map instance is deleted, because it may - // cause script values to detach from the map, in which case they'll need - // to be able to copy the data. - mEditable.reset(); } bool MapDocument::save(const QString &fileName, QString *error) @@ -291,9 +286,9 @@ QString MapDocument::displayName() const return displayName; } -std::unique_ptr MapDocument::createEditable() +EditableAsset *MapDocument::editable() { - return std::make_unique(this, this); + return EditableMap::get(this); } /** diff --git a/src/tiled/mapdocument.h b/src/tiled/mapdocument.h index 3c402ceed5..0540ed1104 100644 --- a/src/tiled/mapdocument.h +++ b/src/tiled/mapdocument.h @@ -95,6 +95,8 @@ class TILED_EDITOR_EXPORT MapDocument final : public Document bool canReload() const override; bool reload(QString *error); + EditableAsset *editable() override; + /** * Loads a map and returns a MapDocument instance on success. Returns null * on error and sets the \a error message. @@ -382,7 +384,6 @@ public slots: void deselectObjects(const QList &objects); protected: - std::unique_ptr createEditable() override; private: void onChanged(const ChangeEvent &change); diff --git a/src/tiled/projectdocument.cpp b/src/tiled/projectdocument.cpp index ca36524d06..1f92789fb1 100644 --- a/src/tiled/projectdocument.cpp +++ b/src/tiled/projectdocument.cpp @@ -37,13 +37,6 @@ ProjectDocument::ProjectDocument(std::unique_ptr project, QObject *pare this, [this] { mProject->save(); }); } -ProjectDocument::~ProjectDocument() -{ - // The Editable needs to be deleted before the Project, otherwise ~Object() - // will delete it, whereas the editable is actually owned by the Document. - mEditable.reset(); -} - QString ProjectDocument::displayName() const { return mProject->fileName(); @@ -79,9 +72,9 @@ void ProjectDocument::setLastExportFileName(const QString &/* fileName */) // do nothing } -std::unique_ptr ProjectDocument::createEditable() +EditableAsset *ProjectDocument::editable() { - return std::make_unique(this, this); + return EditableProject::get(this); } } // namespace Tiled diff --git a/src/tiled/projectdocument.h b/src/tiled/projectdocument.h index 9ed07cd433..7adef2c9df 100644 --- a/src/tiled/projectdocument.h +++ b/src/tiled/projectdocument.h @@ -32,7 +32,6 @@ class ProjectDocument final : public Document public: explicit ProjectDocument(std::unique_ptr project, QObject *parent = nullptr); - ~ProjectDocument() override; QString displayName() const override; FileFormat *writerFormat() const override; @@ -41,7 +40,7 @@ class ProjectDocument final : public Document FileFormat *exportFormat() const override; QString lastExportFileName() const override; void setLastExportFileName(const QString &fileName) override; - std::unique_ptr createEditable() override; + EditableAsset *editable() override; Project &project() { return *mProject; } diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index b60c6bf519..638582e7a9 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -199,8 +199,11 @@ bool ScriptModule::setActiveAsset(EditableAsset *asset) const if (asset->checkReadOnly()) return false; - if (auto document = asset->document()) - return documentManager->switchToDocument(document); + if (auto document = asset->document()) { + if (!documentManager->switchToDocument(document)) + documentManager->addDocument(document->sharedFromThis()); + return true; + } if (auto document = asset->createDocument()) { documentManager->addDocument(document); @@ -310,6 +313,24 @@ bool ScriptModule::versionLessThan(const QString &a, const QString &b) return QVersionNumber::fromString(a) < QVersionNumber::fromString(b); } +EditableAsset *ScriptModule::load(const QString &fileName) const +{ + auto documentManager = DocumentManager::maybeInstance(); + if (!documentManager) { + ScriptManager::instance().throwError(QCoreApplication::translate("Script Errors", "Editor not available")); + return nullptr; + } + + QString error; + if (auto document = documentManager->loadDocument(fileName, nullptr, &error)) { + return document->editable(); + } else { + ScriptManager::instance().throwError(error); + } + + return nullptr; +} + EditableAsset *ScriptModule::open(const QString &fileName) const { auto documentManager = DocumentManager::maybeInstance(); diff --git a/src/tiled/scriptmodule.h b/src/tiled/scriptmodule.h index 947766035f..2fab4c16c8 100644 --- a/src/tiled/scriptmodule.h +++ b/src/tiled/scriptmodule.h @@ -116,6 +116,7 @@ class ScriptModule : public QObject Q_INVOKABLE bool versionLessThan(const QString &a); Q_INVOKABLE bool versionLessThan(const QString &a, const QString &b); + Q_INVOKABLE Tiled::EditableAsset *load(const QString &fileName) const; Q_INVOKABLE Tiled::EditableAsset *open(const QString &fileName) const; Q_INVOKABLE bool close(Tiled::EditableAsset *asset) const; Q_INVOKABLE Tiled::EditableAsset *reload(Tiled::EditableAsset *asset) const; diff --git a/src/tiled/tilesetdocument.cpp b/src/tiled/tilesetdocument.cpp index 5f74d7bd77..c3f5182c85 100644 --- a/src/tiled/tilesetdocument.cpp +++ b/src/tiled/tilesetdocument.cpp @@ -67,12 +67,10 @@ TilesetDocument::TilesetDocument(const SharedTileset &tileset) Q_ASSERT(!sTilesetToDocument.contains(tileset)); sTilesetToDocument.insert(tileset, this); - // If there already happens to be an editable for this tileset, take - // ownership of it. - if (auto editable = EditableTileset::find(tileset.data())) { - setEditable(std::unique_ptr(editable)); - QQmlEngine::setObjectOwnership(editable, QQmlEngine::CppOwnership); - } + // If there already happens to be an editable for this tileset, make sure + // it knows about us. + if (auto editable = EditableTileset::find(tileset.data())) + editable->setDocument(this); mCurrentObject = tileset.data(); @@ -95,11 +93,6 @@ TilesetDocument::~TilesetDocument() IssuesModel::instance().removeIssuesWithContext(this); sTilesetToDocument.remove(mTileset); - - // Needs to be deleted before the Tileset instance is deleted, because it - // may cause script values to detach from the map, in which case they'll - // need to be able to copy the data. - mEditable.reset(); } bool TilesetDocument::save(const QString &fileName, QString *error) @@ -260,19 +253,20 @@ void TilesetDocument::swapTileset(SharedTileset &tileset) setCurrentObject(mTileset.data()); mWangColorModels.clear(); - emit changed(AboutToReloadEvent()); + // Delete the editable and have it deal with any child editables that were + // created, because their document and object references would no longer be + // valid after the swap. + delete mTileset->editable(); - sTilesetToDocument.remove(mTileset); mTileset->swap(*tileset); - sTilesetToDocument.insert(mTileset, this); emit changed(ReloadEvent()); emit tilesetChanged(mTileset.data()); } -std::unique_ptr TilesetDocument::createEditable() +EditableTileset *TilesetDocument::editable() { - return std::make_unique(this, this); + return EditableTileset::get(mTileset.data()); } /** diff --git a/src/tiled/tilesetdocument.h b/src/tiled/tilesetdocument.h index 0d09bfb4e1..bec9074c37 100644 --- a/src/tiled/tilesetdocument.h +++ b/src/tiled/tilesetdocument.h @@ -84,7 +84,7 @@ class TilesetDocument final : public Document void swapTileset(SharedTileset &tileset); const SharedTileset &tileset() const; - EditableTileset *editable(); + EditableTileset *editable() override; bool isEmbedded() const; void setClean(); @@ -164,9 +164,6 @@ class TilesetDocument final : public Document */ void selectedTilesChanged(); -protected: - std::unique_ptr createEditable() override; - private: void onPropertyAdded(Object *object, const QString &name); void onPropertyRemoved(Object *object, const QString &name); @@ -192,11 +189,6 @@ inline const SharedTileset &TilesetDocument::tileset() const return mTileset; } -inline EditableTileset *TilesetDocument::editable() -{ - return static_cast(Document::editable()); -} - inline bool TilesetDocument::isEmbedded() const { return fileName().isEmpty() && mMapDocuments.count() == 1; diff --git a/src/tiled/worlddocument.cpp b/src/tiled/worlddocument.cpp index 156e8cb4b8..1ec908cc71 100644 --- a/src/tiled/worlddocument.cpp +++ b/src/tiled/worlddocument.cpp @@ -56,13 +56,6 @@ WorldDocument::WorldDocument(std::unique_ptr world, QObject *parent) setCurrentObject(mWorld.get()); } -WorldDocument::~WorldDocument() -{ - // The Editable needs to be deleted before the World, otherwise ~World() - // will delete it, whereas the editable is actually owned by the Document. - mEditable.reset(); -} - QString WorldDocument::displayName() const { QString displayName = QFileInfo(fileName()).fileName(); @@ -136,9 +129,9 @@ void WorldDocument::swapWorld(std::unique_ptr &other) emit worldChanged(); } -std::unique_ptr WorldDocument::createEditable() +EditableAsset *WorldDocument::editable() { - return std::make_unique(this, this); + return EditableWorld::get(this); } } // namespace Tiled diff --git a/src/tiled/worlddocument.h b/src/tiled/worlddocument.h index 50e779a105..201bbff2e6 100644 --- a/src/tiled/worlddocument.h +++ b/src/tiled/worlddocument.h @@ -24,8 +24,6 @@ #include "document.h" #include "editableasset.h" -class WorldManager; - namespace Tiled { class World; @@ -43,7 +41,6 @@ class WorldDocument final : public Document public: explicit WorldDocument(std::unique_ptr world, QObject *parent = nullptr); - ~WorldDocument(); // Document interface QString displayName() const override; @@ -61,6 +58,8 @@ class WorldDocument final : public Document FileFormat *writerFormat() const override { return nullptr; } + EditableAsset *editable() override; // TODO: Check + // Exporting not supported for worlds QString lastExportFileName() const override { return QString(); } void setLastExportFileName(const QString &) override {} @@ -75,9 +74,6 @@ class WorldDocument final : public Document void worldChanged(); private: - // Document interface - std::unique_ptr createEditable() override; - std::unique_ptr mWorld; };