Skip to content

Commit

Permalink
Fixed crashes resulting from the Tile Animation Editor
Browse files Browse the repository at this point in the history
The TilesetModel in the TileAnimationEditor could stay around after its
TilesetDocument was deleted, causing crashes while painting or
layouting.

Not reported as far as I know, but I saw this crash on Sentry several
times per week.
  • Loading branch information
bjorn committed Jul 7, 2021
1 parent 68a1784 commit b2761f2
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 32 deletions.
35 changes: 14 additions & 21 deletions src/tiled/tileanimationeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@

#include <QAbstractListModel>
#include <QCloseEvent>
#include <QMimeData>
#include <QScopedValueRollback>
#include <QShortcut>
#include <QUndoStack>
#include <QMimeData>

namespace Tiled {

Expand Down Expand Up @@ -275,14 +276,8 @@ void FrameListModel::setDefaultFrameTime(int duration)
TileAnimationEditor::TileAnimationEditor(QWidget *parent)
: QDialog(parent, Qt::Window)
, mUi(new Ui::TileAnimationEditor)
, mTilesetDocument(nullptr)
, mTile(nullptr)
, mFrameListModel(new FrameListModel(this))
, mApplyingChanges(false)
, mSuppressUndo(false)
, mPreviewAnimationDriver(new TileAnimationDriver(this))
, mPreviewFrameIndex(0)
, mPreviewUnusedTime(0)
{
mUi->setupUi(this);
resize(Utils::dpiScaled(size()));
Expand Down Expand Up @@ -341,13 +336,19 @@ TileAnimationEditor::~TileAnimationEditor()

void TileAnimationEditor::setTilesetDocument(TilesetDocument *tilesetDocument)
{
if (mTilesetDocument)
if (mTilesetDocument) {
mTilesetDocument->disconnect(this);
delete mUi->tilesetView->model();
}

setTile(nullptr); // Avoid roaming pointers in FrameListModel and preview
mTilesetDocument = tilesetDocument;

mUi->tilesetView->setTilesetDocument(tilesetDocument);

if (mTilesetDocument) {
mUi->tilesetView->setModel(new TilesetModel(mTilesetDocument, mUi->tilesetView));

connect(mTilesetDocument, &TilesetDocument::tileAnimationChanged,
this, &TileAnimationEditor::tileAnimationChanged);

Expand All @@ -359,17 +360,11 @@ void TileAnimationEditor::setTilesetDocument(TilesetDocument *tilesetDocument)
void TileAnimationEditor::setTile(Tile *tile)
{
mTile = tile;
delete mUi->tilesetView->model();

if (tile) {
if (tile)
mFrameListModel->setFrames(tile->tileset(), tile->frames());

TilesetModel *tilesetModel = new TilesetModel(mTilesetDocument,
mUi->tilesetView);
mUi->tilesetView->setModel(tilesetModel);
} else {
else
mFrameListModel->setFrames(nullptr, QVector<Frame>());
}

mUi->frameList->setEnabled(tile);

Expand Down Expand Up @@ -407,17 +402,15 @@ void TileAnimationEditor::hideEvent(QHideEvent *)

void TileAnimationEditor::framesEdited()
{

if (mSuppressUndo)
if (mSuppressUndo || !mTilesetDocument)
return;

QUndoStack *undoStack = mTilesetDocument->undoStack();
QScopedValueRollback<bool> applyingChanges(mApplyingChanges, true);

mApplyingChanges = true;
QUndoStack *undoStack = mTilesetDocument->undoStack();
undoStack->push(new ChangeTileAnimation(mTilesetDocument,
mTile,
mFrameListModel->frames()));
mApplyingChanges = false;
}

void TileAnimationEditor::setDefaultFrameTime(int duration)
Expand Down
12 changes: 6 additions & 6 deletions src/tiled/tileanimationeditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ public slots:

Ui::TileAnimationEditor *mUi;

TilesetDocument *mTilesetDocument;
Tile *mTile;
TilesetDocument *mTilesetDocument = nullptr;
Tile *mTile = nullptr;
FrameListModel *mFrameListModel;
bool mApplyingChanges;
bool mSuppressUndo;
bool mApplyingChanges = false;
bool mSuppressUndo = false;

TileAnimationDriver *mPreviewAnimationDriver;
int mPreviewFrameIndex;
int mPreviewUnusedTime;
int mPreviewFrameIndex = 0;
int mPreviewUnusedTime = 0;
};

} // namespace Tiled
1 change: 0 additions & 1 deletion src/tiled/tilecollisiondock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,6 @@ void TileCollisionDock::setTile(Tile *tile)
mToolManager->setMapDocument(nullptr);
}


emit dummyMapDocumentChanged(mDummyMapDocument.data());

setHasSelectedObjects(false);
Expand Down
2 changes: 0 additions & 2 deletions src/tiled/tileseteditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,6 @@ TilesetEditor::TilesetEditor(QObject *parent)
, mZoomComboBox(new QComboBox)
, mStatusInfoLabel(new QLabel)
, mTileAnimationEditor(new TileAnimationEditor(mMainWindow))
, mCurrentTilesetDocument(nullptr)
, mCurrentTile(nullptr)
{
mMainWindow->setDockOptions(mMainWindow->dockOptions() | QMainWindow::GroupedDragging);
mMainWindow->setDockNestingEnabled(true);
Expand Down
4 changes: 2 additions & 2 deletions src/tiled/tileseteditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ class TilesetEditor final : public Editor
TileAnimationEditor *mTileAnimationEditor;

QHash<TilesetDocument*, TilesetView*> mViewForTileset;
TilesetDocument *mCurrentTilesetDocument;
TilesetDocument *mCurrentTilesetDocument = nullptr;

Tile *mCurrentTile;
Tile *mCurrentTile = nullptr;
bool mSettingSelectedTiles = false;
};

Expand Down

0 comments on commit b2761f2

Please sign in to comment.