1 /* 2 * Copyright (c) 2017 Dmitry Kazakov <dimula73@gmail.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 */ 18 19 #ifndef KISASYNCANIMATIONRENDERERBASE_H 20 #define KISASYNCANIMATIONRENDERERBASE_H 21 22 #include <QObject> 23 #include "kis_types.h" 24 25 #include "kritaui_export.h" 26 27 class KisRegion; 28 29 /** 30 * KisAsyncAnimationRendererBase is a special class representing a 31 * single worker thread inside KisAsyncAnimationRenderDialogBase. It connects 32 * the specified image using correct Qt::DirectConnection connections and 33 * reacts on them. On sigFrameReady() signal it calls frameCompletedCallback(), 34 * so the derived class can fetch a frame from the image and process it. On 35 * sigFrameCancelled() it calls frameCancelledCallback(). The derived class 36 * should override these two methods to do the actual work. 37 */ 38 39 class KRITAUI_EXPORT KisAsyncAnimationRendererBase : public QObject 40 { 41 Q_OBJECT 42 public: 43 explicit KisAsyncAnimationRendererBase(QObject *parent = 0); 44 virtual ~KisAsyncAnimationRendererBase(); 45 46 /** 47 * Initiates the rendering of the frame \p frame on an image \p image. 48 * Only \p regionOfInterest is regenerated. If \p regionOfInterest is 49 * empty, then entire bounds of the image is regenerated. 50 */ 51 void startFrameRegeneration(KisImageSP image, int frame, const KisRegion ®ionOfInterest); 52 53 /** 54 * Convenience overload that regenerates the full image 55 */ 56 void startFrameRegeneration(KisImageSP image, int frame); 57 58 /** 59 * @return true if the regeneration process is in progress 60 */ 61 bool isActive() const; 62 63 public Q_SLOTS: 64 /** 65 * @brief cancels current rendering operation 66 * 67 * After calling this slot requestedImage() becomes invalid. 68 * @see requestedImage() 69 */ 70 void cancelCurrentFrameRendering(); 71 72 Q_SIGNALS: 73 void sigFrameCompleted(int frame); 74 void sigFrameCancelled(int frame); 75 76 private Q_SLOTS: 77 void slotFrameRegenerationCancelled(); 78 void slotFrameRegenerationFinished(int frame); 79 80 protected Q_SLOTS: 81 /** 82 * Called by a derived class to continue processing of the frames 83 */ 84 void notifyFrameCompleted(int frame); 85 86 /** 87 * Called by a derived class to cancel processing of the frames. After calling 88 * this method, the dialog will stop processing the frames and close. 89 */ 90 void notifyFrameCancelled(int frame); 91 92 protected: 93 /** 94 * @brief frameCompletedCallback is called by the renderer when 95 * a new frame becomes ready 96 * 97 * NOTE1: the callback is called from the context of a image 98 * worker thread! So it is asynchronous from the GUI thread. 99 * NOTE2: in case of successful processing of the frame, the callback 100 * must issue some signal, connected to notifyFrameCompleted() 101 * via auto connection, to continue processing. Please do not 102 * call the method directly, because notifyFame*() slots should 103 * be called from the context of the GUI thread. 104 * NOTE3: In case of failure, notifyFrameCancelled(). The same threading 105 * rules apply. 106 */ 107 virtual void frameCompletedCallback(int frame, const KisRegion &requestedRegion) = 0; 108 109 /** 110 * @brief frameCancelledCallback is called when the rendering of 111 * the frame was cancelled. 112 * 113 * The rendering of the frame can be either cancelled by the image itself or 114 * by receiving a timeout signal (10 seconds). 115 * 116 * NOTE: the slot is called in the GUI thread. Don't forget to call 117 * notifyFrameCancelled() in he end of your call. 118 */ 119 virtual void frameCancelledCallback(int frame) = 0; 120 121 122 /** 123 * Called by KisAsyncAnimationRendererBase when the processing has been completed 124 * and the internal state of the populator should be cleared 125 * 126 * @param isCancelled tells if frame regeneration has failed to be regenerated 127 */ 128 virtual void clearFrameRegenerationState(bool isCancelled); 129 130 protected: 131 /** 132 * @return the image that for which the rendering was requested using 133 * startFrameRegeneration(). Should be used by the derived classes only. 134 * 135 * Please note that requestedImage() will become null as soon as the user 136 * cancels the processing. That happens in the GUI thread so 137 * frameCompletedCallback() should be extremely careful when requesting the 138 * value (check the shared pointer after fetching). 139 */ 140 KisImageSP requestedImage() const; 141 142 private: 143 struct Private; 144 const QScopedPointer<Private> m_d; 145 }; 146 147 #endif // KISASYNCANIMATIONRENDERERBASE_H 148