1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module glib.Timeout;
26 
27 private import glib.Source;
28 private import gtkc.glib;
29 public  import gtkc.glibtypes;
30 
31 
32 /** */
33 public class Timeout
34 {
35 	/** Holds all timeout delegates */
36 	bool delegate()[] timeoutListeners;
37 	/** our gtk timeout ID */
38 	uint timeoutID;
39 	
40 	
41 	/**
42 	 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT.
43 	 *
44 	 * Note that timeout functions may be delayed, due to the processing of other
45 	 * event sources. Thus they should not be relied on for precise timing.
46 	 * After each call to the timeout function, the time of the next timeout is
47 	 * recalculated based on the current time and the given interval
48 	 * (it does not try to 'catch up' time lost in delays).
49 	 * Params:
50 	 *    	interval = 	the timeout in milieconds
51 	 *    	delegate() = 	the delegate to be executed
52 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
53 	 */
54 	this(uint interval, bool delegate() dlg, bool fireNow=false)
55 	{
56 		timeoutListeners ~= dlg;
57 		timeoutID = g_timeout_add(interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this);
58 		if ( fireNow )
59 		{
60 			if ( !dlg() )
61 			{
62 				timeoutListeners.length = 0;
63 			}
64 		}
65 	}
66 	
67 	/**
68 	 * Creates a new timeout cycle.
69 	 * Params:
70 	 *    	interval = 	the timeout in milieconds
71 	 *    	delegate() = 	the delegate to be executed
72 	 *      priority = Priority for the timeout function
73 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
74 	 */
75 	this(uint interval, bool delegate() dlg, GPriority priority, bool fireNow=false)
76 	{
77 		timeoutListeners ~= dlg;
78 		timeoutID = g_timeout_add_full(priority, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, null);
79 		if ( fireNow )
80 		{
81 			if ( !dlg() )
82 			{
83 				timeoutListeners.length = 0;
84 			}
85 		}
86 	}
87 	
88 	/**
89 	 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT.
90 	 * Params:
91 	 *    	delegate() = 	the delegate to be executed
92 	 *      seconds = interval in seconds.
93 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
94 	 */
95 	this(bool delegate() dlg, uint seconds, bool fireNow=false)
96 	{
97 		timeoutListeners ~= dlg;
98 		timeoutID = g_timeout_add_seconds(seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this);
99 		if ( fireNow )
100 		{
101 			if ( !dlg() )
102 			{
103 				timeoutListeners.length = 0;
104 			}
105 		}
106 	}
107 	
108 	/**
109 	 * Creates a new timeout cycle.
110 	 * Params:
111 	 *    	delegate() = 	the delegate to be executed
112 	 *      seconds = interval in seconds.
113 	 *      priority = Priority for the timeout function
114 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
115 	 */
116 	this(bool delegate() dlg, uint seconds, GPriority priority, bool fireNow=false)
117 	{
118 		timeoutListeners ~= dlg;
119 		timeoutID = g_timeout_add_seconds_full(priority, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, null);
120 		if ( fireNow )
121 		{
122 			if ( !dlg() )
123 			{
124 				timeoutListeners.length = 0;
125 			}
126 		}
127 	}
128 	
129 	/** */
130 	public void stop()
131 	{
132 		if ( timeoutID > 0 )
133 		{
134 			g_source_remove(timeoutID);
135 		}
136 		timeoutID = 0;
137 		timeoutListeners.length = 0;
138 	}
139 	
140 	/**
141 	 * Removes the timeout from gtk
142 	 */
143 	~this()
144 	{
145 		stop();
146 	}
147 	
148 	/**
149 	 * Adds a new delegate to this timeout cycle
150 	 * Params:
151 	 *    	dlg =
152 	 *    	fireNow =
153 	 */
154 	public void addListener(bool delegate() dlg, bool fireNow=false)
155 	{
156 		timeoutListeners ~= dlg;
157 		if ( fireNow )
158 		{
159 			if ( !dlg() )
160 			{
161 				timeoutListeners.length = timeoutListeners.length - 1;
162 			}
163 		}
164 	}
165 	
166 	/**
167 	 * The callback execution from glib
168 	 * Params:
169 	 *    	timeout =
170 	 * Returns:
171 	 */
172 	extern(C) static bool timeoutCallback(Timeout timeout)
173 	{
174 		return timeout.callAllListeners();
175 	}
176 	
177 	/**
178 	 * Executes all delegates on the execution list
179 	 * Returns:
180 	 */
181 	private bool callAllListeners()
182 	{
183 		bool runAgain = false;
184 		
185 		int i = 0;
186 		
187 		while ( i<timeoutListeners.length )
188 		{
189 			if ( !timeoutListeners[i]() )
190 			{
191 				timeoutListeners = timeoutListeners[0..i] ~ timeoutListeners[i+1..timeoutListeners.length];
192 			}
193 			else
194 			{
195 				runAgain = true;
196 				++i;
197 			}
198 		}
199 		
200 		// Set timeoutID to 0 if all delegates are removed
201 		if (timeoutListeners.length == 0)
202 			timeoutID = 0;
203 		
204 		return runAgain;
205 	}
206 
207 	/**
208 	 */
209 
210 	/**
211 	 * Sets a function to be called at regular intervals, with the default
212 	 * priority, #G_PRIORITY_DEFAULT.  The function is called repeatedly
213 	 * until it returns %FALSE, at which point the timeout is automatically
214 	 * destroyed and the function will not be called again.  The first call
215 	 * to the function will be at the end of the first @interval.
216 	 *
217 	 * Note that timeout functions may be delayed, due to the processing of other
218 	 * event sources. Thus they should not be relied on for precise timing.
219 	 * After each call to the timeout function, the time of the next
220 	 * timeout is recalculated based on the current time and the given interval
221 	 * (it does not try to 'catch up' time lost in delays).
222 	 *
223 	 * See [memory management of sources][mainloop-memory-management] for details
224 	 * on how to handle the return value and memory management of @data.
225 	 *
226 	 * If you want to have a timer in the "seconds" range and do not care
227 	 * about the exact time of the first call of the timer, use the
228 	 * g_timeout_add_seconds() function; this function allows for more
229 	 * optimizations and more efficient system power usage.
230 	 *
231 	 * This internally creates a main loop source using g_timeout_source_new()
232 	 * and attaches it to the global #GMainContext using g_source_attach(), so
233 	 * the callback will be invoked in whichever thread is running that main
234 	 * context. You can do these steps manually if you need greater control or to
235 	 * use a custom main context.
236 	 *
237 	 * The interval given is in terms of monotonic time, not wall clock
238 	 * time.  See g_get_monotonic_time().
239 	 *
240 	 * Params:
241 	 *     interval = the time between calls to the function, in milliseconds
242 	 *         (1/1000ths of a second)
243 	 *     funct = function to call
244 	 *     data = data to pass to @function
245 	 *
246 	 * Return: the ID (greater than 0) of the event source.
247 	 */
248 	public static uint add(uint interval, GSourceFunc funct, void* data)
249 	{
250 		return g_timeout_add(interval, funct, data);
251 	}
252 
253 	/**
254 	 * Sets a function to be called at regular intervals, with the given
255 	 * priority.  The function is called repeatedly until it returns
256 	 * %FALSE, at which point the timeout is automatically destroyed and
257 	 * the function will not be called again.  The @notify function is
258 	 * called when the timeout is destroyed.  The first call to the
259 	 * function will be at the end of the first @interval.
260 	 *
261 	 * Note that timeout functions may be delayed, due to the processing of other
262 	 * event sources. Thus they should not be relied on for precise timing.
263 	 * After each call to the timeout function, the time of the next
264 	 * timeout is recalculated based on the current time and the given interval
265 	 * (it does not try to 'catch up' time lost in delays).
266 	 *
267 	 * See [memory management of sources][mainloop-memory-management] for details
268 	 * on how to handle the return value and memory management of @data.
269 	 *
270 	 * This internally creates a main loop source using g_timeout_source_new()
271 	 * and attaches it to the global #GMainContext using g_source_attach(), so
272 	 * the callback will be invoked in whichever thread is running that main
273 	 * context. You can do these steps manually if you need greater control or to
274 	 * use a custom main context.
275 	 *
276 	 * The interval given in terms of monotonic time, not wall clock time.
277 	 * See g_get_monotonic_time().
278 	 *
279 	 * Params:
280 	 *     priority = the priority of the timeout source. Typically this will be in
281 	 *         the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
282 	 *     interval = the time between calls to the function, in milliseconds
283 	 *         (1/1000ths of a second)
284 	 *     funct = function to call
285 	 *     data = data to pass to @function
286 	 *     notify = function to call when the timeout is removed, or %NULL
287 	 *
288 	 * Return: the ID (greater than 0) of the event source.
289 	 */
290 	public static uint addFull(int priority, uint interval, GSourceFunc funct, void* data, GDestroyNotify notify)
291 	{
292 		return g_timeout_add_full(priority, interval, funct, data, notify);
293 	}
294 
295 	/**
296 	 * Sets a function to be called at regular intervals with the default
297 	 * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly until
298 	 * it returns %FALSE, at which point the timeout is automatically destroyed
299 	 * and the function will not be called again.
300 	 *
301 	 * This internally creates a main loop source using
302 	 * g_timeout_source_new_seconds() and attaches it to the main loop context
303 	 * using g_source_attach(). You can do these steps manually if you need
304 	 * greater control. Also see g_timeout_add_seconds_full().
305 	 *
306 	 * Note that the first call of the timer may not be precise for timeouts
307 	 * of one second. If you need finer precision and have such a timeout,
308 	 * you may want to use g_timeout_add() instead.
309 	 *
310 	 * See [memory management of sources][mainloop-memory-management] for details
311 	 * on how to handle the return value and memory management of @data.
312 	 *
313 	 * The interval given is in terms of monotonic time, not wall clock
314 	 * time.  See g_get_monotonic_time().
315 	 *
316 	 * Params:
317 	 *     interval = the time between calls to the function, in seconds
318 	 *     funct = function to call
319 	 *     data = data to pass to @function
320 	 *
321 	 * Return: the ID (greater than 0) of the event source.
322 	 *
323 	 * Since: 2.14
324 	 */
325 	public static uint addSeconds(uint interval, GSourceFunc funct, void* data)
326 	{
327 		return g_timeout_add_seconds(interval, funct, data);
328 	}
329 
330 	/**
331 	 * Sets a function to be called at regular intervals, with @priority.
332 	 * The function is called repeatedly until it returns %FALSE, at which
333 	 * point the timeout is automatically destroyed and the function will
334 	 * not be called again.
335 	 *
336 	 * Unlike g_timeout_add(), this function operates at whole second granularity.
337 	 * The initial starting point of the timer is determined by the implementation
338 	 * and the implementation is expected to group multiple timers together so that
339 	 * they fire all at the same time.
340 	 * To allow this grouping, the @interval to the first timer is rounded
341 	 * and can deviate up to one second from the specified interval.
342 	 * Subsequent timer iterations will generally run at the specified interval.
343 	 *
344 	 * Note that timeout functions may be delayed, due to the processing of other
345 	 * event sources. Thus they should not be relied on for precise timing.
346 	 * After each call to the timeout function, the time of the next
347 	 * timeout is recalculated based on the current time and the given @interval
348 	 *
349 	 * See [memory management of sources][mainloop-memory-management] for details
350 	 * on how to handle the return value and memory management of @data.
351 	 *
352 	 * If you want timing more precise than whole seconds, use g_timeout_add()
353 	 * instead.
354 	 *
355 	 * The grouping of timers to fire at the same time results in a more power
356 	 * and CPU efficient behavior so if your timer is in multiples of seconds
357 	 * and you don't require the first timer exactly one second from now, the
358 	 * use of g_timeout_add_seconds() is preferred over g_timeout_add().
359 	 *
360 	 * This internally creates a main loop source using
361 	 * g_timeout_source_new_seconds() and attaches it to the main loop context
362 	 * using g_source_attach(). You can do these steps manually if you need
363 	 * greater control.
364 	 *
365 	 * The interval given is in terms of monotonic time, not wall clock
366 	 * time.  See g_get_monotonic_time().
367 	 *
368 	 * Params:
369 	 *     priority = the priority of the timeout source. Typically this will be in
370 	 *         the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
371 	 *     interval = the time between calls to the function, in seconds
372 	 *     funct = function to call
373 	 *     data = data to pass to @function
374 	 *     notify = function to call when the timeout is removed, or %NULL
375 	 *
376 	 * Return: the ID (greater than 0) of the event source.
377 	 *
378 	 * Since: 2.14
379 	 */
380 	public static uint addSecondsFull(int priority, uint interval, GSourceFunc funct, void* data, GDestroyNotify notify)
381 	{
382 		return g_timeout_add_seconds_full(priority, interval, funct, data, notify);
383 	}
384 
385 	/**
386 	 * Creates a new timeout source.
387 	 *
388 	 * The source will not initially be associated with any #GMainContext
389 	 * and must be added to one with g_source_attach() before it will be
390 	 * executed.
391 	 *
392 	 * The interval given is in terms of monotonic time, not wall clock
393 	 * time.  See g_get_monotonic_time().
394 	 *
395 	 * Params:
396 	 *     interval = the timeout interval in milliseconds.
397 	 *
398 	 * Return: the newly-created timeout source
399 	 */
400 	public static Source sourceNew(uint interval)
401 	{
402 		auto p = g_timeout_source_new(interval);
403 		
404 		if(p is null)
405 		{
406 			return null;
407 		}
408 		
409 		return new Source(cast(GSource*) p, true);
410 	}
411 
412 	/**
413 	 * Creates a new timeout source.
414 	 *
415 	 * The source will not initially be associated with any #GMainContext
416 	 * and must be added to one with g_source_attach() before it will be
417 	 * executed.
418 	 *
419 	 * The scheduling granularity/accuracy of this timeout source will be
420 	 * in seconds.
421 	 *
422 	 * The interval given in terms of monotonic time, not wall clock time.
423 	 * See g_get_monotonic_time().
424 	 *
425 	 * Params:
426 	 *     interval = the timeout interval in seconds
427 	 *
428 	 * Return: the newly-created timeout source
429 	 *
430 	 * Since: 2.14
431 	 */
432 	public static Source sourceNewSeconds(uint interval)
433 	{
434 		auto p = g_timeout_source_new_seconds(interval);
435 		
436 		if(p is null)
437 		{
438 			return null;
439 		}
440 		
441 		return new Source(cast(GSource*) p, true);
442 	}
443 }