alternative to assert
[gtkD.git] / gtkD / src / glib / MainLoop.d
blobe94531413db891cda461d3cfd21ed29951f0ecd3
1 /*
2 * This file is part of gtkD.
4 * gtkD is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
9 * gtkD is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with gtkD; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // generated automatically - do not change
20 // find conversion definition on APILookup.txt
21 // implement new conversion functionalities on the wrap.utils pakage
24 * Conversion parameters:
25 * inFile = glib-The-Main-Event-Loop.html
26 * outPack = glib
27 * outFile = MainLoop
28 * strct = GMainLoop
29 * realStrct=
30 * ctorStrct=
31 * clss = MainLoop
32 * interf =
33 * class Code: Yes
34 * interface Code: No
35 * template for:
36 * extend =
37 * implements:
38 * prefixes:
39 * - g_main_loop_
40 * omit structs:
41 * omit prefixes:
42 * - g_main_context_
43 * - g_timeout_
44 * - g_child_
45 * - g_source_
46 * omit code:
47 * - g_main_loop_ref
48 * imports:
49 * - glib.Dataset
50 * - glib.MainContext
51 * - glib.Source
52 * structWrap:
53 * - GDataset* -> Dataset
54 * - GMainContext* -> MainContext
55 * - GSource* -> Source
56 * module aliases:
57 * local aliases:
60 module glib.MainLoop;
62 version(noAssert)
64 version(Tango)
66 import tango.io.Stdout; // use the tango loging?
70 private import gtkc.glibtypes;
72 private import gtkc.glib;
75 private import glib.Dataset;
76 private import glib.MainContext;
77 private import glib.Source;
82 /**
83 * Description
84 * The main event loop manages all the available sources of events for
85 * GLib and GTK+ applications. These events can come from any number of
86 * different types of sources such as file descriptors (plain files,
87 * pipes or sockets) and timeouts. New types of event sources can also
88 * be added using g_source_attach().
89 * To allow multiple independent sets of sources to be handled in
90 * different threads, each source is associated with a GMainContext.
91 * A GMainContext can only be running in a single thread, but
92 * sources can be added to it and removed from it from other threads.
93 * Each event source is assigned a priority. The default priority,
94 * G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher
95 * priorities. Values greater than 0 denote lower priorities. Events
96 * from high priority sources are always processed before events from
97 * lower priority sources.
98 * Idle functions can also be added, and assigned a priority. These will
99 * be run whenever no events with a higher priority are ready to be
100 * processed.
101 * The GMainLoop data type represents a main event loop. A GMainLoop
102 * is created with g_main_loop_new(). After adding the initial event sources,
103 * g_main_loop_run() is called. This continuously checks for new events from
104 * each of the event sources and dispatches them. Finally, the
105 * processing of an event from one of the sources leads to a call to
106 * g_main_loop_quit() to exit the main loop, and g_main_loop_run() returns.
107 * It is possible to create new instances of GMainLoop recursively.
108 * This is often used in GTK+ applications when showing modal dialog
109 * boxes. Note that event sources are associated with a particular
110 * GMainContext, and will be checked and dispatched for all main
111 * loops associated with that GMainContext.
112 * GTK+ contains wrappers of some of these functions, e.g. gtk_main(),
113 * gtk_main_quit() and gtk_events_pending().
114 * Creating new sources types
115 * One of the unusual features of the GTK+ main loop functionality
116 * is that new types of event source can be created and used in
117 * addition to the builtin type of event source. A new event source
118 * type is used for handling GDK events. A new source type is
119 * created by deriving from the GSource
120 * structure. The derived type of source is represented by a
121 * structure that has the GSource structure as a first element,
122 * and other elements specific to the new source type. To create
123 * an instance of the new source type, call g_source_new() passing
124 * in the size of the derived structure and a table of functions.
125 * These GSourceFuncs determine the behavior of the new source
126 * types.
127 * New source types basically interact with with the main context
128 * in two ways. Their prepare function in GSourceFuncs can set
129 * a timeout to determine the maximum amount of time that the
130 * main loop will sleep before checking the source again. In
131 * addition, or as well, the source can add file descriptors to
132 * the set that the main context checks using g_source_add_poll().
133 * <hr>
134 * Customizing the main loop iteration
135 * Single iterations of a GMainContext can be run with
136 * g_main_context_iteration(). In some cases, more detailed control
137 * of exactly how the details of the main loop work is desired,
138 * for instance, when integrating the GMainLoop with an external
139 * main loop. In such cases, you can call the component functions
140 * of g_main_context_iteration() directly. These functions
141 * are g_main_context_prepare(), g_main_context_query(),
142 * g_main_context_check() and g_main_context_dispatch().
143 * The operation of these functions can best be seen in terms
144 * of a state diagram, as shown in Figure1, States of a Main Context.
145 * Figure1.States of a Main Context
147 public class MainLoop
150 /** the main Gtk struct */
151 protected GMainLoop* gMainLoop;
154 public GMainLoop* getMainLoopStruct()
156 return gMainLoop;
160 /** the main Gtk struct as a void* */
161 protected void* getStruct()
163 return cast(void*)gMainLoop;
167 * Sets our main struct and passes it to the parent class
169 public this (GMainLoop* gMainLoop)
171 version(noAssert)
173 if ( gMainLoop is null )
175 int zero = 0;
176 version(Tango)
178 Stdout("struct gMainLoop is null on constructor").newline;
180 else
182 printf("struct gMainLoop is null on constructor");
184 zero = zero / zero;
187 else
189 assert(gMainLoop !is null, "struct gMainLoop is null on constructor");
191 this.gMainLoop = gMainLoop;
195 * Increases the reference count on a GMainLoop object by one.
196 * loop:
197 * a GMainLoop
198 * Returns:
199 * loop
201 public MainLoop doref()
203 // GMainLoop* g_main_loop_ref (GMainLoop *loop);
204 return new MainLoop( g_main_loop_ref(gMainLoop) );
212 * Creates a new GMainLoop structure.
213 * context:
214 * a GMainContext (if NULL, the default context will be used).
215 * is_running:
216 * set to TRUE to indicate that the loop is running. This
217 * is not very important since calling g_main_loop_run() will set this to
218 * TRUE anyway.
219 * Returns:
220 * a new GMainLoop.
222 public this (MainContext context, int isRunning)
224 // GMainLoop* g_main_loop_new (GMainContext *context, gboolean is_running);
225 this(cast(GMainLoop*)g_main_loop_new((context is null) ? null : context.getMainContextStruct(), isRunning) );
230 * Decreases the reference count on a GMainLoop object by one. If
231 * the result is zero, free the loop and free all associated memory.
232 * loop:
233 * a GMainLoop
235 public void unref()
237 // void g_main_loop_unref (GMainLoop *loop);
238 g_main_loop_unref(gMainLoop);
242 * Runs a main loop until g_main_loop_quit() is called on the loop.
243 * If this is called for the thread of the loop's GMainContext,
244 * it will process events from the loop, otherwise it will
245 * simply wait.
246 * loop:
247 * a GMainLoop
249 public void run()
251 // void g_main_loop_run (GMainLoop *loop);
252 g_main_loop_run(gMainLoop);
256 * Stops a GMainLoop from running. Any calls to g_main_loop_run()
257 * for the loop will return.
258 * loop:
259 * a GMainLoop
261 public void quit()
263 // void g_main_loop_quit (GMainLoop *loop);
264 g_main_loop_quit(gMainLoop);
268 * Checks to see if the main loop is currently being run via g_main_loop_run().
269 * loop:
270 * a GMainLoop.
271 * Returns:
272 * TRUE if the mainloop is currently being run.
274 public int isRunning()
276 // gboolean g_main_loop_is_running (GMainLoop *loop);
277 return g_main_loop_is_running(gMainLoop);
281 * Returns the GMainContext of loop.
282 * loop:
283 * a GMainLoop.
284 * Returns:
285 * the GMainContext of loop
287 public MainContext getContext()
289 // GMainContext* g_main_loop_get_context (GMainLoop *loop);
290 return new MainContext( g_main_loop_get_context(gMainLoop) );
330 * Return value: The main loop recursion level in the current thread
331 * Returns:
332 * the depth of the stack of calls to
333 * g_main_context_dispatch() on any GMainContext in the current thread.
334 * That is, when called from the toplevel, it gives 0. When
335 * called from within a callback from g_main_context_iteration()
336 * (or g_main_loop_run(), etc.) it returns 1. When called from within
337 * a callback to a recursive call to g_main_context_iterate(),
338 * it returns 2. And so forth.
339 * This function is useful in a situation like the following:
340 * Imagine an extremely simple "garbage collected" system.
341 * Example1.
342 * static GList *free_list;
343 * gpointer
344 * allocate_memory (gsize size)
346 * gpointer result = g_malloc (size);
347 * free_list = g_list_prepend (free_list, result);
348 * return result;
350 * void
351 * free_allocated_memory (void)
353 * GList *l;
354 * for (l = free_list; l; l = l->next);
355 * g_free (l->data);
356 * g_list_free (free_list);
357 * free_list = NULL;
359 * [...]
360 * while (TRUE);
362 * g_main_context_iteration (NULL, TRUE);
363 * free_allocated_memory();
365 * This works from an application, however, if you want to do the same
366 * thing from a library, it gets more difficult, since you no longer
367 * control the main loop. You might think you can simply use an idle
368 * function to make the call to free_allocated_memory(), but that
369 * doesn't work, since the idle function could be called from a
370 * recursive callback. This can be fixed by using g_main_depth()
371 * Example2.
372 * gpointer
373 * allocate_memory (gsize size)
375 * FreeListBlock *block = g_new (FreeListBlock, 1);\
376 * block->mem = g_malloc (size);
377 * block->depth = g_main_depth();
378 * free_list = g_list_prepend (free_list, block);
379 * return block->mem;
381 * void
382 * free_allocated_memory (void)
384 * GList *l;
385 * int depth = g_main_depth();
386 * for (l = free_list; l; );
388 * GList *next = l->next;
389 * FreeListBlock *block = l->data;
390 * if (block->depth > depth)
392 * g_free (block->mem);
393 * g_free (block);
394 * free_list = g_list_delete_link (free_list, l);
396 * l = next;
399 * There is a temptation to use g_main_depth() to solve
400 * problems with reentrancy. For instance, while waiting for data
401 * to be received from the network in response to a menu item,
402 * the menu item might be selected again. It might seem that
403 * one could make the menu item's callback return immediately
404 * and do nothing if g_main_depth() returns a value greater than 1.
405 * However, this should be avoided since the user then sees selecting
406 * the menu item do nothing. Furthermore, you'll find yourself adding
407 * these checks all over your code, since there are doubtless many,
408 * many things that the user could do. Instead, you can use the
409 * following techniques:
410 * Use gtk_widget_set_sensitive() or modal dialogs to prevent
411 * the user from interacting with elements while the main
412 * loop is recursing.
413 * Avoid main loop recursion in situations where you can't handle
414 * arbitrary callbacks. Instead, structure your code so that you
415 * simply return to the main loop and then get called again when
416 * there is more work to do.
418 public static int gMainDepth()
420 // gint g_main_depth (void);
421 return g_main_depth();
425 * Returns the currently firing source for this thread.
426 * Returns:
427 * The currently firing source or NULL.
428 * Since 2.12
430 public static Source gMainCurrentSource()
432 // GSource* g_main_current_source (void);
433 return new Source( g_main_current_source() );
443 * Creates a new idle source.
444 * The source will not initially be associated with any GMainContext
445 * and must be added to one with g_source_attach() before it will be
446 * executed. Note that the default priority for idle sources is
447 * G_PRIORITY_DEFAULT_IDLE, as compared to other sources which
448 * have a default priority of G_PRIORITY_DEFAULT.
449 * Returns:
450 * the newly-created idle source
452 public static Source gIdleSourceNew()
454 // GSource* g_idle_source_new (void);
455 return new Source( g_idle_source_new() );
459 * Adds a function to be called whenever there are no higher priority
460 * events pending to the default main loop. The function is given the
461 * default idle priority, G_PRIORITY_DEFAULT_IDLE. If the function
462 * returns FALSE it is automatically removed from the list of event
463 * sources and will not be called again.
464 * function:
465 * function to call
466 * data:
467 * data to pass to function.
468 * Returns:
469 * the ID (greater than 0) of the event source.
471 public static uint gIdleAdd(GSourceFunc funct, void* data)
473 // guint g_idle_add (GSourceFunc function, gpointer data);
474 return g_idle_add(funct, data);
478 * Adds a function to be called whenever there are no higher priority
479 * events pending. If the function returns FALSE it is automatically
480 * removed from the list of event sources and will not be called again.
481 * priority:
482 * the priority of the idle source. Typically this will be in the
483 * range btweeen G_PRIORITY_DEFAULT_IDLE and G_PRIORITY_HIGH_IDLE.
484 * function:
485 * function to call
486 * data:
487 * data to pass to function
488 * notify:
489 * function to call when the idle is removed, or NULL
490 * Returns:
491 * the ID (greater than 0) of the event source.
493 public static uint gIdleAddFull(int priority, GSourceFunc funct, void* data, GDestroyNotify notify)
495 // guint g_idle_add_full (gint priority, GSourceFunc function, gpointer data, GDestroyNotify notify);
496 return g_idle_add_full(priority, funct, data, notify);
500 * Removes the idle function with the given data.
501 * data:
502 * the data for the idle source's callback.
503 * Returns:
504 * TRUE if an idle source was found and removed.
506 public static int gIdleRemoveByData(void* data)
508 // gboolean g_idle_remove_by_data (gpointer data);
509 return g_idle_remove_by_data(data);