Skip to content

Commit

Permalink
Implemented reloading of worlds using an undo command
Browse files Browse the repository at this point in the history
For consistency with the map and tileset reload, and because it is nice
to allow the user to undo the reload, in case it threw away changes they
did not want to lose.
  • Loading branch information
bjorn committed Aug 29, 2024
1 parent 4e1f3ac commit f307f06
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 10 deletions.
15 changes: 15 additions & 0 deletions src/tiled/editableworld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "editableworld.h"

#include "changeevents.h"
#include "changeworld.h"
#include "maprenderer.h"
#include "scriptmanager.h"
Expand Down Expand Up @@ -144,6 +145,20 @@ QSharedPointer<Document> EditableWorld::createDocument()
return nullptr;
}

void EditableWorld::documentChanged(const ChangeEvent &event)
{
switch (event.type) {
case ChangeEvent::DocumentAboutToReload:
setObject(nullptr);
break;
case ChangeEvent::DocumentReloaded:
setObject(worldDocument()->world());
break;
default:
break;
}
}

} // namespace Tiled

#include "moc_editableworld.cpp"
3 changes: 3 additions & 0 deletions src/tiled/editableworld.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ class EditableWorld final : public EditableAsset
Q_INVOKABLE void removeMap(EditableMap *map);

QSharedPointer<Document> createDocument() override;

private:
void documentChanged(const ChangeEvent &event);
};

inline World *EditableWorld::world() const
Expand Down
56 changes: 46 additions & 10 deletions src/tiled/worlddocument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "worlddocument.h"

#include "changeevents.h"
#include "editableworld.h"
#include "worldmanager.h"

Expand All @@ -29,10 +30,30 @@

namespace Tiled {

class ReloadWorld : public QUndoCommand
{
public:
ReloadWorld(WorldDocument *worldDocument, std::unique_ptr<World> world)
: mWorldDocument(worldDocument)
, mWorld(std::move(world))
{
setText(QCoreApplication::translate("Undo Commands", "Reload World"));
}

void undo() override { mWorldDocument->swapWorld(mWorld); }
void redo() override { mWorldDocument->swapWorld(mWorld); }

private:
WorldDocument *mWorldDocument;
std::unique_ptr<World> mWorld;
};


WorldDocument::WorldDocument(std::unique_ptr<World> world, QObject *parent)
: Document(WorldDocumentType, world->fileName, parent)
, mWorld(std::move(world))
{
setCurrentObject(mWorld.get());
}

WorldDocument::~WorldDocument()
Expand Down Expand Up @@ -77,18 +98,17 @@ bool WorldDocument::reload(QString *error)
if (!canReload())
return false;

if (auto world = World::load(fileName(), error)) {
// todo: consider replacing the world using an undo command
mWorld->clearErrorsAndWarnings();
mWorld = std::move(world);
undoStack()->clear();
updateIsModified();
auto world = World::load(fileName(), error);
if (!world)
return false;

emit worldChanged();
return true;
}
undoStack()->push(new ReloadWorld(this, std::move(world)));
undoStack()->setClean();

return false;
mLastSaved = QFileInfo(fileName()).lastModified();
setChangedOnDisk(false);

return true;
}

WorldDocumentPtr WorldDocument::load(const QString &fileName, QString *error)
Expand All @@ -100,6 +120,22 @@ WorldDocumentPtr WorldDocument::load(const QString &fileName, QString *error)
return WorldDocumentPtr::create(std::move(world));
}

void WorldDocument::swapWorld(std::unique_ptr<World> &other)
{
setCurrentObject(nullptr);

emit changed(AboutToReloadEvent());

mWorld->clearErrorsAndWarnings();
mWorld.swap(other);
updateIsModified();

emit changed(ReloadEvent());

setCurrentObject(mWorld.get());
emit worldChanged();
}

std::unique_ptr<EditableAsset> WorldDocument::createEditable()
{
return std::make_unique<EditableWorld>(this, this);
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/worlddocument.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class WorldDocument final : public Document

World *world() const { return mWorld.get(); }

void swapWorld(std::unique_ptr<World> &other);

signals:
void worldChanged();

Expand Down

0 comments on commit f307f06

Please sign in to comment.