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