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  * Conversion parameters:
26  * inFile  = 
27  * outPack = glib
28  * outFile = Timeout
29  * strct   = 
30  * realStrct=
31  * ctorStrct=
32  * clss    = Timeout
33  * interf  = 
34  * class Code: Yes
35  * interface Code: No
36  * template for:
37  * extend  = 
38  * implements:
39  * prefixes:
40  * 	- g_timeout_
41  * omit structs:
42  * omit prefixes:
43  * omit code:
44  * omit signals:
45  * imports:
46  * 	- glib.Source
47  * structWrap:
48  * 	- GSource* -> Source
49  * module aliases:
50  * local aliases:
51  * overrides:
52  */
53 
54 module glib.Timeout;
55 
56 public  import gtkc.glibtypes;
57 
58 private import gtkc.glib;
59 private import glib.ConstructionException;
60 
61 
62 private import glib.Source;
63 
64 
65 
66 
67 /**
68  * Description
69  * The main event loop manages all the available sources of events for
70  * GLib and GTK+ applications. These events can come from any number of
71  * different types of sources such as file descriptors (plain files,
72  * pipes or sockets) and timeouts. New types of event sources can also
73  * be added using g_source_attach().
74  * To allow multiple independent sets of sources to be handled in
75  * different threads, each source is associated with a GMainContext.
76  * A GMainContext can only be running in a single thread, but
77  * sources can be added to it and removed from it from other threads.
78  * Each event source is assigned a priority. The default priority,
79  * G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher priorities.
80  * Values greater than 0 denote lower priorities. Events from high priority
81  * sources are always processed before events from lower priority sources.
82  * Idle functions can also be added, and assigned a priority. These will
83  * be run whenever no events with a higher priority are ready to be processed.
84  * The GMainLoop data type represents a main event loop. A GMainLoop is
85  * created with g_main_loop_new(). After adding the initial event sources,
86  * g_main_loop_run() is called. This continuously checks for new events from
87  * each of the event sources and dispatches them. Finally, the processing of
88  * an event from one of the sources leads to a call to g_main_loop_quit() to
89  * exit the main loop, and g_main_loop_run() returns.
90  * It is possible to create new instances of GMainLoop recursively.
91  * This is often used in GTK+ applications when showing modal dialog
92  * boxes. Note that event sources are associated with a particular
93  * GMainContext, and will be checked and dispatched for all main
94  * loops associated with that GMainContext.
95  * GTK+ contains wrappers of some of these functions, e.g. gtk_main(),
96  * gtk_main_quit() and gtk_events_pending().
97  * Creating new source types
98  * One of the unusual features of the GMainLoop functionality
99  * is that new types of event source can be created and used in
100  * addition to the builtin type of event source. A new event source
101  * type is used for handling GDK events. A new source type is created
102  * by deriving from the GSource structure.
103  * The derived type of source is represented by a structure that has
104  * the GSource structure as a first element, and other elements specific
105  * to the new source type. To create an instance of the new source type,
106  * call g_source_new() passing in the size of the derived structure and
107  * a table of functions. These GSourceFuncs determine the behavior of
108  * the new source type.
109  * New source types basically interact with the main context
110  * in two ways. Their prepare function in GSourceFuncs can set a timeout
111  * to determine the maximum amount of time that the main loop will sleep
112  * before checking the source again. In addition, or as well, the source
113  * can add file descriptors to the set that the main context checks using
114  * g_source_add_poll().
115  * <hr>
116  * Customizing the main loop iteration
117  * Single iterations of a GMainContext can be run with
118  * g_main_context_iteration(). In some cases, more detailed control
119  * of exactly how the details of the main loop work is desired, for
120  * instance, when integrating the GMainLoop with an external main loop.
121  * In such cases, you can call the component functions of
122  * g_main_context_iteration() directly. These functions are
123  * g_main_context_prepare(), g_main_context_query(),
124  * g_main_context_check() and g_main_context_dispatch().
125  * The operation of these functions can best be seen in terms
126  * of a state diagram, as shown in Figure 1, “States of a Main Context”.
127  * Figure 1. States of a Main Context
128  */
129 public class Timeout
130 {
131 	
132 	/** Holds all timeout delegates */
133 	bool delegate()[] timeoutListeners;
134 	/** our gtk timeout ID */
135 	uint timeoutID;
136 	
137 	
138 	/**
139 	 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT.
140 	 *
141 	 * Note that timeout functions may be delayed, due to the processing of other
142 	 * event sources. Thus they should not be relied on for precise timing.
143 	 * After each call to the timeout function, the time of the next timeout is
144 	 * recalculated based on the current time and the given interval
145 	 * (it does not try to 'catch up' time lost in delays).
146 	 * Params:
147 	 *    	interval = 	the timeout in milieconds
148 	 *    	delegate() = 	the delegate to be executed
149 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
150 	 */
151 	this(uint interval, bool delegate() dlg, bool fireNow=false)
152 	{
153 		timeoutListeners ~= dlg;
154 		timeoutID = g_timeout_add(interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this);
155 		if ( fireNow )
156 		{
157 			if ( !dlg() )
158 			{
159 				timeoutListeners.length = 0;
160 			}
161 		}
162 	}
163 	
164 	/**
165 	 * Creates a new timeout cycle.
166 	 * Params:
167 	 *    	interval = 	the timeout in milieconds
168 	 *    	delegate() = 	the delegate to be executed
169 	 *      priority = Priority for the timeout function
170 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
171 	 */
172 	this(uint interval, bool delegate() dlg, GPriority priority, bool fireNow=false)
173 	{
174 		timeoutListeners ~= dlg;
175 		timeoutID = g_timeout_add_full(priority, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, null);
176 		if ( fireNow )
177 		{
178 			if ( !dlg() )
179 			{
180 				timeoutListeners.length = 0;
181 			}
182 		}
183 	}
184 	
185 	/**
186 	 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT.
187 	 * Params:
188 	 *    	delegate() = 	the delegate to be executed
189 	 *      seconds = interval in seconds.
190 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
191 	 */
192 	this(bool delegate() dlg, uint seconds, bool fireNow=false)
193 	{
194 		timeoutListeners ~= dlg;
195 		timeoutID = g_timeout_add_seconds(seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this);
196 		if ( fireNow )
197 		{
198 			if ( !dlg() )
199 			{
200 				timeoutListeners.length = 0;
201 			}
202 		}
203 	}
204 	
205 	/**
206 	 * Creates a new timeout cycle.
207 	 * Params:
208 	 *    	delegate() = 	the delegate to be executed
209 	 *      seconds = interval in seconds.
210 	 *      priority = Priority for the timeout function
211 	 *    	fireNow = 	When true the delegate will be executed emmidiatly
212 	 */
213 	this(bool delegate() dlg, uint seconds, GPriority priority, bool fireNow=false)
214 	{
215 		timeoutListeners ~= dlg;
216 		timeoutID = g_timeout_add_seconds_full(priority, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, null);
217 		if ( fireNow )
218 		{
219 			if ( !dlg() )
220 			{
221 				timeoutListeners.length = 0;
222 			}
223 		}
224 	}
225 	
226 	/** */
227 	public void stop()
228 	{
229 		if ( timeoutID > 0 )
230 		{
231 			g_source_remove(timeoutID);
232 		}
233 		timeoutListeners.length = 0;
234 	}
235 	
236 	/**
237 	 * Removes the timeout from gtk
238 	 */
239 	~this()
240 	{
241 		stop();
242 	}
243 	
244 	/**
245 	 * Adds a new delegate to this timeout cycle
246 	 * Params:
247 	 *    	dlg =
248 	 *    	fireNow =
249 	 */
250 	public void addListener(bool delegate() dlg, bool fireNow=false)
251 	{
252 		timeoutListeners ~= dlg;
253 		if ( fireNow )
254 		{
255 			if ( !dlg() )
256 			{
257 				timeoutListeners.length = timeoutListeners.length - 1;
258 			}
259 		}
260 	}
261 	
262 	/**
263 	 * The callback execution from glib
264 	 * Params:
265 	 *    	timeout =
266 	 * Returns:
267 	 */
268 	extern(C) static bool timeoutCallback(Timeout timeout)
269 	{
270 		return timeout.callAllListeners();
271 	}
272 	
273 	/**
274 	 * Executes all delegates on the execution list
275 	 * Returns:
276 	 */
277 	private bool callAllListeners()
278 	{
279 		bool runAgain = false;
280 		
281 		int i = 0;
282 		
283 		while ( i<timeoutListeners.length )
284 		{
285 			if ( !timeoutListeners[i]() )
286 			{
287 				timeoutListeners = timeoutListeners[0..i] ~ timeoutListeners[i+1..timeoutListeners.length];
288 			}
289 			else
290 			{
291 				runAgain = true;
292 				++i;
293 			}
294 		}
295 		return runAgain;
296 	}
297 	
298 	/**
299 	 */
300 	
301 	/**
302 	 * Creates a new timeout source.
303 	 * The source will not initially be associated with any GMainContext
304 	 * and must be added to one with g_source_attach() before it will be
305 	 * executed.
306 	 * Params:
307 	 * interval = the timeout interval in milliseconds.
308 	 * Returns: the newly-created timeout source
309 	 */
310 	public static Source sourceNew(uint interval)
311 	{
312 		// GSource * g_timeout_source_new (guint interval);
313 		auto p = g_timeout_source_new(interval);
314 		
315 		if(p is null)
316 		{
317 			return null;
318 		}
319 		
320 		return new Source(cast(GSource*) p);
321 	}
322 	
323 	/**
324 	 * Creates a new timeout source.
325 	 * The source will not initially be associated with any GMainContext
326 	 * and must be added to one with g_source_attach() before it will be
327 	 * executed.
328 	 * The scheduling granularity/accuracy of this timeout source will be
329 	 * in seconds.
330 	 * Since 2.14
331 	 * Params:
332 	 * interval = the timeout interval in seconds
333 	 * Returns: the newly-created timeout source
334 	 */
335 	public static Source sourceNewSeconds(uint interval)
336 	{
337 		// GSource * g_timeout_source_new_seconds (guint interval);
338 		auto p = g_timeout_source_new_seconds(interval);
339 		
340 		if(p is null)
341 		{
342 			return null;
343 		}
344 		
345 		return new Source(cast(GSource*) p);
346 	}
347 	
348 	/**
349 	 * Sets a function to be called at regular intervals, with the default
350 	 * priority, G_PRIORITY_DEFAULT. The function is called repeatedly
351 	 * until it returns FALSE, at which point the timeout is automatically
352 	 * destroyed and the function will not be called again. The first call
353 	 * to the function will be at the end of the first interval.
354 	 * Note that timeout functions may be delayed, due to the processing of other
355 	 * event sources. Thus they should not be relied on for precise timing.
356 	 * After each call to the timeout function, the time of the next
357 	 * timeout is recalculated based on the current time and the given interval
358 	 * (it does not try to 'catch up' time lost in delays).
359 	 * If you want to have a timer in the "seconds" range and do not care
360 	 * about the exact time of the first call of the timer, use the
361 	 * g_timeout_add_seconds() function; this function allows for more
362 	 * optimizations and more efficient system power usage.
363 	 * This internally creates a main loop source using g_timeout_source_new()
364 	 * and attaches it to the main loop context using g_source_attach(). You can
365 	 * do these steps manually if you need greater control.
366 	 * Params:
367 	 * interval = the time between calls to the function, in milliseconds
368 	 * (1/1000ths of a second)
369 	 * data = data to pass to function
370 	 * Returns: the ID (greater than 0) of the event source.
371 	 */
372 	public static uint add(uint interval, GSourceFunc funct, void* data)
373 	{
374 		// guint g_timeout_add (guint interval,  GSourceFunc function,  gpointer data);
375 		return g_timeout_add(interval, funct, data);
376 	}
377 	
378 	/**
379 	 * Sets a function to be called at regular intervals, with the given
380 	 * priority. The function is called repeatedly until it returns
381 	 * FALSE, at which point the timeout is automatically destroyed and
382 	 * the function will not be called again. The notify function is
383 	 * called when the timeout is destroyed. The first call to the
384 	 * function will be at the end of the first interval.
385 	 * Note that timeout functions may be delayed, due to the processing of other
386 	 * event sources. Thus they should not be relied on for precise timing.
387 	 * After each call to the timeout function, the time of the next
388 	 * timeout is recalculated based on the current time and the given interval
389 	 * (it does not try to 'catch up' time lost in delays).
390 	 * This internally creates a main loop source using g_timeout_source_new()
391 	 * and attaches it to the main loop context using g_source_attach(). You can
392 	 * do these steps manually if you need greater control.
393 	 * Params:
394 	 * priority = the priority of the timeout source. Typically this will be in
395 	 * the range between G_PRIORITY_DEFAULT and G_PRIORITY_HIGH.
396 	 * interval = the time between calls to the function, in milliseconds
397 	 * (1/1000ths of a second)
398 	 * data = data to pass to function
399 	 * notify = function to call when the timeout is removed, or NULL
400 	 * Returns: the ID (greater than 0) of the event source.
401 	 */
402 	public static uint addFull(int priority, uint interval, GSourceFunc funct, void* data, GDestroyNotify notify)
403 	{
404 		// guint g_timeout_add_full (gint priority,  guint interval,  GSourceFunc function,  gpointer data,  GDestroyNotify notify);
405 		return g_timeout_add_full(priority, interval, funct, data, notify);
406 	}
407 	
408 	/**
409 	 * Sets a function to be called at regular intervals with the default
410 	 * priority, G_PRIORITY_DEFAULT. The function is called repeatedly until
411 	 * it returns FALSE, at which point the timeout is automatically destroyed
412 	 * and the function will not be called again.
413 	 * This internally creates a main loop source using
414 	 * g_timeout_source_new_seconds() and attaches it to the main loop context
415 	 * using g_source_attach(). You can do these steps manually if you need
416 	 * greater control. Also see g_timout_add_seconds_full().
417 	 * Note that the first call of the timer may not be precise for timeouts
418 	 * of one second. If you need finer precision and have such a timeout,
419 	 * you may want to use g_timeout_add() instead.
420 	 * Since 2.14
421 	 * Params:
422 	 * interval = the time between calls to the function, in seconds
423 	 * data = data to pass to function
424 	 * Returns: the ID (greater than 0) of the event source.
425 	 */
426 	public static uint addSeconds(uint interval, GSourceFunc funct, void* data)
427 	{
428 		// guint g_timeout_add_seconds (guint interval,  GSourceFunc function,  gpointer data);
429 		return g_timeout_add_seconds(interval, funct, data);
430 	}
431 	
432 	/**
433 	 * Sets a function to be called at regular intervals, with priority.
434 	 * The function is called repeatedly until it returns FALSE, at which
435 	 * point the timeout is automatically destroyed and the function will
436 	 * not be called again.
437 	 * Unlike g_timeout_add(), this function operates at whole second granularity.
438 	 * The initial starting point of the timer is determined by the implementation
439 	 * and the implementation is expected to group multiple timers together so that
440 	 * they fire all at the same time.
441 	 * To allow this grouping, the interval to the first timer is rounded
442 	 * and can deviate up to one second from the specified interval.
443 	 * Subsequent timer iterations will generally run at the specified interval.
444 	 * Note that timeout functions may be delayed, due to the processing of other
445 	 * event sources. Thus they should not be relied on for precise timing.
446 	 * After each call to the timeout function, the time of the next
447 	 * timeout is recalculated based on the current time and the given interval
448 	 * If you want timing more precise than whole seconds, use g_timeout_add()
449 	 * instead.
450 	 * The grouping of timers to fire at the same time results in a more power
451 	 * and CPU efficient behavior so if your timer is in multiples of seconds
452 	 * and you don't require the first timer exactly one second from now, the
453 	 * use of g_timeout_add_seconds() is preferred over g_timeout_add().
454 	 * This internally creates a main loop source using
455 	 * g_timeout_source_new_seconds() and attaches it to the main loop context
456 	 * using g_source_attach(). You can do these steps manually if you need
457 	 * greater control.
458 	 * Since 2.14
459 	 * Params:
460 	 * priority = the priority of the timeout source. Typically this will be in
461 	 * the range between G_PRIORITY_DEFAULT and G_PRIORITY_HIGH.
462 	 * interval = the time between calls to the function, in seconds
463 	 * data = data to pass to function
464 	 * notify = function to call when the timeout is removed, or NULL
465 	 * Returns: the ID (greater than 0) of the event source.
466 	 */
467 	public static uint addSecondsFull(int priority, uint interval, GSourceFunc funct, void* data, GDestroyNotify notify)
468 	{
469 		// guint g_timeout_add_seconds_full (gint priority,  guint interval,  GSourceFunc function,  gpointer data,  GDestroyNotify notify);
470 		return g_timeout_add_seconds_full(priority, interval, funct, data, notify);
471 	}
472 }