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