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