mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 04:20:23 +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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterManagerImpl::apply(Transaction& transaction)
|
void FilterManagerImpl::apply()
|
||||||
{
|
{
|
||||||
bool cancelled = false;
|
bool cancelled = false;
|
||||||
|
|
||||||
@ -203,7 +203,7 @@ void FilterManagerImpl::apply(Transaction& transaction)
|
|||||||
if (algorithm::shrink_bounds2(m_src.get(), m_dst.get(),
|
if (algorithm::shrink_bounds2(m_src.get(), m_dst.get(),
|
||||||
m_bounds, output)) {
|
m_bounds, output)) {
|
||||||
if (m_cel->layer()->isBackground()) {
|
if (m_cel->layer()->isBackground()) {
|
||||||
transaction.execute(
|
m_transaction->execute(
|
||||||
new cmd::CopyRegion(
|
new cmd::CopyRegion(
|
||||||
m_cel->image(),
|
m_cel->image(),
|
||||||
m_dst.get(),
|
m_dst.get(),
|
||||||
@ -212,7 +212,7 @@ void FilterManagerImpl::apply(Transaction& transaction)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Patch "m_cel"
|
// Patch "m_cel"
|
||||||
transaction.execute(
|
m_transaction->execute(
|
||||||
new cmd::PatchCel(
|
new cmd::PatchCel(
|
||||||
m_cel, m_dst.get(),
|
m_cel, m_dst.get(),
|
||||||
gfx::Region(output),
|
gfx::Region(output),
|
||||||
@ -239,7 +239,7 @@ void FilterManagerImpl::applyToTarget()
|
|||||||
// Initialize writting operation
|
// Initialize writting operation
|
||||||
ContextReader reader(m_context);
|
ContextReader reader(m_context);
|
||||||
ContextWriter writer(reader);
|
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_progressBase = 0.0f;
|
||||||
m_progressWidth = 1.0f / images.size();
|
m_progressWidth = 1.0f / images.size();
|
||||||
@ -250,7 +250,7 @@ void FilterManagerImpl::applyToTarget()
|
|||||||
if (paletteChange) {
|
if (paletteChange) {
|
||||||
Palette newPalette = *getNewPalette();
|
Palette newPalette = *getNewPalette();
|
||||||
restoreSpritePalette();
|
restoreSpritePalette();
|
||||||
transaction.execute(
|
m_transaction->execute(
|
||||||
new cmd::SetPalette(m_site.sprite(),
|
new cmd::SetPalette(m_site.sprite(),
|
||||||
m_site.frame(), &newPalette));
|
m_site.frame(), &newPalette));
|
||||||
}
|
}
|
||||||
@ -264,7 +264,7 @@ void FilterManagerImpl::applyToTarget()
|
|||||||
// Avoid applying the filter two times to the same image
|
// Avoid applying the filter two times to the same image
|
||||||
if (visited.find(image->id()) == visited.end()) {
|
if (visited.find(image->id()) == visited.end()) {
|
||||||
visited.insert(image->id());
|
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?
|
// 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;
|
m_progressBase += m_progressWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction.commit();
|
|
||||||
|
|
||||||
// Reset m_oldPalette to avoid restoring the color palette
|
// Reset m_oldPalette to avoid restoring the color palette
|
||||||
m_oldPalette.reset(nullptr);
|
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()
|
void FilterManagerImpl::flush()
|
||||||
{
|
{
|
||||||
int h = m_row - m_nextRowToFlush;
|
int h = m_row - m_nextRowToFlush;
|
||||||
@ -395,10 +400,10 @@ void FilterManagerImpl::init(Cel* cel)
|
|||||||
m_target &= ~TARGET_ALPHA_CHANNEL;
|
m_target &= ~TARGET_ALPHA_CHANNEL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FilterManagerImpl::applyToCel(Transaction& transaction, Cel* cel)
|
void FilterManagerImpl::applyToCel(Cel* cel)
|
||||||
{
|
{
|
||||||
init(cel);
|
init(cel);
|
||||||
apply(transaction);
|
apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FilterManagerImpl::updateBounds(doc::Mask* mask)
|
bool FilterManagerImpl::updateBounds(doc::Mask* mask)
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "gfx/rect.h"
|
#include "gfx/rect.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace doc {
|
namespace doc {
|
||||||
class Cel;
|
class Cel;
|
||||||
@ -82,6 +83,7 @@ namespace app {
|
|||||||
void end();
|
void end();
|
||||||
bool applyStep();
|
bool applyStep();
|
||||||
void applyToTarget();
|
void applyToTarget();
|
||||||
|
void commitTransaction();
|
||||||
|
|
||||||
app::Document* document();
|
app::Document* document();
|
||||||
doc::Sprite* sprite() { return m_site.sprite(); }
|
doc::Sprite* sprite() { return m_site.sprite(); }
|
||||||
@ -114,8 +116,8 @@ namespace app {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void init(doc::Cel* cel);
|
void init(doc::Cel* cel);
|
||||||
void apply(Transaction& transaction);
|
void apply();
|
||||||
void applyToCel(Transaction& transaction, doc::Cel* cel);
|
void applyToCel(doc::Cel* cel);
|
||||||
bool updateBounds(doc::Mask* mask);
|
bool updateBounds(doc::Mask* mask);
|
||||||
bool paletteHasChanged();
|
bool paletteHasChanged();
|
||||||
void restoreSpritePalette();
|
void restoreSpritePalette();
|
||||||
@ -136,6 +138,7 @@ namespace app {
|
|||||||
Target m_targetOrig; // Original targets
|
Target m_targetOrig; // Original targets
|
||||||
Target m_target; // Filtered targets
|
Target m_target; // Filtered targets
|
||||||
base::UniquePtr<doc::Palette> m_oldPalette;
|
base::UniquePtr<doc::Palette> m_oldPalette;
|
||||||
|
std::unique_ptr<Transaction> m_transaction;
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
float m_progressBase;
|
float m_progressBase;
|
||||||
|
@ -104,7 +104,9 @@ void FilterWorker::run()
|
|||||||
|
|
||||||
{
|
{
|
||||||
scoped_lock lock(m_mutex);
|
scoped_lock lock(m_mutex);
|
||||||
if (!m_done)
|
if (m_done)
|
||||||
|
m_filterMgr->commitTransaction();
|
||||||
|
else
|
||||||
m_cancelled = true;
|
m_cancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// Aseprite
|
// Aseprite
|
||||||
// Copyright (C) 2001-2015 David Capello
|
// Copyright (C) 2001-2017 David Capello
|
||||||
//
|
//
|
||||||
// This program is distributed under the terms of
|
// This program is distributed under the terms of
|
||||||
// the End-User License Agreement for Aseprite.
|
// 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 you don't use this routine, all the changes will be discarded
|
||||||
// (if the sprite's undo was enabled when the Transaction was
|
// (if the sprite's undo was enabled when the Transaction was
|
||||||
// created).
|
// 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 commit();
|
||||||
|
|
||||||
void execute(Cmd* cmd);
|
void execute(Cmd* cmd);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user