Krita Source Code Documentation
Loading...
Searching...
No Matches
KisSuspendProjectionUpdatesStrokeStrategy Class Reference

#include <kis_suspend_projection_updates_stroke_strategy.h>

+ Inheritance diagram for KisSuspendProjectionUpdatesStrokeStrategy:

Classes

struct  Private
 
struct  SharedData
 
struct  SuspendUpdatesFilterInterface
 

Public Types

using SharedDataSP = QSharedPointer<SharedData>
 
- Public Types inherited from KisSimpleStrokeStrategy
enum  JobType {
  JOB_INIT = 0 , JOB_CANCEL , JOB_FINISH , JOB_DOSTROKE ,
  JOB_SUSPEND , JOB_RESUME , NJOBS
}
 

Public Member Functions

 KisSuspendProjectionUpdatesStrokeStrategy (KisImageWSP image, bool suspend, SharedDataSP sharedData)
 
 ~KisSuspendProjectionUpdatesStrokeStrategy () override
 
- Public Member Functions inherited from KisRunnableBasedStrokeStrategy
 KisRunnableBasedStrokeStrategy (const KisRunnableBasedStrokeStrategy &rhs)
 
 KisRunnableBasedStrokeStrategy (const QLatin1String &id, const KUndo2MagicString &name=KUndo2MagicString())
 
KisRunnableStrokeJobsInterfacerunnableJobsInterface () const
 
 ~KisRunnableBasedStrokeStrategy ()
 
- Public Member Functions inherited from KisSimpleStrokeStrategy
KisStrokeJobDatacreateCancelData () override
 
KisStrokeJobStrategycreateCancelStrategy () override
 
KisStrokeJobStrategycreateDabStrategy () override
 
KisStrokeJobDatacreateFinishData () override
 
KisStrokeJobStrategycreateFinishStrategy () override
 
KisStrokeJobDatacreateInitData () override
 
KisStrokeJobStrategycreateInitStrategy () override
 
KisStrokeJobDatacreateResumeData () override
 
KisStrokeJobStrategycreateResumeStrategy () override
 
KisStrokeJobDatacreateSuspendData () override
 
KisStrokeJobStrategycreateSuspendStrategy () override
 
virtual void finishStrokeCallback ()
 
 KisSimpleStrokeStrategy (const QLatin1String &id, const KUndo2MagicString &name=KUndo2MagicString())
 
- Public Member Functions inherited from KisStrokeStrategy
qreal balancingRatioOverride () const
 
bool canForgetAboutMe () const
 
bool clearsRedoOnStart () const
 
virtual KisStrokeStrategycreateLodClone (int levelOfDetail)
 
KisLodPreferences currentLodPreferences () const
 
bool forceLodModeIfPossible () const
 
QString id () const
 
bool isAsynchronouslyCancellable () const
 
bool isExclusive () const
 
 KisStrokeStrategy (const QLatin1String &id, const KUndo2MagicString &name=KUndo2MagicString())
 
KUndo2MagicString name () const
 
bool needsExplicitCancel () const
 
virtual void notifyUserEndedStroke ()
 
virtual void notifyUserStartedStroke ()
 
bool requestsOtherStrokesToEnd () const
 
void setForceLodModeIfPossible (bool forceLodModeIfPossible)
 
void setMutatedJobsInterface (KisStrokesQueueMutatedJobInterface *mutatedJobsInterface, KisStrokeId strokeId)
 
bool supportsWrapAroundMode () const
 
virtual void tryCancelCurrentStrokeJobAsync ()
 tryCancelCurrentStrokeJobAsync is called by the strokes queue when the stroke is being cancelled. The stroke strategy may or may not handle this request and cancel the currently running long action.
 
virtual ~KisStrokeStrategy ()
 

Static Public Member Functions

static QList< KisStrokeJobData * > createResumeJobsData (KisImageWSP image)
 
static SharedDataSP createSharedData ()
 
