File indexing completed on 2024-05-12 16:01:45
0001 /* 0002 * SPDX-FileCopyrightText: 2017 Dmitry Kazakov <dimula73@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KISASYNCANIMATIONRENDERERBASE_H 0008 #define KISASYNCANIMATIONRENDERERBASE_H 0009 0010 #include <QObject> 0011 #include "kis_types.h" 0012 0013 #include "kritaui_export.h" 0014 0015 class KisRegion; 0016 0017 /** 0018 * KisAsyncAnimationRendererBase is a special class representing a 0019 * single worker thread inside KisAsyncAnimationRenderDialogBase. It connects 0020 * the specified image using correct Qt::DirectConnection connections and 0021 * reacts on them. On sigFrameReady() signal it calls frameCompletedCallback(), 0022 * so the derived class can fetch a frame from the image and process it. On 0023 * sigFrameCancelled() it calls frameCancelledCallback(). The derived class 0024 * should override these two methods to do the actual work. 0025 */ 0026 0027 class KRITAUI_EXPORT KisAsyncAnimationRendererBase : public QObject 0028 { 0029 Q_OBJECT 0030 0031 public: 0032 enum Flag 0033 { 0034 None = 0x0, 0035 Cancellable = 0x1 0036 }; 0037 Q_DECLARE_FLAGS(Flags, Flag) 0038 0039 enum CancelReason { 0040 UserCancelled = 0, 0041 RenderingFailed, 0042 RenderingTimedOut 0043 }; 0044 Q_ENUM(CancelReason) 0045 0046 public: 0047 explicit KisAsyncAnimationRendererBase(QObject *parent = 0); 0048 virtual ~KisAsyncAnimationRendererBase(); 0049 0050 /** 0051 * Initiates the rendering of the frame \p frame on an image \p image. 0052 * Only \p regionOfInterest is regenerated. If \p regionOfInterest is 0053 * empty, then entire bounds of the image is regenerated. 0054 */ 0055 void startFrameRegeneration(KisImageSP image, int frame, const KisRegion ®ionOfInterest, Flags flags = None); 0056 0057 /** 0058 * Convenience overload that regenerates the full image 0059 */ 0060 void startFrameRegeneration(KisImageSP image, int frame, Flags flags = None); 0061 0062 /** 0063 * @return true if the regeneration process is in progress 0064 */ 0065 bool isActive() const; 0066 0067 public Q_SLOTS: 0068 /** 0069 * @brief cancels current rendering operation 0070 * 0071 * After calling this slot requestedImage() becomes invalid. 0072 * @see requestedImage() 0073 */ 0074 void cancelCurrentFrameRendering(CancelReason cancelReason); 0075 0076 Q_SIGNALS: 0077 void sigFrameCompleted(int frame); 0078 void sigFrameCancelled(int frame, KisAsyncAnimationRendererBase::CancelReason cancelReason); 0079 0080 private Q_SLOTS: 0081 void slotFrameRegenerationCancelled(); 0082 void slotFrameRegenerationTimedOut(); 0083 void slotFrameRegenerationFinished(int frame); 0084 0085 protected Q_SLOTS: 0086 /** 0087 * Called by a derived class to continue processing of the frames 0088 */ 0089 void notifyFrameCompleted(int frame); 0090 0091 /** 0092 * Called by a derived class to cancel processing of the frames. After calling 0093 * this method, the dialog will stop processing the frames and close. 0094 */ 0095 void notifyFrameCancelled(int frame, KisAsyncAnimationRendererBase::CancelReason cancelReason); 0096 0097 protected: 0098 /** 0099 * @brief frameCompletedCallback is called by the renderer when 0100 * a new frame becomes ready 0101 * 0102 * NOTE1: the callback is called from the context of a image 0103 * worker thread! So it is asynchronous from the GUI thread. 0104 * NOTE2: in case of successful processing of the frame, the callback 0105 * must issue some signal, connected to notifyFrameCompleted() 0106 * via auto connection, to continue processing. Please do not 0107 * call the method directly, because notifyFame*() slots should 0108 * be called from the context of the GUI thread. 0109 * NOTE3: In case of failure, notifyFrameCancelled(). The same threading 0110 * rules apply. 0111 */ 0112 virtual void frameCompletedCallback(int frame, const KisRegion &requestedRegion) = 0; 0113 0114 /** 0115 * @brief frameCancelledCallback is called when the rendering of 0116 * the frame was cancelled. 0117 * 0118 * The rendering of the frame can be either cancelled by the image itself or 0119 * by receiving a timeout signal (10 seconds). 0120 * 0121 * NOTE: the slot is called in the GUI thread. Don't forget to call 0122 * notifyFrameCancelled() in he end of your call. 0123 */ 0124 virtual void frameCancelledCallback(int frame, CancelReason cancelReason) = 0; 0125 0126 0127 /** 0128 * Called by KisAsyncAnimationRendererBase when the processing has been completed 0129 * and the internal state of the populator should be cleared 0130 * 0131 * @param isCancelled tells if frame regeneration has failed to be regenerated 0132 */ 0133 virtual void clearFrameRegenerationState(bool isCancelled); 0134 0135 protected: 0136 /** 0137 * @return the image that for which the rendering was requested using 0138 * startFrameRegeneration(). Should be used by the derived classes only. 0139 * 0140 * Please note that requestedImage() will become null as soon as the user 0141 * cancels the processing. That happens in the GUI thread so 0142 * frameCompletedCallback() should be extremely careful when requesting the 0143 * value (check the shared pointer after fetching). 0144 */ 0145 KisImageSP requestedImage() const; 0146 0147 private: 0148 struct Private; 0149 const QScopedPointer<Private> m_d; 0150 }; 0151 0152 Q_DECLARE_OPERATORS_FOR_FLAGS(KisAsyncAnimationRendererBase::Flags) 0153 0154 #endif // KISASYNCANIMATIONRENDERERBASE_H