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