1 /*****************************************************************************/ 2 // Copyright 2006-2019 Adobe Systems Incorporated 3 // All Rights Reserved. 4 // 5 // NOTICE: Adobe permits you to use, modify, and distribute this file in 6 // accordance with the terms of the Adobe license agreement accompanying it. 7 /*****************************************************************************/ 8 9 /** \file 10 * Classes supporting user cancellation and progress tracking. 11 */ 12 13 /*****************************************************************************/ 14 15 #ifndef __dng_abort_sniffer__ 16 #define __dng_abort_sniffer__ 17 18 /*****************************************************************************/ 19 20 #include "dng_classes.h" 21 #include "dng_flags.h" 22 #include "dng_string.h" 23 #include "dng_types.h" 24 #include "dng_uncopyable.h" 25 26 /*****************************************************************************/ 27 28 /// \brief Thread priority level. 29 30 enum dng_priority 31 { 32 33 dng_priority_low, 34 dng_priority_medium, 35 dng_priority_high, 36 37 dng_priority_count, 38 39 dng_priority_minimum = dng_priority_low, 40 dng_priority_maximum = dng_priority_high 41 42 }; 43 44 /*****************************************************************************/ 45 46 /// \brief Convenience class for setting thread priority level to minimum. 47 48 class dng_set_minimum_priority 49 { 50 51 private: 52 53 dng_priority fPriority; 54 55 dng_string fName; 56 57 public: 58 59 dng_set_minimum_priority (dng_priority priority, 60 const char *name); 61 62 ~dng_set_minimum_priority (); 63 64 }; 65 66 /*****************************************************************************/ 67 68 /** \brief Class for signaling user cancellation and receiving progress updates. 69 * 70 * DNG SDK clients should derive a host application specific implementation 71 * from this class. 72 */ 73 74 class dng_abort_sniffer 75 { 76 77 friend class dng_sniffer_task; 78 79 private: 80 81 dng_priority fPriority; 82 83 public: 84 85 dng_abort_sniffer (); 86 87 virtual ~dng_abort_sniffer (); 88 89 /// Getter for priority level. 90 Priority()91 dng_priority Priority () const 92 { 93 return fPriority; 94 } 95 96 /// Setter for priority level. 97 98 void SetPriority (dng_priority priority); 99 100 /// Check for pending user cancellation or other abort. ThrowUserCanceled 101 /// will be called if one is pending. This static method is provided as a 102 /// convenience for quickly testing for an abort and throwing an exception 103 /// if one is pending. 104 /// \param sniffer The dng_sniffer to test for a pending abort. Can be NULL, 105 /// in which case there an abort is never signalled. 106 107 static void SniffForAbort (dng_abort_sniffer *sniffer); 108 109 // A way to call Sniff while bypassing the priority wait. 110 SniffNoPriorityWait()111 void SniffNoPriorityWait () 112 { 113 Sniff (); 114 } 115 116 // Specifies whether or not the sniffer may be called by multiple threads 117 // in parallel. Default result is false. Subclass must override to return 118 // true. 119 ThreadSafe()120 virtual bool ThreadSafe () const 121 { 122 return false; 123 } 124 125 // Specifies whether or not this sniffer may participate in 126 // priority-based waiting (sleep the current thread on which 127 // SniffForAbort is called, if another thread has higher priority). 128 // Default result is false. Subclass must override to return true. 129 130 virtual bool SupportsPriorityWait () const; 131 132 protected: 133 134 /// Should be implemented by derived classes to check for an user 135 /// cancellation. 136 137 virtual void Sniff () = 0; 138 139 /// Signals the start of a named task withn processing in the DNG SDK. 140 /// Tasks may be nested. 141 /// \param name of the task 142 /// \param fract Percentage of total processing this task is expected to 143 /// take. From 0.0 to 1.0 . 144 145 virtual void StartTask (const char *name, 146 real64 fract); 147 148 /// Signals the end of the innermost task that has been started. 149 150 virtual void EndTask (); 151 152 /// Signals progress made on current task. 153 /// \param fract percentage of processing completed on current task. 154 /// From 0.0 to 1.0 . 155 156 virtual void UpdateProgress (real64 fract); 157 158 }; 159 160 /******************************************************************************/ 161 162 /// \brief Class to establish scope of a named subtask in DNG processing. 163 /// 164 /// Instances of this class are intended to be stack allocated. 165 166 class dng_sniffer_task: private dng_uncopyable 167 { 168 169 private: 170 171 dng_abort_sniffer *fSniffer; 172 173 public: 174 175 /// Inform a sniffer of a subtask in DNG processing. 176 /// \param sniffer The sniffer associated with the host on which this 177 /// processing is occurring. 178 /// \param name The name of this subtask as a NUL terminated string. 179 /// \param fract Percentage of total processing this task is expected 180 /// to take, from 0.0 to 1.0 . 181 182 dng_sniffer_task (dng_abort_sniffer *sniffer, 183 const char *name = NULL, 184 real64 fract = 0.0) 185 fSniffer(sniffer)186 : fSniffer (sniffer) 187 188 { 189 if (fSniffer) 190 fSniffer->StartTask (name, fract); 191 } 192 ~dng_sniffer_task()193 ~dng_sniffer_task () 194 { 195 if (fSniffer) 196 fSniffer->EndTask (); 197 } 198 199 /// Check for pending user cancellation or other abort. ThrowUserCanceled 200 /// will be called if one is pending. 201 Sniff()202 void Sniff () 203 { 204 dng_abort_sniffer::SniffForAbort (fSniffer); 205 } 206 207 /// Update progress on this subtask. 208 /// \param fract Percentage of processing completed on current task, 209 /// from 0.0 to 1.0 . 210 UpdateProgress(real64 fract)211 void UpdateProgress (real64 fract) 212 { 213 if (fSniffer) 214 fSniffer->UpdateProgress (fract); 215 } 216 217 /// Update progress on this subtask. 218 /// \param done Amount of task completed in arbitrary integer units. 219 /// \param total Total size of task in same arbitrary integer units as done. 220 UpdateProgress(uint32 done,uint32 total)221 void UpdateProgress (uint32 done, 222 uint32 total) 223 { 224 UpdateProgress ((real64) done / 225 (real64) total); 226 } 227 228 /// Signal task completed for progress purposes. 229 Finish()230 void Finish () 231 { 232 UpdateProgress (1.0); 233 } 234 235 }; 236 237 /*****************************************************************************/ 238 239 #endif 240 241 /*****************************************************************************/ 242