mirror of https://github.com/aseprite/aseprite.git
				
				
				
			Fix possibilities of random crashes using filters w/Undo History window visible
Same problem as in 86a6462d7b
			
			
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…
	
		Reference in New Issue