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 timeoutID = 0; 234 timeoutListeners.length = 0; 235 } 236 237 /** 238 * Removes the timeout from gtk 239 */ 240 ~this() 241 { 242 stop(); 243 } 244 245 /** 246 * Adds a new delegate to this timeout cycle 247 * Params: 248 * dlg = 249 * fireNow = 250 */ 251 public void addListener(bool delegate() dlg, bool fireNow=false) 252 { 253 timeoutListeners ~= dlg; 254 if ( fireNow ) 255 { 256 if ( !dlg() ) 257 { 258 timeoutListeners.length = timeoutListeners.length - 1; 259 } 260 } 261 } 262 263 /** 264 * The callback execution from glib 265 * Params: 266 * timeout = 267 * Returns: 268 */ 269 extern(C) static bool timeoutCallback(Timeout timeout) 270 { 271 return timeout.callAllListeners(); 272 } 273 274 /** 275 * Executes all delegates on the execution list 276 * Returns: 277 */ 278 private bool callAllListeners() 279 { 280 bool runAgain = false; 281 282 int i = 0; 283 284 while ( i<timeoutListeners.length ) 285 { 286 if ( !timeoutListeners[i]() ) 287 { 288 timeoutListeners = timeoutListeners[0..i] ~ timeoutListeners[i+1..timeoutListeners.length]; 289 } 290 else 291 { 292 runAgain = true; 293 ++i; 294 } 295 } 296 return runAgain; 297 } 298 299 /** 300 */ 301 302 /** 303 * Creates a new timeout source. 304 * The source will not initially be associated with any GMainContext 305 * and must be added to one with g_source_attach() before it will be 306 * executed. 307 * Params: 308 * interval = the timeout interval in milliseconds. 309 * Returns: the newly-created timeout source 310 */ 311 public static Source sourceNew(uint interval) 312 { 313 // GSource * g_timeout_source_new (guint interval); 314 auto p = g_timeout_source_new(interval); 315 316 if(p is null) 317 { 318 return null; 319 } 320 321 return new Source(cast(GSource*) p); 322 } 323 324 /** 325 * Creates a new timeout source. 326 * The source will not initially be associated with any GMainContext 327 * and must be added to one with g_source_attach() before it will be 328 * executed. 329 * The scheduling granularity/accuracy of this timeout source will be 330 * in seconds. 331 * Since 2.14 332 * Params: 333 * interval = the timeout interval in seconds 334 * Returns: the newly-created timeout source 335 */ 336 public static Source sourceNewSeconds(uint interval) 337 { 338 // GSource * g_timeout_source_new_seconds (guint interval); 339 auto p = g_timeout_source_new_seconds(interval); 340 341 if(p is null) 342 { 343 return null; 344 } 345 346 return new Source(cast(GSource*) p); 347 } 348 349 /** 350 * Sets a function to be called at regular intervals, with the default 351 * priority, G_PRIORITY_DEFAULT. The function is called repeatedly 352 * until it returns FALSE, at which point the timeout is automatically 353 * destroyed and the function will not be called again. The first call 354 * to the function will be at the end of the first interval. 355 * Note that timeout functions may be delayed, due to the processing of other 356 * event sources. Thus they should not be relied on for precise timing. 357 * After each call to the timeout function, the time of the next 358 * timeout is recalculated based on the current time and the given interval 359 * (it does not try to 'catch up' time lost in delays). 360 * If you want to have a timer in the "seconds" range and do not care 361 * about the exact time of the first call of the timer, use the 362 * g_timeout_add_seconds() function; this function allows for more 363 * optimizations and more efficient system power usage. 364 * This internally creates a main loop source using g_timeout_source_new() 365 * and attaches it to the main loop context using g_source_attach(). You can 366 * do these steps manually if you need greater control. 367 * Params: 368 * interval = the time between calls to the function, in milliseconds 369 * (1/1000ths of a second) 370 * data = data to pass to function 371 * Returns: the ID (greater than 0) of the event source. 372 */ 373 public static uint add(uint interval, GSourceFunc funct, void* data) 374 { 375 // guint g_timeout_add (guint interval, GSourceFunc function, gpointer data); 376 return g_timeout_add(interval, funct, data); 377 } 378 379 /** 380 * Sets a function to be called at regular intervals, with the given 381 * priority. The function is called repeatedly until it returns 382 * FALSE, at which point the timeout is automatically destroyed and 383 * the function will not be called again. The notify function is 384 * called when the timeout is destroyed. The first call to the 385 * function will be at the end of the first interval. 386 * Note that timeout functions may be delayed, due to the processing of other 387 * event sources. Thus they should not be relied on for precise timing. 388 * After each call to the timeout function, the time of the next 389 * timeout is recalculated based on the current time and the given interval 390 * (it does not try to 'catch up' time lost in delays). 391 * This internally creates a main loop source using g_timeout_source_new() 392 * and attaches it to the main loop context using g_source_attach(). You can 393 * do these steps manually if you need greater control. 394 * Params: 395 * priority = the priority of the timeout source. Typically this will be in 396 * the range between G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. 397 * interval = the time between calls to the function, in milliseconds 398 * (1/1000ths of a second) 399 * data = data to pass to function 400 * notify = function to call when the timeout is removed, or NULL 401 * Returns: the ID (greater than 0) of the event source. 402 */ 403 public static uint addFull(int priority, uint interval, GSourceFunc funct, void* data, GDestroyNotify notify) 404 { 405 // guint g_timeout_add_full (gint priority, guint interval, GSourceFunc function, gpointer data, GDestroyNotify notify); 406 return g_timeout_add_full(priority, interval, funct, data, notify); 407 } 408 409 /** 410 * Sets a function to be called at regular intervals with the default 411 * priority, G_PRIORITY_DEFAULT. The function is called repeatedly until 412 * it returns FALSE, at which point the timeout is automatically destroyed 413 * and the function will not be called again. 414 * This internally creates a main loop source using 415 * g_timeout_source_new_seconds() and attaches it to the main loop context 416 * using g_source_attach(). You can do these steps manually if you need 417 * greater control. Also see g_timout_add_seconds_full(). 418 * Note that the first call of the timer may not be precise for timeouts 419 * of one second. If you need finer precision and have such a timeout, 420 * you may want to use g_timeout_add() instead. 421 * Since 2.14 422 * Params: 423 * interval = the time between calls to the function, in seconds 424 * data = data to pass to function 425 * Returns: the ID (greater than 0) of the event source. 426 */ 427 public static uint addSeconds(uint interval, GSourceFunc funct, void* data) 428 { 429 // guint g_timeout_add_seconds (guint interval, GSourceFunc function, gpointer data); 430 return g_timeout_add_seconds(interval, funct, data); 431 } 432 433 /** 434 * Sets a function to be called at regular intervals, with priority. 435 * The function is called repeatedly until it returns FALSE, at which 436 * point the timeout is automatically destroyed and the function will 437 * not be called again. 438 * Unlike g_timeout_add(), this function operates at whole second granularity. 439 * The initial starting point of the timer is determined by the implementation 440 * and the implementation is expected to group multiple timers together so that 441 * they fire all at the same time. 442 * To allow this grouping, the interval to the first timer is rounded 443 * and can deviate up to one second from the specified interval. 444 * Subsequent timer iterations will generally run at the specified interval. 445 * Note that timeout functions may be delayed, due to the processing of other 446 * event sources. Thus they should not be relied on for precise timing. 447 * After each call to the timeout function, the time of the next 448 * timeout is recalculated based on the current time and the given interval 449 * If you want timing more precise than whole seconds, use g_timeout_add() 450 * instead. 451 * The grouping of timers to fire at the same time results in a more power 452 * and CPU efficient behavior so if your timer is in multiples of seconds 453 * and you don't require the first timer exactly one second from now, the 454 * use of g_timeout_add_seconds() is preferred over g_timeout_add(). 455 * This internally creates a main loop source using 456 * g_timeout_source_new_seconds() and attaches it to the main loop context 457 * using g_source_attach(). You can do these steps manually if you need 458 * greater control. 459 * Since 2.14 460 * Params: 461 * priority = the priority of the timeout source. Typically this will be in 462 * the range between G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. 463 * interval = the time between calls to the function, in seconds 464 * data = data to pass to function 465 * notify = function to call when the timeout is removed, or NULL 466 * Returns: the ID (greater than 0) of the event source. 467 */ 468 public static uint addSecondsFull(int priority, uint interval, GSourceFunc funct, void* data, GDestroyNotify notify) 469 { 470 // guint g_timeout_add_seconds_full (gint priority, guint interval, GSourceFunc function, gpointer data, GDestroyNotify notify); 471 return g_timeout_add_seconds_full(priority, interval, funct, data, notify); 472 } 473 }