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 private import std.conv; 32 33 34 /** */ 35 public class Timeout 36 { 37 /** Holds all idle delegates */ 38 private bool delegate()[] timeoutListeners; 39 /** Our timeout ID */ 40 private uint timeoutID; 41 42 43 /** 44 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. 45 * 46 * Note that timeout functions may be delayed, due to the processing of other 47 * event sources. Thus they should not be relied on for precise timing. 48 * After each call to the timeout function, the time of the next timeout is 49 * recalculated based on the current time and the given interval 50 * (it does not try to 'catch up' time lost in delays). 51 * Params: 52 * interval = the timeout in milieconds 53 * delegate() = the delegate to be executed 54 * fireNow = When true the delegate will be executed emmidiatly 55 */ 56 this(uint interval, bool delegate() dlg, bool fireNow=false) 57 { 58 if ( fireNow && !dlg() ) 59 return; 60 61 timeoutListeners ~= dlg; 62 timeoutID = g_timeout_add_full(GPriority.DEFAULT, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 63 } 64 65 this(Duration interval, bool delegate() dlg, bool fireNow=false) 66 { 67 this(interval.total!"msecs".to!uint, dlg, fireNow); 68 } 69 70 /** 71 * Creates a new timeout cycle. 72 * Params: 73 * interval = the timeout in milieconds 74 * delegate() = the delegate to be executed 75 * priority = Priority for the timeout function 76 * fireNow = When true the delegate will be executed emmidiatly 77 */ 78 this(uint interval, bool delegate() dlg, GPriority priority, bool fireNow=false) 79 { 80 if ( fireNow && !dlg() ) 81 return; 82 83 timeoutListeners ~= dlg; 84 timeoutID = g_timeout_add_full(priority, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 85 } 86 87 this(Duration interval, bool delegate() dlg, GPriority priority, bool fireNow=false) 88 { 89 this(interval.total!"msecs".to!uint, dlg, priority, fireNow); 90 } 91 92 /** 93 * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. 94 * Params: 95 * delegate() = the delegate to be executed 96 * seconds = interval in seconds. 97 * fireNow = When true the delegate will be executed emmidiatly 98 */ 99 this(bool delegate() dlg, uint seconds, bool fireNow=false) 100 { 101 if ( fireNow && !dlg() ) 102 return; 103 104 timeoutListeners ~= dlg; 105 timeoutID = g_timeout_add_seconds_full(GPriority.DEFAULT, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 106 } 107 108 this(bool delegate() dlg, Duration seconds, bool fireNow=false) 109 { 110 this(dlg, seconds.total!"seconds".to!uint, fireNow); 111 } 112 113 /** 114 * Creates a new timeout cycle. 115 * Params: 116 * delegate() = the delegate to be executed 117 * seconds = interval in seconds. 118 * priority = Priority for the timeout function 119 * fireNow = When true the delegate will be executed emmidiatly 120 */ 121 this(bool delegate() dlg, uint seconds, GPriority priority, bool fireNow=false) 122 { 123 if ( fireNow && !dlg() ) 124 return; 125 126 timeoutListeners ~= dlg; 127 timeoutID = g_timeout_add_seconds_full(priority, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); 128 } 129 130 this(bool delegate() dlg, Duration seconds, GPriority priority, bool fireNow=false) 131 { 132 this(dlg, seconds.total!"seconds".to!uint, priority, fireNow); 133 } 134 135 /** Removes the timeout from gtk */ 136 public void stop() 137 { 138 if ( timeoutID > 0 ) 139 { 140 g_source_remove(timeoutID); 141 } 142 } 143 144 /** 145 * Removes the timeout from gtk 146 */ 147 ~this() 148 { 149 stop(); 150 } 151 152 /** 153 * Adds a new delegate to this timeout cycle 154 * Params: 155 * dlg = 156 * fireNow = 157 */ 158 public void addListener(bool delegate() dlg, bool fireNow=false) 159 { 160 if ( fireNow && !dlg() ) 161 return; 162 163 timeoutListeners ~= dlg; 164 } 165 166 /** 167 * The callback execution from glib 168 * Params: 169 * timeout = 170 * Returns: 171 */ 172 extern(C) static bool timeoutCallback(Timeout timeout) 173 { 174 bool runAgain = false; 175 int i = 0; 176 177 while ( i<timeout.timeoutListeners.length ) 178 { 179 if ( !timeout.timeoutListeners[i]() ) 180 { 181 timeout.timeoutListeners = timeout.timeoutListeners[0..i] ~ timeout.timeoutListeners[i+1..$]; 182 } 183 else 184 { 185 runAgain = true; 186 ++i; 187 } 188 } 189 190 return runAgain; 191 } 192 193 /* 194 * Reset the timeout object when it's destroyed on the GTK side. 195 */ 196 extern(C) static void destroyTimeoutNotify(Timeout timeout) 197 { 198 timeout.timeoutListeners.length = 0; 199 timeout.timeoutID = 0; 200 } 201 202 /** 203 */ 204 205 /** 206 * Sets a function to be called at regular intervals, with the default 207 * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly 208 * until it returns %FALSE, at which point the timeout is automatically 209 * destroyed and the function will not be called again. The first call 210 * to the function will be at the end of the first @interval. 211 * 212 * Note that timeout functions may be delayed, due to the processing of other 213 * event sources. Thus they should not be relied on for precise timing. 214 * After each call to the timeout function, the time of the next 215 * timeout is recalculated based on the current time and the given interval 216 * (it does not try to 'catch up' time lost in delays). 217 * 218 * See [memory management of sources][mainloop-memory-management] for details 219 * on how to handle the return value and memory management of @data. 220 * 221 * If you want to have a timer in the "seconds" range and do not care 222 * about the exact time of the first call of the timer, use the 223 * g_timeout_add_seconds() function; this function allows for more 224 * optimizations and more efficient system power usage. 225 * 226 * This internally creates a main loop source using g_timeout_source_new() 227 * and attaches it to the global #GMainContext using g_source_attach(), so 228 * the callback will be invoked in whichever thread is running that main 229 * context. You can do these steps manually if you need greater control or to 230 * use a custom main context. 231 * 232 * It is safe to call this function from any thread. 233 * 234 * The interval given is in terms of monotonic time, not wall clock 235 * time. See g_get_monotonic_time(). 236 * 237 * Params: 238 * interval = the time between calls to the function, in milliseconds 239 * (1/1000ths of a second) 240 * function_ = function to call 241 * data = data to pass to @function 242 * 243 * Returns: the ID (greater than 0) of the event source. 244 */ 245 public static uint add(uint interval, GSourceFunc function_, void* data) 246 { 247 return g_timeout_add(interval, function_, data); 248 } 249 250 /** 251 * Sets a function to be called at regular intervals, with the given 252 * priority. The function is called repeatedly until it returns 253 * %FALSE, at which point the timeout is automatically destroyed and 254 * the function will not be called again. The @notify function is 255 * called when the timeout is destroyed. The first call to the 256 * function will be at the end of the first @interval. 257 * 258 * Note that timeout functions may be delayed, due to the processing of other 259 * event sources. Thus they should not be relied on for precise timing. 260 * After each call to the timeout function, the time of the next 261 * timeout is recalculated based on the current time and the given interval 262 * (it does not try to 'catch up' time lost in delays). 263 * 264 * See [memory management of sources][mainloop-memory-management] for details 265 * on how to handle the return value and memory management of @data. 266 * 267 * This internally creates a main loop source using g_timeout_source_new() 268 * and attaches it to the global #GMainContext using g_source_attach(), so 269 * the callback will be invoked in whichever thread is running that main 270 * context. You can do these steps manually if you need greater control or to 271 * use a custom main context. 272 * 273 * The interval given is in terms of monotonic time, not wall clock time. 274 * See g_get_monotonic_time(). 275 * 276 * Params: 277 * priority = the priority of the timeout source. Typically this will be in 278 * the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. 279 * interval = the time between calls to the function, in milliseconds 280 * (1/1000ths of a second) 281 * function_ = function to call 282 * data = data to pass to @function 283 * notify = function to call when the timeout is removed, or %NULL 284 * 285 * Returns: the ID (greater than 0) of the event source. 286 */ 287 public static uint addFull(int priority, uint interval, GSourceFunc function_, void* data, GDestroyNotify notify) 288 { 289 return g_timeout_add_full(priority, interval, function_, data, notify); 290 } 291 292 /** 293 * Sets a function to be called at regular intervals with the default 294 * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly until 295 * it returns %FALSE, at which point the timeout is automatically destroyed 296 * and the function will not be called again. 297 * 298 * This internally creates a main loop source using 299 * g_timeout_source_new_seconds() and attaches it to the main loop context 300 * using g_source_attach(). You can do these steps manually if you need 301 * greater control. Also see g_timeout_add_seconds_full(). 302 * 303 * It is safe to call this function from any thread. 304 * 305 * Note that the first call of the timer may not be precise for timeouts 306 * of one second. If you need finer precision and have such a timeout, 307 * you may want to use g_timeout_add() instead. 308 * 309 * See [memory management of sources][mainloop-memory-management] for details 310 * on how to handle the return value and memory management of @data. 311 * 312 * The interval given is in terms of monotonic time, not wall clock 313 * time. See g_get_monotonic_time(). 314 * 315 * Params: 316 * interval = the time between calls to the function, in seconds 317 * function_ = function to call 318 * data = data to pass to @function 319 * 320 * Returns: the ID (greater than 0) of the event source. 321 * 322 * Since: 2.14 323 */ 324 public static uint addSeconds(uint interval, GSourceFunc function_, void* data) 325 { 326 return g_timeout_add_seconds(interval, function_, data); 327 } 328 329 /** 330 * Sets a function to be called at regular intervals, with @priority. 331 * The function is called repeatedly until it returns %FALSE, at which 332 * point the timeout is automatically destroyed and the function will 333 * not be called again. 334 * 335 * Unlike g_timeout_add(), this function operates at whole second granularity. 336 * The initial starting point of the timer is determined by the implementation 337 * and the implementation is expected to group multiple timers together so that 338 * they fire all at the same time. 339 * To allow this grouping, the @interval to the first timer is rounded 340 * and can deviate up to one second from the specified interval. 341 * Subsequent timer iterations will generally run at the specified interval. 342 * 343 * Note that timeout functions may be delayed, due to the processing of other 344 * event sources. Thus they should not be relied on for precise timing. 345 * After each call to the timeout function, the time of the next 346 * timeout is recalculated based on the current time and the given @interval 347 * 348 * See [memory management of sources][mainloop-memory-management] for details 349 * on how to handle the return value and memory management of @data. 350 * 351 * If you want timing more precise than whole seconds, use g_timeout_add() 352 * instead. 353 * 354 * The grouping of timers to fire at the same time results in a more power 355 * and CPU efficient behavior so if your timer is in multiples of seconds 356 * and you don't require the first timer exactly one second from now, the 357 * use of g_timeout_add_seconds() is preferred over g_timeout_add(). 358 * 359 * This internally creates a main loop source using 360 * g_timeout_source_new_seconds() and attaches it to the main loop context 361 * using g_source_attach(). You can do these steps manually if you need 362 * greater control. 363 * 364 * It is safe to call this function from any thread. 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 * function_ = 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 function_, void* data, GDestroyNotify notify) 382 { 383 return g_timeout_add_seconds_full(priority, interval, function_, 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 is 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 }