static QList< KisStrokeJobData * > createSuspendJobsData (KisImageWSP image)
 
- Static Public Member Functions inherited from KisSimpleStrokeStrategy
static QLatin1String jobTypeToString (JobType type)
 

Private Member Functions

void cancelStrokeCallback () override
 
void doStrokeCallback (KisStrokeJobData *data) override
 
void initStrokeCallback () override
 
void resumeStrokeCallback () override
 
void suspendStrokeCallback () override
 

Private Attributes

const QScopedPointer< Privatem_d
 

Additional Inherited Members

- Protected Member Functions inherited from KisSimpleStrokeStrategy
void enableJob (JobType type, bool enable=true, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
 
 KisSimpleStrokeStrategy (const KisSimpleStrokeStrategy &rhs)
 
- Protected Member Functions inherited from KisStrokeStrategy
void addMutatedJob (KisStrokeJobData *data)
 
void addMutatedJobs (const QVector< KisStrokeJobData * > list)
 
 KisStrokeStrategy (const KisStrokeStrategy &rhs)
 
void setAsynchronouslyCancellable (bool value)
 
void setBalancingRatioOverride (qreal value)
 
void setCanForgetAboutMe (bool value)
 
void setClearsRedoOnStart (bool value)
 
void setExclusive (bool value)
 
void setNeedsExplicitCancel (bool value)
 
void setRequestsOtherStrokesToEnd (bool value)
 
void setSupportsWrapAroundMode (bool value)
 

Detailed Description

Member Typedef Documentation

◆ SharedDataSP

Constructor & Destructor Documentation

◆ KisSuspendProjectionUpdatesStrokeStrategy()

KisSuspendProjectionUpdatesStrokeStrategy::KisSuspendProjectionUpdatesStrokeStrategy ( KisImageWSP image,
bool suspend,
SharedDataSP sharedData )

Here we add a dumb INIT job so that KisStrokesQueue would know that the stroke has already started or not. When the queue reaches the resume stroke and starts its execution, no Lod0 can execute anymore. So all the new Lod0 strokes should go to the end of the queue and wrapped into their own Suspend/Resume pair.

Definition at line 426 of file kis_suspend_projection_updates_stroke_strategy.cpp.

428 QLatin1String("suspend_stroke_strategy") :
429 QLatin1String("resume_stroke_strategy")),
430 m_d(new Private)
431{
432 m_d->image = image;
433 m_d->suspend = suspend;
434 m_d->sharedData = sharedData;
435
443 enableJob(JOB_INIT, true);
444
445 enableJob(JOB_DOSTROKE, true);
446 enableJob(JOB_CANCEL, true);
447
450
453}
KisRunnableBasedStrokeStrategy(const QLatin1String &id, const KUndo2MagicString &name=KUndo2MagicString())
void enableJob(JobType type, bool enable=true, KisStrokeJobData::Sequentiality sequentiality=KisStrokeJobData::SEQUENTIAL, KisStrokeJobData::Exclusivity exclusivity=KisStrokeJobData::NORMAL)
void setClearsRedoOnStart(bool value)
void setNeedsExplicitCancel(bool value)

References KisStrokeJobData::BARRIER, KisSimpleStrokeStrategy::enableJob(), KisSimpleStrokeStrategy::JOB_CANCEL, KisSimpleStrokeStrategy::JOB_DOSTROKE, KisSimpleStrokeStrategy::JOB_INIT, KisSimpleStrokeStrategy::JOB_RESUME, KisSimpleStrokeStrategy::JOB_SUSPEND, m_d, KisStrokeStrategy::setClearsRedoOnStart(), and KisStrokeStrategy::setNeedsExplicitCancel().

◆ ~KisSuspendProjectionUpdatesStrokeStrategy()

KisSuspendProjectionUpdatesStrokeStrategy::~KisSuspendProjectionUpdatesStrokeStrategy ( )
override

