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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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…
	
		Reference in New Issue