mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-26 17:37:07 +00:00
Fix possibilities of random crashes using filters w/Undo History window visible
Same problem as in 86a6462d7b82608cc14a8417bbdb42e2a4e3c467
This commit is contained in:
parent
7becbc09b8
commit
4585b5e7e5
@ -183,7 +183,7 @@ bool FilterManagerImpl::applyStep()
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilterManagerImpl::apply(Transaction& transaction)
|
||||
void FilterManagerImpl::apply()
|
||||
{
|
||||
bool cancelled = false;
|
||||
|
||||
@ -203,7 +203,7 @@ void FilterManagerImpl::apply(Transaction& transaction)
|
||||
if (algorithm::shrink_bounds2(m_src.get(), m_dst.get(),
|
||||
m_bounds, output)) {
|
||||
if (m_cel->layer()->isBackground()) {
|
||||
transaction.execute(
|
||||
m_transaction->execute(
|
||||
new cmd::CopyRegion(
|
||||
m_cel->image(),
|
||||
m_dst.get(),
|
||||
@ -212,7 +212,7 @@ void FilterManagerImpl::apply(Transaction& transaction)
|
||||
}
|
||||
else {
|
||||
// Patch "m_cel"
|
||||
transaction.execute(
|
||||
m_transaction->execute(
|
||||
new cmd::PatchCel(
|
||||
m_cel, m_dst.get(),
|
||||
gfx::Region(output),
|
||||
@ -239,7 +239,7 @@ void FilterManagerImpl::applyToTarget()
|
||||
// Initialize writting operation
|
||||
ContextReader reader(m_context);
|
||||
ContextWriter writer(reader);
|
||||
Transaction transaction(writer.context(), m_filter->getName(), ModifyDocument);
|
||||
m_transaction.reset(new Transaction(writer.context(), m_filter->getName(), ModifyDocument));
|
||||
|
||||
m_progressBase = 0.0f;
|
||||
m_progressWidth = 1.0f / images.size();
|
||||
@ -250,7 +250,7 @@ void FilterManagerImpl::applyToTarget()
|
||||
if (paletteChange) {
|
||||
Palette newPalette = *getNewPalette();
|
||||
restoreSpritePalette();
|
||||
transaction.execute(
|
||||
m_transaction->execute(
|
||||
new cmd::SetPalette(m_site.sprite(),
|
||||
m_site.frame(), &newPalette));
|
||||
}
|
||||
@ -264,7 +264,7 @@ void FilterManagerImpl::applyToTarget()
|
||||
// Avoid applying the filter two times to the same image
|
||||
if (visited.find(image->id()) == visited.end()) {
|
||||
visited.insert(image->id());
|
||||
applyToCel(transaction, it->cel());
|
||||
applyToCel(it->cel());
|
||||
}
|
||||
|
||||
// Is there a delegate to know if the process was cancelled by the user?
|
||||
@ -275,12 +275,17 @@ void FilterManagerImpl::applyToTarget()
|
||||
m_progressBase += m_progressWidth;
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
|
||||
// Reset m_oldPalette to avoid restoring the color palette
|
||||
m_oldPalette.reset(nullptr);
|
||||
}
|
||||
|
||||
void FilterManagerImpl::commitTransaction()
|
||||
{
|
||||
// This must be executed in the main UI thread.
|
||||
// Check Transaction::commit() comments.
|
||||
m_transaction->commit();
|
||||
}
|
||||
|
||||
void FilterManagerImpl::flush()
|
||||
{
|
||||
int h = m_row - m_nextRowToFlush;
|
||||
@ -395,10 +400,10 @@ void FilterManagerImpl::init(Cel* cel)
|
||||
m_target &= ~TARGET_ALPHA_CHANNEL;
|
||||
}
|
||||
|
||||
void FilterManagerImpl::applyToCel(Transaction& transaction, Cel* cel)
|
||||
void FilterManagerImpl::applyToCel(Cel* cel)
|
||||
{
|
||||
init(cel);
|
||||
apply(transaction);
|
||||
apply();
|
||||
}
|
||||
|
||||
bool FilterManagerImpl::updateBounds(doc::Mask* mask)
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "gfx/rect.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
namespace doc {
|
||||
class Cel;
|
||||
@ -82,6 +83,7 @@ namespace app {
|
||||
void end();
|
||||
bool applyStep();
|
||||
void applyToTarget();
|
||||
void commitTransaction();
|
||||
|
||||
app::Document* document();
|
||||
doc::Sprite* sprite() { return m_site.sprite(); }
|
||||
@ -114,8 +116,8 @@ namespace app {
|
||||
|
||||
private:
|
||||
void init(doc::Cel* cel);
|
||||
void apply(Transaction& transaction);
|
||||
void applyToCel(Transaction& transaction, doc::Cel* cel);
|
||||
void apply();
|
||||
void applyToCel(doc::Cel* cel);
|
||||
bool updateBounds(doc::Mask* mask);
|
||||
bool paletteHasChanged();
|
||||
void restoreSpritePalette();
|
||||
@ -136,6 +138,7 @@ namespace app {
|
||||
Target m_targetOrig; // Original targets
|
||||
Target m_target; // Filtered targets
|
||||
base::UniquePtr<doc::Palette> m_oldPalette;
|
||||
std::unique_ptr<Transaction> m_transaction;
|
||||
|
||||
// Hooks
|
||||
float m_progressBase;
|
||||
|
@ -104,7 +104,9 @@ void FilterWorker::run()
|
||||
|
||||
{
|
||||
scoped_lock lock(m_mutex);
|
||||
if (!m_done)
|
||||
if (m_done)
|
||||
m_filterMgr->commitTransaction();
|
||||
else
|
||||
m_cancelled = true;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
// Copyright (C) 2001-2017 David Capello
|
||||
//
|
||||
// This program is distributed under the terms of
|
||||
// the End-User License Agreement for Aseprite.
|
||||
@ -51,6 +51,11 @@ namespace app {
|
||||
// If you don't use this routine, all the changes will be discarded
|
||||
// (if the sprite's undo was enabled when the Transaction was
|
||||
// created).
|
||||
//
|
||||
// WARNING: This must be called from the main UI thread, because
|
||||
// it will generate a DocumentUndo::add() which triggers a
|
||||
// DocumentUndoObserver::onAddUndoState() notification, which
|
||||
// updates the Undo History window UI.
|
||||
void commit();
|
||||
|
||||
void execute(Cmd* cmd);
|
||||
|
Loading…
x
Reference in New Issue
Block a user