Definition at line 455 of file kis_suspend_projection_updates_stroke_strategy.cpp.

456{
457 qDeleteAll(m_d->executedCommands);
458}

References m_d.

Member Function Documentation

◆ cancelStrokeCallback()

void KisSuspendProjectionUpdatesStrokeStrategy::cancelStrokeCallback ( )
overrideprivatevirtual

We shouldn't Q_EMIT any ad-hoc updates when cancelling the stroke. It generates weird temporary holes on the canvas, making the user feel awful, thinking his image got corrupted. We will just Q_EMIT a common refreshGraphAsync() that will do all the work in a beautiful way

Reimplemented from KisSimpleStrokeStrategy.

Definition at line 571 of file kis_suspend_projection_updates_stroke_strategy.cpp.

572{
573 KisImageSP image = m_d->image.toStrongRef();
574 if (!image) {
575 return;
576 }
577
578 for (auto it = m_d->executedCommands.rbegin(); it != m_d->executedCommands.rend(); ++it) {
579 (*it)->undo();
580 }
581
582 m_d->tryFetchUsedUpdatesFilter(image);
583
584 if (m_d->haveDisabledGUILodSync) {
586 }
587
595 if (!m_d->suspend) {
596 // FIXME: optimize
597 image->refreshGraphAsync();
598 }
599}
void emitRequestLodPlanesSyncBlocked(bool value)
void refreshGraphAsync(KisNodeSP root, const QVector< QRect > &rects, const QRect &cropRect, KisProjectionUpdateFlags flags=KisProjectionUpdateFlag::None) override
KisImageSignalRouter * signalRouter()

References KisImageSignalRouter::emitRequestLodPlanesSyncBlocked(), m_d, KisImage::refreshGraphAsync(), and KisImage::signalRouter().

◆ createResumeJobsData()

QList< KisStrokeJobData * > KisSuspendProjectionUpdatesStrokeStrategy::createResumeJobsData ( KisImageWSP image)
static

◆ createSharedData()

KisSuspendProjectionUpdatesStrokeStrategy::SharedDataSP KisSuspendProjectionUpdatesStrokeStrategy::createSharedData ( )
static

Definition at line 537 of file kis_suspend_projection_updates_stroke_strategy.cpp.

538{
539 return toQShared(new SharedData());
540}
QSharedPointer< T > toQShared(T *ptr)

References toQShared().

◆ createSuspendJobsData()

QList< KisStrokeJobData * > KisSuspendProjectionUpdatesStrokeStrategy::createSuspendJobsData ( KisImageWSP image)
static

Definition at line 527 of file kis_suspend_projection_updates_stroke_strategy.cpp.

528{
530}

◆ doStrokeCallback()

void KisSuspendProjectionUpdatesStrokeStrategy::doStrokeCallback ( KisStrokeJobData * data)
overrideprivatevirtual

When the Lod0 stroke is being recalculated in the background we should block all the updates it issues to avoid user distraction. The result of the final stroke should be shown to the user in the very end when everything is fully ready. Ideally the use should not notice that the image has changed :)

(Don't mix this process with suspend/resume capabilities of a single stroke. That is a different system!)

The process of the Lod0 regeneration consists of the following:

1) Suspend stroke executes. It sets a special updates filter on the image. The filter blocks all the updates and saves them in an internal structure to be emitted in the future.

2) Lod0 strokes are being recalculated. All their updates are blocked and saved in the filter.

3) Resume stroke starts:

3.1) First it disables emitting of sigImageUpdated() so the gui
     will not get any update notifications.

3.2) Then it enables updates themselves.

3.3) Initiates all the updates that were requested by the Lod0
     stroke. The node graph is regenerated, but the GUI does
     not get this change.

3.4) Special barrier job waits for all the updates to finish
     and, when they are done, enables GUI notifications again.

3.5) In a multithreaded way emits the GUI notifications for the
     entire image. Multithreaded way is used to conform the
     double-stage update principle of KisCanvas2.

