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 }