File indexing completed on 2024-05-19 04:26:35

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Dmitry Kazakov <dimula73@gmail.com>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #ifndef __KIS_STROKE_STRATEGY_H
0008 #define __KIS_STROKE_STRATEGY_H
0009 
0010 #include <QString>
0011 #include "kis_types.h"
0012 #include "kundo2magicstring.h"
0013 #include "kritaimage_export.h"
0014 #include "KisLodPreferences.h"
0015 
0016 class KisStrokeJobStrategy;
0017 class KisStrokeJobData;
0018 class KisStrokesQueueMutatedJobInterface;
0019 
0020 class KRITAIMAGE_EXPORT KisStrokeStrategy
0021 {
0022 public:
0023     KisStrokeStrategy(const QLatin1String &id, const KUndo2MagicString &name = KUndo2MagicString());
0024     virtual ~KisStrokeStrategy();
0025 
0026     /**
0027      * notifyUserStartedStroke() is a callback used by the strokes system to notify
0028      * when the user adds the stroke to the strokes queue. That moment corresponds
0029      * to the user calling strokesFacade->startStroke(strategy) and might happen much
0030      * earlier than the first job being executed.
0031      *
0032      * NOTE: this method will be executed in the context of the GUI thread!
0033      */
0034     virtual void notifyUserStartedStroke();
0035 
0036     /**
0037      * notifyUserEndedStroke() is a callback used by the strokes system to notify
0038      * when the user ends the stroke. That moment corresponds to the user calling
0039      * strokesFacade->endStroke(id) and might happen much earlier when the stroke
0040      * even started its execution.
0041      *
0042      * NOTE: this method will be executed in the context of the GUI thread!
0043      */
0044     virtual void notifyUserEndedStroke();
0045 
0046     virtual KisStrokeJobStrategy* createInitStrategy();
0047     virtual KisStrokeJobStrategy* createFinishStrategy();
0048     virtual KisStrokeJobStrategy* createCancelStrategy();
0049     virtual KisStrokeJobStrategy* createDabStrategy();
0050     virtual KisStrokeJobStrategy* createSuspendStrategy();
0051     virtual KisStrokeJobStrategy* createResumeStrategy();
0052 
0053     virtual KisStrokeJobData* createInitData();
0054     virtual KisStrokeJobData* createFinishData();
0055     virtual KisStrokeJobData* createCancelData();
0056     virtual KisStrokeJobData* createSuspendData();
0057     virtual KisStrokeJobData* createResumeData();
0058 
0059     virtual KisStrokeStrategy* createLodClone(int levelOfDetail);
0060 
0061     /**
0062      * @brief tryCancelCurrentStrokeJobAsync is called by the strokes queue
0063      * when the stroke is being cancelled. The stroke strategy may or may not
0064      * handle this request and cancel the currently running long action.
0065      */
0066     virtual void tryCancelCurrentStrokeJobAsync();
0067 
0068     bool isExclusive() const;
0069     bool supportsWrapAroundMode() const;
0070 
0071 
0072     /**
0073      * Returns true if mere start of the stroke should cancel all the
0074      * pending redo tasks.
0075      *
0076      * This method should return true in almost all circumstances
0077      * except if we are running an undo or redo stroke.
0078      */
0079     bool clearsRedoOnStart() const;
0080 
0081     /**
0082      * Returns true if the other currently running strokes should be
0083      * politely asked to exit. The default value is 'true'.
0084      *
0085      * The only known exception right now is
0086      * KisRegenerateFrameStrokeStrategy which does not requests ending
0087      * of any actions, since it performs purely background action.
0088      */
0089     bool requestsOtherStrokesToEnd() const;
0090 
0091     /**
0092      * Returns true if the update scheduler can cancel this stroke
0093      * when some other stroke is going to be started. This makes the
0094      * "forgettable" stroke very low priority.
0095      *
0096      * Default is 'false'.
0097      */
0098     bool canForgetAboutMe() const;
0099 
0100     /**
0101      * Returns true if the stroke can be cancelled by the
0102      * engine, e.g. when the user presses Esc key or
0103      * Ctrl+Z shortcut. Default value is true. The only
0104      * exception right now are the strokes that perform
0105      * undo/redo operations.
0106      *
0107      * The owner of the stroke can still cancel the stroke
0108      * via the strokeId handle (though it is not used for
0109      * undo/redo strokes).
0110      */
0111     bool isAsynchronouslyCancellable() const;
0112 
0113     bool needsExplicitCancel() const;
0114 
0115 
0116     /**
0117      * \see setBalancingRatioOverride() for details
0118      */
0119     qreal balancingRatioOverride() const;
0120 
0121     QString id() const;
0122     KUndo2MagicString name() const;
0123 
0124     /**
0125      * Returns current lod preferences of the strokes queue
0126      */
0127     KisLodPreferences currentLodPreferences() const;
0128 
0129     void setMutatedJobsInterface(KisStrokesQueueMutatedJobInterface *mutatedJobsInterface, KisStrokeId strokeId);
0130 
0131     bool forceLodModeIfPossible() const;
0132     void setForceLodModeIfPossible(bool forceLodModeIfPossible);
0133 
0134 protected:
0135     // testing surrogate class
0136     friend class KisMutatableDabStrategy;
0137 
0138     /**
0139      * This function is supposed to be called by internal asynchronous
0140      * jobs. It allows adding subtasks that may be executed concurrently.
0141      *
0142      * Requirements:
0143      *   * must be called *only* from within the context of the strokes
0144      *     worker thread during execution of one of its jobs
0145      *
0146      * Guarantees:
0147      *   * the added job is guaranteed to be executed in some time after
0148      *     the currently executed job, *before* the next SEQUENTIAL or
0149      *     BARRIER job
0150      *   * if the currently executed job is CONCURRENT, the mutated job *may*
0151      *     start execution right after adding to the queue without waiting for
0152      *     its parent to complete. Though this behavior is *not* guaranteed,
0153      *     because addMutatedJob does not initiate processQueues(), because
0154      *     it may lead to a deadlock.
0155      */
0156     void addMutatedJobs(const QVector<KisStrokeJobData*> list);
0157 
0158     /**
0159      * Convenience override for addMutatedJobs()
0160      */
0161     void addMutatedJob(KisStrokeJobData *data);
0162 
0163 
0164     // you are not supposed to change these parameters
0165     // after the KisStroke object has been created
0166 
0167     void setExclusive(bool value);
0168     void setSupportsWrapAroundMode(bool value);
0169     void setClearsRedoOnStart(bool value);
0170     void setRequestsOtherStrokesToEnd(bool value);
0171     void setCanForgetAboutMe(bool value);
0172     void setAsynchronouslyCancellable(bool value);
0173     void setNeedsExplicitCancel(bool value);
0174 
0175     /**
0176      * Set override for the desired scheduler balancing ratio:
0177      *
0178      * ratio = stroke jobs / update jobs
0179      *
0180      * If \p value < 1.0, then the priority is given to updates, if
0181      * the value is higher than 1.0, then the priority is given
0182      * to stroke jobs.
0183      *
0184      * Special value -1.0, suggests the scheduler to use the default value
0185      * set by the user's config file (which is 100.0 by default).
0186      */
0187     void setBalancingRatioOverride(qreal value);
0188 
0189 protected:
0190     /**
0191      * Protected c-tor, used for cloning of hi-level strategies
0192      */
0193     KisStrokeStrategy(const KisStrokeStrategy &rhs);
0194 
0195 private:
0196     bool m_exclusive;
0197     bool m_supportsWrapAroundMode;
0198 
0199     bool m_clearsRedoOnStart;
0200     bool m_requestsOtherStrokesToEnd;
0201     bool m_canForgetAboutMe;
0202     bool m_asynchronouslyCancellable;
0203     bool m_needsExplicitCancel;
0204     bool m_forceLodModeIfPossible;
0205     qreal m_balancingRatioOverride;
0206 
0207     QLatin1String m_id;
0208     KUndo2MagicString m_name;
0209 
0210     KisStrokeId m_strokeId;
0211     KisStrokesQueueMutatedJobInterface *m_mutatedJobsInterface;
0212 };
0213 
0214 #endif /* __KIS_STROKE_STRATEGY_H */