Reimplemented from KisRunnableBasedStrokeStrategy.

Definition at line 514 of file kis_suspend_projection_updates_stroke_strategy.cpp.

515{
516 KisRunnableStrokeJobDataBase *runnable = dynamic_cast<KisRunnableStrokeJobDataBase*>(data);
517 if (runnable) {
518 runnable->run();
519
520 if (Private::UndoableData *undoable = dynamic_cast<Private::UndoableData*>(data)) {
521 Private::StrokeJobCommand *command = undoable->m_command.release();
522 m_d->executedCommands.append(command);
523 }
524 }
525}
virtual void run()=0

References m_d, and KisRunnable::run().

◆ initStrokeCallback()

void KisSuspendProjectionUpdatesStrokeStrategy::initStrokeCallback ( )
overrideprivatevirtual

Reimplemented from KisSimpleStrokeStrategy.

Definition at line 460 of file kis_suspend_projection_updates_stroke_strategy.cpp.

461{
463
464 if (m_d->suspend) {
465 jobs << new Private::UndoableData(new Private::SuspendUpdatesCommand(m_d.data()));
466 } else {
467 jobs << new Private::UndoableData(new Private::ResumeAndIssueGraphUpdatesCommand(m_d.data()));
468 jobs << new Private::BlockUILodSync(true, this);
469 jobs << new Private::UndoableData(new Private::StartBatchUIUpdatesCommand(this));
470 jobs << new Private::UndoableData(new Private::EndBatchUIUpdatesCommand(this));
471 jobs << new Private::BlockUILodSync(false, this);
472 }
473
475}
KisRunnableStrokeJobsInterface * runnableJobsInterface() const
virtual void addRunnableJobs(const QVector< KisRunnableStrokeJobDataBase * > &list)=0

References KisRunnableStrokeJobsInterface::addRunnableJobs(), m_d, and KisRunnableBasedStrokeStrategy::runnableJobsInterface().

◆ resumeStrokeCallback()

void KisSuspendProjectionUpdatesStrokeStrategy::resumeStrokeCallback ( )
overrideprivatevirtual

Reimplemented from KisSimpleStrokeStrategy.

Definition at line 623 of file kis_suspend_projection_updates_stroke_strategy.cpp.

624{
626
627 Q_FOREACH (Private::StrokeJobCommand *command, m_d->executedCommands) {
628 jobs << new Private::UndoableData(command);
629 }
630 m_d->executedCommands.clear();
631
633}

References KisRunnableStrokeJobsInterface::addRunnableJobs(), m_d, and KisRunnableBasedStrokeStrategy::runnableJobsInterface().

◆ suspendStrokeCallback()

void KisSuspendProjectionUpdatesStrokeStrategy::suspendStrokeCallback ( )
overrideprivatevirtual

The resume stroke can be suspended even when all its jobs are completed. In such a case, we should just ensure that all the internal state is reset to default.

Reimplemented from KisSimpleStrokeStrategy.

Definition at line 601 of file kis_suspend_projection_updates_stroke_strategy.cpp.

602{
610 !m_d->sanityResumingFinished ||
611 (m_d->sanityResumingFinished &&
612 m_d->usedFilters.isEmpty() &&
613 m_d->accumulatedDirtyRects.isEmpty()));
614
615 for (auto it = m_d->executedCommands.rbegin(); it != m_d->executedCommands.rend(); ++it) {
616 (*it)->undo();
617 }
618
619 // reset all the issued updates
620 m_d->updatesEpoch++;
621}
#define KIS_SAFE_ASSERT_RECOVER_NOOP(cond)
Definition kis_assert.h:130

References KIS_SAFE_ASSERT_RECOVER_NOOP, and m_d.

Member Data Documentation

◆ m_d

const QScopedPointer<Private> KisSuspendProjectionUpdatesStrokeStrategy::m_d
private

The documentation for this class was generated from the following files: