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 gio.Task; 26 27 private import gio.AsyncResultIF; 28 private import gio.AsyncResultT; 29 private import gio.Cancellable; 30 private import gio.c.functions; 31 public import gio.c.types; 32 private import glib.ConstructionException; 33 private import glib.ErrorG; 34 private import glib.GException; 35 private import glib.MainContext; 36 private import glib.Source; 37 private import glib.Str; 38 private import gobject.ObjectG; 39 public import gtkc.giotypes; 40 41 42 /** 43 * A #GTask represents and manages a cancellable "task". 44 * 45 * ## Asynchronous operations 46 * 47 * The most common usage of #GTask is as a #GAsyncResult, to 48 * manage data during an asynchronous operation. You call 49 * g_task_new() in the "start" method, followed by 50 * g_task_set_task_data() and the like if you need to keep some 51 * additional data associated with the task, and then pass the 52 * task object around through your asynchronous operation. 53 * Eventually, you will call a method such as 54 * g_task_return_pointer() or g_task_return_error(), which will 55 * save the value you give it and then invoke the task's callback 56 * function (waiting until the next iteration of the main 57 * loop first, if necessary). The caller will pass the #GTask back 58 * to the operation's finish function (as a #GAsyncResult), and 59 * you can use g_task_propagate_pointer() or the like to extract 60 * the return value. 61 * 62 * Here is an example for using GTask as a GAsyncResult: 63 * |[<!-- language="C" --> 64 * typedef struct { 65 * CakeFrostingType frosting; 66 * char *message; 67 * } DecorationData; 68 * 69 * static void 70 * decoration_data_free (DecorationData *decoration) 71 * { 72 * g_free (decoration->message); 73 * g_slice_free (DecorationData, decoration); 74 * } 75 * 76 * static void 77 * baked_cb (Cake *cake, 78 * gpointer user_data) 79 * { 80 * GTask *task = user_data; 81 * DecorationData *decoration = g_task_get_task_data (task); 82 * GError *error = NULL; 83 * 84 * if (cake == NULL) 85 * { 86 * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, 87 * "Go to the supermarket"); 88 * g_object_unref (task); 89 * return; 90 * } 91 * 92 * if (!cake_decorate (cake, decoration->frosting, decoration->message, &error)) 93 * { 94 * g_object_unref (cake); 95 * // g_task_return_error() takes ownership of error 96 * g_task_return_error (task, error); 97 * g_object_unref (task); 98 * return; 99 * } 100 * 101 * g_task_return_pointer (task, cake, g_object_unref); 102 * g_object_unref (task); 103 * } 104 * 105 * void 106 * baker_bake_cake_async (Baker *self, 107 * guint radius, 108 * CakeFlavor flavor, 109 * CakeFrostingType frosting, 110 * const char *message, 111 * GCancellable *cancellable, 112 * GAsyncReadyCallback callback, 113 * gpointer user_data) 114 * { 115 * GTask *task; 116 * DecorationData *decoration; 117 * Cake *cake; 118 * 119 * task = g_task_new (self, cancellable, callback, user_data); 120 * if (radius < 3) 121 * { 122 * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_TOO_SMALL, 123 * "%ucm radius cakes are silly", 124 * radius); 125 * g_object_unref (task); 126 * return; 127 * } 128 * 129 * cake = _baker_get_cached_cake (self, radius, flavor, frosting, message); 130 * if (cake != NULL) 131 * { 132 * // _baker_get_cached_cake() returns a reffed cake 133 * g_task_return_pointer (task, cake, g_object_unref); 134 * g_object_unref (task); 135 * return; 136 * } 137 * 138 * decoration = g_slice_new (DecorationData); 139 * decoration->frosting = frosting; 140 * decoration->message = g_strdup (message); 141 * g_task_set_task_data (task, decoration, (GDestroyNotify) decoration_data_free); 142 * 143 * _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); 144 * } 145 * 146 * Cake * 147 * baker_bake_cake_finish (Baker *self, 148 * GAsyncResult *result, 149 * GError **error) 150 * { 151 * g_return_val_if_fail (g_task_is_valid (result, self), NULL); 152 * 153 * return g_task_propagate_pointer (G_TASK (result), error); 154 * } 155 * ]| 156 * 157 * ## Chained asynchronous operations 158 * 159 * #GTask also tries to simplify asynchronous operations that 160 * internally chain together several smaller asynchronous 161 * operations. g_task_get_cancellable(), g_task_get_context(), 162 * and g_task_get_priority() allow you to get back the task's 163 * #GCancellable, #GMainContext, and [I/O priority][io-priority] 164 * when starting a new subtask, so you don't have to keep track 165 * of them yourself. g_task_attach_source() simplifies the case 166 * of waiting for a source to fire (automatically using the correct 167 * #GMainContext and priority). 168 * 169 * Here is an example for chained asynchronous operations: 170 * |[<!-- language="C" --> 171 * typedef struct { 172 * Cake *cake; 173 * CakeFrostingType frosting; 174 * char *message; 175 * } BakingData; 176 * 177 * static void 178 * decoration_data_free (BakingData *bd) 179 * { 180 * if (bd->cake) 181 * g_object_unref (bd->cake); 182 * g_free (bd->message); 183 * g_slice_free (BakingData, bd); 184 * } 185 * 186 * static void 187 * decorated_cb (Cake *cake, 188 * GAsyncResult *result, 189 * gpointer user_data) 190 * { 191 * GTask *task = user_data; 192 * GError *error = NULL; 193 * 194 * if (!cake_decorate_finish (cake, result, &error)) 195 * { 196 * g_object_unref (cake); 197 * g_task_return_error (task, error); 198 * g_object_unref (task); 199 * return; 200 * } 201 * 202 * // baking_data_free() will drop its ref on the cake, so we have to 203 * // take another here to give to the caller. 204 * g_task_return_pointer (task, g_object_ref (cake), g_object_unref); 205 * g_object_unref (task); 206 * } 207 * 208 * static gboolean 209 * decorator_ready (gpointer user_data) 210 * { 211 * GTask *task = user_data; 212 * BakingData *bd = g_task_get_task_data (task); 213 * 214 * cake_decorate_async (bd->cake, bd->frosting, bd->message, 215 * g_task_get_cancellable (task), 216 * decorated_cb, task); 217 * 218 * return G_SOURCE_REMOVE; 219 * } 220 * 221 * static void 222 * baked_cb (Cake *cake, 223 * gpointer user_data) 224 * { 225 * GTask *task = user_data; 226 * BakingData *bd = g_task_get_task_data (task); 227 * GError *error = NULL; 228 * 229 * if (cake == NULL) 230 * { 231 * g_task_return_new_error (task, BAKER_ERROR, BAKER_ERROR_NO_FLOUR, 232 * "Go to the supermarket"); 233 * g_object_unref (task); 234 * return; 235 * } 236 * 237 * bd->cake = cake; 238 * 239 * // Bail out now if the user has already cancelled 240 * if (g_task_return_error_if_cancelled (task)) 241 * { 242 * g_object_unref (task); 243 * return; 244 * } 245 * 246 * if (cake_decorator_available (cake)) 247 * decorator_ready (task); 248 * else 249 * { 250 * GSource *source; 251 * 252 * source = cake_decorator_wait_source_new (cake); 253 * // Attach @source to @task's GMainContext and have it call 254 * // decorator_ready() when it is ready. 255 * g_task_attach_source (task, source, decorator_ready); 256 * g_source_unref (source); 257 * } 258 * } 259 * 260 * void 261 * baker_bake_cake_async (Baker *self, 262 * guint radius, 263 * CakeFlavor flavor, 264 * CakeFrostingType frosting, 265 * const char *message, 266 * gint priority, 267 * GCancellable *cancellable, 268 * GAsyncReadyCallback callback, 269 * gpointer user_data) 270 * { 271 * GTask *task; 272 * BakingData *bd; 273 * 274 * task = g_task_new (self, cancellable, callback, user_data); 275 * g_task_set_priority (task, priority); 276 * 277 * bd = g_slice_new0 (BakingData); 278 * bd->frosting = frosting; 279 * bd->message = g_strdup (message); 280 * g_task_set_task_data (task, bd, (GDestroyNotify) baking_data_free); 281 * 282 * _baker_begin_cake (self, radius, flavor, cancellable, baked_cb, task); 283 * } 284 * 285 * Cake * 286 * baker_bake_cake_finish (Baker *self, 287 * GAsyncResult *result, 288 * GError **error) 289 * { 290 * g_return_val_if_fail (g_task_is_valid (result, self), NULL); 291 * 292 * return g_task_propagate_pointer (G_TASK (result), error); 293 * } 294 * ]| 295 * 296 * ## Asynchronous operations from synchronous ones 297 * 298 * You can use g_task_run_in_thread() to turn a synchronous 299 * operation into an asynchronous one, by running it in a thread 300 * which will then dispatch the result back to the caller's 301 * #GMainContext when it completes. 302 * 303 * Running a task in a thread: 304 * |[<!-- language="C" --> 305 * typedef struct { 306 * guint radius; 307 * CakeFlavor flavor; 308 * CakeFrostingType frosting; 309 * char *message; 310 * } CakeData; 311 * 312 * static void 313 * cake_data_free (CakeData *cake_data) 314 * { 315 * g_free (cake_data->message); 316 * g_slice_free (CakeData, cake_data); 317 * } 318 * 319 * static void 320 * bake_cake_thread (GTask *task, 321 * gpointer source_object, 322 * gpointer task_data, 323 * GCancellable *cancellable) 324 * { 325 * Baker *self = source_object; 326 * CakeData *cake_data = task_data; 327 * Cake *cake; 328 * GError *error = NULL; 329 * 330 * cake = bake_cake (baker, cake_data->radius, cake_data->flavor, 331 * cake_data->frosting, cake_data->message, 332 * cancellable, &error); 333 * if (cake) 334 * g_task_return_pointer (task, cake, g_object_unref); 335 * else 336 * g_task_return_error (task, error); 337 * } 338 * 339 * void 340 * baker_bake_cake_async (Baker *self, 341 * guint radius, 342 * CakeFlavor flavor, 343 * CakeFrostingType frosting, 344 * const char *message, 345 * GCancellable *cancellable, 346 * GAsyncReadyCallback callback, 347 * gpointer user_data) 348 * { 349 * CakeData *cake_data; 350 * GTask *task; 351 * 352 * cake_data = g_slice_new (CakeData); 353 * cake_data->radius = radius; 354 * cake_data->flavor = flavor; 355 * cake_data->frosting = frosting; 356 * cake_data->message = g_strdup (message); 357 * task = g_task_new (self, cancellable, callback, user_data); 358 * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); 359 * g_task_run_in_thread (task, bake_cake_thread); 360 * g_object_unref (task); 361 * } 362 * 363 * Cake * 364 * baker_bake_cake_finish (Baker *self, 365 * GAsyncResult *result, 366 * GError **error) 367 * { 368 * g_return_val_if_fail (g_task_is_valid (result, self), NULL); 369 * 370 * return g_task_propagate_pointer (G_TASK (result), error); 371 * } 372 * ]| 373 * 374 * ## Adding cancellability to uncancellable tasks 375 * 376 * Finally, g_task_run_in_thread() and g_task_run_in_thread_sync() 377 * can be used to turn an uncancellable operation into a 378 * cancellable one. If you call g_task_set_return_on_cancel(), 379 * passing %TRUE, then if the task's #GCancellable is cancelled, 380 * it will return control back to the caller immediately, while 381 * allowing the task thread to continue running in the background 382 * (and simply discarding its result when it finally does finish). 383 * Provided that the task thread is careful about how it uses 384 * locks and other externally-visible resources, this allows you 385 * to make "GLib-friendly" asynchronous and cancellable 386 * synchronous variants of blocking APIs. 387 * 388 * Cancelling a task: 389 * |[<!-- language="C" --> 390 * static void 391 * bake_cake_thread (GTask *task, 392 * gpointer source_object, 393 * gpointer task_data, 394 * GCancellable *cancellable) 395 * { 396 * Baker *self = source_object; 397 * CakeData *cake_data = task_data; 398 * Cake *cake; 399 * GError *error = NULL; 400 * 401 * cake = bake_cake (baker, cake_data->radius, cake_data->flavor, 402 * cake_data->frosting, cake_data->message, 403 * &error); 404 * if (error) 405 * { 406 * g_task_return_error (task, error); 407 * return; 408 * } 409 * 410 * // If the task has already been cancelled, then we don't want to add 411 * // the cake to the cake cache. Likewise, we don't want to have the 412 * // task get cancelled in the middle of updating the cache. 413 * // g_task_set_return_on_cancel() will return %TRUE here if it managed 414 * // to disable return-on-cancel, or %FALSE if the task was cancelled 415 * // before it could. 416 * if (g_task_set_return_on_cancel (task, FALSE)) 417 * { 418 * // If the caller cancels at this point, their 419 * // GAsyncReadyCallback won't be invoked until we return, 420 * // so we don't have to worry that this code will run at 421 * // the same time as that code does. But if there were 422 * // other functions that might look at the cake cache, 423 * // then we'd probably need a GMutex here as well. 424 * baker_add_cake_to_cache (baker, cake); 425 * g_task_return_pointer (task, cake, g_object_unref); 426 * } 427 * } 428 * 429 * void 430 * baker_bake_cake_async (Baker *self, 431 * guint radius, 432 * CakeFlavor flavor, 433 * CakeFrostingType frosting, 434 * const char *message, 435 * GCancellable *cancellable, 436 * GAsyncReadyCallback callback, 437 * gpointer user_data) 438 * { 439 * CakeData *cake_data; 440 * GTask *task; 441 * 442 * cake_data = g_slice_new (CakeData); 443 * 444 * ... 445 * 446 * task = g_task_new (self, cancellable, callback, user_data); 447 * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); 448 * g_task_set_return_on_cancel (task, TRUE); 449 * g_task_run_in_thread (task, bake_cake_thread); 450 * } 451 * 452 * Cake * 453 * baker_bake_cake_sync (Baker *self, 454 * guint radius, 455 * CakeFlavor flavor, 456 * CakeFrostingType frosting, 457 * const char *message, 458 * GCancellable *cancellable, 459 * GError **error) 460 * { 461 * CakeData *cake_data; 462 * GTask *task; 463 * Cake *cake; 464 * 465 * cake_data = g_slice_new (CakeData); 466 * 467 * ... 468 * 469 * task = g_task_new (self, cancellable, NULL, NULL); 470 * g_task_set_task_data (task, cake_data, (GDestroyNotify) cake_data_free); 471 * g_task_set_return_on_cancel (task, TRUE); 472 * g_task_run_in_thread_sync (task, bake_cake_thread); 473 * 474 * cake = g_task_propagate_pointer (task, error); 475 * g_object_unref (task); 476 * return cake; 477 * } 478 * ]| 479 * 480 * ## Porting from GSimpleAsyncResult 481 * 482 * #GTask's API attempts to be simpler than #GSimpleAsyncResult's 483 * in several ways: 484 * - You can save task-specific data with g_task_set_task_data(), and 485 * retrieve it later with g_task_get_task_data(). This replaces the 486 * abuse of g_simple_async_result_set_op_res_gpointer() for the same 487 * purpose with #GSimpleAsyncResult. 488 * - In addition to the task data, #GTask also keeps track of the 489 * [priority][io-priority], #GCancellable, and 490 * #GMainContext associated with the task, so tasks that consist of 491 * a chain of simpler asynchronous operations will have easy access 492 * to those values when starting each sub-task. 493 * - g_task_return_error_if_cancelled() provides simplified 494 * handling for cancellation. In addition, cancellation 495 * overrides any other #GTask return value by default, like 496 * #GSimpleAsyncResult does when 497 * g_simple_async_result_set_check_cancellable() is called. 498 * (You can use g_task_set_check_cancellable() to turn off that 499 * behavior.) On the other hand, g_task_run_in_thread() 500 * guarantees that it will always run your 501 * `task_func`, even if the task's #GCancellable 502 * is already cancelled before the task gets a chance to run; 503 * you can start your `task_func` with a 504 * g_task_return_error_if_cancelled() check if you need the 505 * old behavior. 506 * - The "return" methods (eg, g_task_return_pointer()) 507 * automatically cause the task to be "completed" as well, and 508 * there is no need to worry about the "complete" vs "complete 509 * in idle" distinction. (#GTask automatically figures out 510 * whether the task's callback can be invoked directly, or 511 * if it needs to be sent to another #GMainContext, or delayed 512 * until the next iteration of the current #GMainContext.) 513 * - The "finish" functions for #GTask-based operations are generally 514 * much simpler than #GSimpleAsyncResult ones, normally consisting 515 * of only a single call to g_task_propagate_pointer() or the like. 516 * Since g_task_propagate_pointer() "steals" the return value from 517 * the #GTask, it is not necessary to juggle pointers around to 518 * prevent it from being freed twice. 519 * - With #GSimpleAsyncResult, it was common to call 520 * g_simple_async_result_propagate_error() from the 521 * `_finish()` wrapper function, and have 522 * virtual method implementations only deal with successful 523 * returns. This behavior is deprecated, because it makes it 524 * difficult for a subclass to chain to a parent class's async 525 * methods. Instead, the wrapper function should just be a 526 * simple wrapper, and the virtual method should call an 527 * appropriate `g_task_propagate_` function. 528 * Note that wrapper methods can now use 529 * g_async_result_legacy_propagate_error() to do old-style 530 * #GSimpleAsyncResult error-returning behavior, and 531 * g_async_result_is_tagged() to check if a result is tagged as 532 * having come from the `_async()` wrapper 533 * function (for "short-circuit" results, such as when passing 534 * 0 to g_input_stream_read_async()). 535 */ 536 public class Task : ObjectG, AsyncResultIF 537 { 538 /** the main Gtk struct */ 539 protected GTask* gTask; 540 541 /** Get the main Gtk struct */ 542 public GTask* getTaskStruct(bool transferOwnership = false) 543 { 544 if (transferOwnership) 545 ownedRef = false; 546 return gTask; 547 } 548 549 /** the main Gtk struct as a void* */ 550 protected override void* getStruct() 551 { 552 return cast(void*)gTask; 553 } 554 555 protected override void setStruct(GObject* obj) 556 { 557 gTask = cast(GTask*)obj; 558 super.setStruct(obj); 559 } 560 561 /** 562 * Sets our main struct and passes it to the parent class. 563 */ 564 public this (GTask* gTask, bool ownedRef = false) 565 { 566 this.gTask = gTask; 567 super(cast(GObject*)gTask, ownedRef); 568 } 569 570 // add the AsyncResult capabilities 571 mixin AsyncResultT!(GTask); 572 573 574 /** */ 575 public static GType getType() 576 { 577 return g_task_get_type(); 578 } 579 580 /** 581 * Creates a #GTask acting on @source_object, which will eventually be 582 * used to invoke @callback in the current 583 * [thread-default main context][g-main-context-push-thread-default]. 584 * 585 * Call this in the "start" method of your asynchronous method, and 586 * pass the #GTask around throughout the asynchronous operation. You 587 * can use g_task_set_task_data() to attach task-specific data to the 588 * object, which you can retrieve later via g_task_get_task_data(). 589 * 590 * By default, if @cancellable is cancelled, then the return value of 591 * the task will always be %G_IO_ERROR_CANCELLED, even if the task had 592 * already completed before the cancellation. This allows for 593 * simplified handling in cases where cancellation may imply that 594 * other objects that the task depends on have been destroyed. If you 595 * do not want this behavior, you can use 596 * g_task_set_check_cancellable() to change it. 597 * 598 * Params: 599 * sourceObject = the #GObject that owns 600 * this task, or %NULL. 601 * cancellable = optional #GCancellable object, %NULL to ignore. 602 * callback = a #GAsyncReadyCallback. 603 * callbackData = user data passed to @callback. 604 * 605 * Returns: a #GTask. 606 * 607 * Since: 2.36 608 * 609 * Throws: ConstructionException GTK+ fails to create the object. 610 */ 611 public this(ObjectG sourceObject, Cancellable cancellable, GAsyncReadyCallback callback, void* callbackData) 612 { 613 auto p = g_task_new((sourceObject is null) ? null : sourceObject.getObjectGStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, callbackData); 614 615 if(p is null) 616 { 617 throw new ConstructionException("null returned by new"); 618 } 619 620 this(cast(GTask*) p, true); 621 } 622 623 /** 624 * Checks that @result is a #GTask, and that @source_object is its 625 * source object (or that @source_object is %NULL and @result has no 626 * source object). This can be used in g_return_if_fail() checks. 627 * 628 * Params: 629 * result = A #GAsyncResult 630 * sourceObject = the source object 631 * expected to be associated with the task 632 * 633 * Returns: %TRUE if @result and @source_object are valid, %FALSE 634 * if not 635 * 636 * Since: 2.36 637 */ 638 public static bool isValid(AsyncResultIF result, ObjectG sourceObject) 639 { 640 return g_task_is_valid((result is null) ? null : result.getAsyncResultStruct(), (sourceObject is null) ? null : sourceObject.getObjectGStruct()) != 0; 641 } 642 643 /** 644 * Creates a #GTask and then immediately calls g_task_return_error() 645 * on it. Use this in the wrapper function of an asynchronous method 646 * when you want to avoid even calling the virtual method. You can 647 * then use g_async_result_is_tagged() in the finish method wrapper to 648 * check if the result there is tagged as having been created by the 649 * wrapper method, and deal with it appropriately if so. 650 * 651 * See also g_task_report_new_error(). 652 * 653 * Params: 654 * sourceObject = the #GObject that owns 655 * this task, or %NULL. 656 * callback = a #GAsyncReadyCallback. 657 * callbackData = user data passed to @callback. 658 * sourceTag = an opaque pointer indicating the source of this task 659 * error = error to report 660 * 661 * Since: 2.36 662 */ 663 public static void reportError(ObjectG sourceObject, GAsyncReadyCallback callback, void* callbackData, void* sourceTag, ErrorG error) 664 { 665 g_task_report_error((sourceObject is null) ? null : sourceObject.getObjectGStruct(), callback, callbackData, sourceTag, (error is null) ? null : error.getErrorGStruct(true)); 666 } 667 668 /** 669 * A utility function for dealing with async operations where you need 670 * to wait for a #GSource to trigger. Attaches @source to @task's 671 * #GMainContext with @task's [priority][io-priority], and sets @source's 672 * callback to @callback, with @task as the callback's `user_data`. 673 * 674 * This takes a reference on @task until @source is destroyed. 675 * 676 * Params: 677 * source = the source to attach 678 * callback = the callback to invoke when @source triggers 679 * 680 * Since: 2.36 681 */ 682 public void attachSource(Source source, GSourceFunc callback) 683 { 684 g_task_attach_source(gTask, (source is null) ? null : source.getSourceStruct(), callback); 685 } 686 687 /** 688 * Gets @task's #GCancellable 689 * 690 * Returns: @task's #GCancellable 691 * 692 * Since: 2.36 693 */ 694 public Cancellable getCancellable() 695 { 696 auto p = g_task_get_cancellable(gTask); 697 698 if(p is null) 699 { 700 return null; 701 } 702 703 return ObjectG.getDObject!(Cancellable)(cast(GCancellable*) p); 704 } 705 706 /** 707 * Gets @task's check-cancellable flag. See 708 * g_task_set_check_cancellable() for more details. 709 * 710 * Since: 2.36 711 */ 712 public bool getCheckCancellable() 713 { 714 return g_task_get_check_cancellable(gTask) != 0; 715 } 716 717 /** 718 * Gets the value of #GTask:completed. This changes from %FALSE to %TRUE after 719 * the task’s callback is invoked, and will return %FALSE if called from inside 720 * the callback. 721 * 722 * Returns: %TRUE if the task has completed, %FALSE otherwise. 723 * 724 * Since: 2.44 725 */ 726 public bool getCompleted() 727 { 728 return g_task_get_completed(gTask) != 0; 729 } 730 731 /** 732 * Gets the #GMainContext that @task will return its result in (that 733 * is, the context that was the 734 * [thread-default main context][g-main-context-push-thread-default] 735 * at the point when @task was created). 736 * 737 * This will always return a non-%NULL value, even if the task's 738 * context is the default #GMainContext. 739 * 740 * Returns: @task's #GMainContext 741 * 742 * Since: 2.36 743 */ 744 public MainContext getContext() 745 { 746 auto p = g_task_get_context(gTask); 747 748 if(p is null) 749 { 750 return null; 751 } 752 753 return new MainContext(cast(GMainContext*) p); 754 } 755 756 /** 757 * Gets @task's priority 758 * 759 * Returns: @task's priority 760 * 761 * Since: 2.36 762 */ 763 public int getPriority() 764 { 765 return g_task_get_priority(gTask); 766 } 767 768 /** 769 * Gets @task's return-on-cancel flag. See 770 * g_task_set_return_on_cancel() for more details. 771 * 772 * Since: 2.36 773 */ 774 public bool getReturnOnCancel() 775 { 776 return g_task_get_return_on_cancel(gTask) != 0; 777 } 778 779 /** 780 * Gets the source object from @task. Like 781 * g_async_result_get_source_object(), but does not ref the object. 782 * 783 * Returns: @task's source object, or %NULL 784 * 785 * Since: 2.36 786 */ 787 public ObjectG getSourceObject() 788 { 789 auto p = g_task_get_source_object(gTask); 790 791 if(p is null) 792 { 793 return null; 794 } 795 796 return ObjectG.getDObject!(ObjectG)(cast(GObject*) p); 797 } 798 799 /** 800 * Gets @task's source tag. See g_task_set_source_tag(). 801 * 802 * Returns: @task's source tag 803 * 804 * Since: 2.36 805 */ 806 public void* getSourceTag() 807 { 808 return g_task_get_source_tag(gTask); 809 } 810 811 /** 812 * Gets @task's `task_data`. 813 * 814 * Returns: @task's `task_data`. 815 * 816 * Since: 2.36 817 */ 818 public void* getTaskData() 819 { 820 return g_task_get_task_data(gTask); 821 } 822 823 /** 824 * Tests if @task resulted in an error. 825 * 826 * Returns: %TRUE if the task resulted in an error, %FALSE otherwise. 827 * 828 * Since: 2.36 829 */ 830 public bool hadError() 831 { 832 return g_task_had_error(gTask) != 0; 833 } 834 835 /** 836 * Gets the result of @task as a #gboolean. 837 * 838 * If the task resulted in an error, or was cancelled, then this will 839 * instead return %FALSE and set @error. 840 * 841 * Since this method transfers ownership of the return value (or 842 * error) to the caller, you may only call it once. 843 * 844 * Returns: the task result, or %FALSE on error 845 * 846 * Since: 2.36 847 * 848 * Throws: GException on failure. 849 */ 850 public bool propagateBoolean() 851 { 852 GError* err = null; 853 854 auto p = g_task_propagate_boolean(gTask, &err) != 0; 855 856 if (err !is null) 857 { 858 throw new GException( new ErrorG(err) ); 859 } 860 861 return p; 862 } 863 864 /** 865 * Gets the result of @task as an integer (#gssize). 866 * 867 * If the task resulted in an error, or was cancelled, then this will 868 * instead return -1 and set @error. 869 * 870 * Since this method transfers ownership of the return value (or 871 * error) to the caller, you may only call it once. 872 * 873 * Returns: the task result, or -1 on error 874 * 875 * Since: 2.36 876 * 877 * Throws: GException on failure. 878 */ 879 public ptrdiff_t propagateInt() 880 { 881 GError* err = null; 882 883 auto p = g_task_propagate_int(gTask, &err); 884 885 if (err !is null) 886 { 887 throw new GException( new ErrorG(err) ); 888 } 889 890 return p; 891 } 892 893 /** 894 * Gets the result of @task as a pointer, and transfers ownership 895 * of that value to the caller. 896 * 897 * If the task resulted in an error, or was cancelled, then this will 898 * instead return %NULL and set @error. 899 * 900 * Since this method transfers ownership of the return value (or 901 * error) to the caller, you may only call it once. 902 * 903 * Returns: the task result, or %NULL on error 904 * 905 * Since: 2.36 906 * 907 * Throws: GException on failure. 908 */ 909 public void* propagatePointer() 910 { 911 GError* err = null; 912 913 auto p = g_task_propagate_pointer(gTask, &err); 914 915 if (err !is null) 916 { 917 throw new GException( new ErrorG(err) ); 918 } 919 920 return p; 921 } 922 923 /** 924 * Sets @task's result to @result and completes the task (see 925 * g_task_return_pointer() for more discussion of exactly what this 926 * means). 927 * 928 * Params: 929 * result = the #gboolean result of a task function. 930 * 931 * Since: 2.36 932 */ 933 public void returnBoolean(bool result) 934 { 935 g_task_return_boolean(gTask, result); 936 } 937 938 /** 939 * Sets @task's result to @error (which @task assumes ownership of) 940 * and completes the task (see g_task_return_pointer() for more 941 * discussion of exactly what this means). 942 * 943 * Note that since the task takes ownership of @error, and since the 944 * task may be completed before returning from g_task_return_error(), 945 * you cannot assume that @error is still valid after calling this. 946 * Call g_error_copy() on the error if you need to keep a local copy 947 * as well. 948 * 949 * See also g_task_return_new_error(). 950 * 951 * Params: 952 * error = the #GError result of a task function. 953 * 954 * Since: 2.36 955 */ 956 public void returnError(ErrorG error) 957 { 958 g_task_return_error(gTask, (error is null) ? null : error.getErrorGStruct(true)); 959 } 960 961 /** 962 * Checks if @task's #GCancellable has been cancelled, and if so, sets 963 * @task's error accordingly and completes the task (see 964 * g_task_return_pointer() for more discussion of exactly what this 965 * means). 966 * 967 * Returns: %TRUE if @task has been cancelled, %FALSE if not 968 * 969 * Since: 2.36 970 */ 971 public bool returnErrorIfCancelled() 972 { 973 return g_task_return_error_if_cancelled(gTask) != 0; 974 } 975 976 /** 977 * Sets @task's result to @result and completes the task (see 978 * g_task_return_pointer() for more discussion of exactly what this 979 * means). 980 * 981 * Params: 982 * result = the integer (#gssize) result of a task function. 983 * 984 * Since: 2.36 985 */ 986 public void returnInt(ptrdiff_t result) 987 { 988 g_task_return_int(gTask, result); 989 } 990 991 /** 992 * Sets @task's result to @result and completes the task. If @result 993 * is not %NULL, then @result_destroy will be used to free @result if 994 * the caller does not take ownership of it with 995 * g_task_propagate_pointer(). 996 * 997 * "Completes the task" means that for an ordinary asynchronous task 998 * it will either invoke the task's callback, or else queue that 999 * callback to be invoked in the proper #GMainContext, or in the next 1000 * iteration of the current #GMainContext. For a task run via 1001 * g_task_run_in_thread() or g_task_run_in_thread_sync(), calling this 1002 * method will save @result to be returned to the caller later, but 1003 * the task will not actually be completed until the #GTaskThreadFunc 1004 * exits. 1005 * 1006 * Note that since the task may be completed before returning from 1007 * g_task_return_pointer(), you cannot assume that @result is still 1008 * valid after calling this, unless you are still holding another 1009 * reference on it. 1010 * 1011 * Params: 1012 * result = the pointer result of a task 1013 * function 1014 * resultDestroy = a #GDestroyNotify function. 1015 * 1016 * Since: 2.36 1017 */ 1018 public void returnPointer(void* result, GDestroyNotify resultDestroy) 1019 { 1020 g_task_return_pointer(gTask, result, resultDestroy); 1021 } 1022 1023 /** 1024 * Runs @task_func in another thread. When @task_func returns, @task's 1025 * #GAsyncReadyCallback will be invoked in @task's #GMainContext. 1026 * 1027 * This takes a ref on @task until the task completes. 1028 * 1029 * See #GTaskThreadFunc for more details about how @task_func is handled. 1030 * 1031 * Although GLib currently rate-limits the tasks queued via 1032 * g_task_run_in_thread(), you should not assume that it will always 1033 * do this. If you have a very large number of tasks to run, but don't 1034 * want them to all run at once, you should only queue a limited 1035 * number of them at a time. 1036 * 1037 * Params: 1038 * taskFunc = a #GTaskThreadFunc 1039 * 1040 * Since: 2.36 1041 */ 1042 public void runInThread(GTaskThreadFunc taskFunc) 1043 { 1044 g_task_run_in_thread(gTask, taskFunc); 1045 } 1046 1047 /** 1048 * Runs @task_func in another thread, and waits for it to return or be 1049 * cancelled. You can use g_task_propagate_pointer(), etc, afterward 1050 * to get the result of @task_func. 1051 * 1052 * See #GTaskThreadFunc for more details about how @task_func is handled. 1053 * 1054 * Normally this is used with tasks created with a %NULL 1055 * `callback`, but note that even if the task does 1056 * have a callback, it will not be invoked when @task_func returns. 1057 * #GTask:completed will be set to %TRUE just before this function returns. 1058 * 1059 * Although GLib currently rate-limits the tasks queued via 1060 * g_task_run_in_thread_sync(), you should not assume that it will 1061 * always do this. If you have a very large number of tasks to run, 1062 * but don't want them to all run at once, you should only queue a 1063 * limited number of them at a time. 1064 * 1065 * Params: 1066 * taskFunc = a #GTaskThreadFunc 1067 * 1068 * Since: 2.36 1069 */ 1070 public void runInThreadSync(GTaskThreadFunc taskFunc) 1071 { 1072 g_task_run_in_thread_sync(gTask, taskFunc); 1073 } 1074 1075 /** 1076 * Sets or clears @task's check-cancellable flag. If this is %TRUE 1077 * (the default), then g_task_propagate_pointer(), etc, and 1078 * g_task_had_error() will check the task's #GCancellable first, and 1079 * if it has been cancelled, then they will consider the task to have 1080 * returned an "Operation was cancelled" error 1081 * (%G_IO_ERROR_CANCELLED), regardless of any other error or return 1082 * value the task may have had. 1083 * 1084 * If @check_cancellable is %FALSE, then the #GTask will not check the 1085 * cancellable itself, and it is up to @task's owner to do this (eg, 1086 * via g_task_return_error_if_cancelled()). 1087 * 1088 * If you are using g_task_set_return_on_cancel() as well, then 1089 * you must leave check-cancellable set %TRUE. 1090 * 1091 * Params: 1092 * checkCancellable = whether #GTask will check the state of 1093 * its #GCancellable for you. 1094 * 1095 * Since: 2.36 1096 */ 1097 public void setCheckCancellable(bool checkCancellable) 1098 { 1099 g_task_set_check_cancellable(gTask, checkCancellable); 1100 } 1101 1102 /** 1103 * Sets @task's priority. If you do not call this, it will default to 1104 * %G_PRIORITY_DEFAULT. 1105 * 1106 * This will affect the priority of #GSources created with 1107 * g_task_attach_source() and the scheduling of tasks run in threads, 1108 * and can also be explicitly retrieved later via 1109 * g_task_get_priority(). 1110 * 1111 * Params: 1112 * priority = the [priority][io-priority] of the request 1113 * 1114 * Since: 2.36 1115 */ 1116 public void setPriority(int priority) 1117 { 1118 g_task_set_priority(gTask, priority); 1119 } 1120 1121 /** 1122 * Sets or clears @task's return-on-cancel flag. This is only 1123 * meaningful for tasks run via g_task_run_in_thread() or 1124 * g_task_run_in_thread_sync(). 1125 * 1126 * If @return_on_cancel is %TRUE, then cancelling @task's 1127 * #GCancellable will immediately cause it to return, as though the 1128 * task's #GTaskThreadFunc had called 1129 * g_task_return_error_if_cancelled() and then returned. 1130 * 1131 * This allows you to create a cancellable wrapper around an 1132 * uninterruptable function. The #GTaskThreadFunc just needs to be 1133 * careful that it does not modify any externally-visible state after 1134 * it has been cancelled. To do that, the thread should call 1135 * g_task_set_return_on_cancel() again to (atomically) set 1136 * return-on-cancel %FALSE before making externally-visible changes; 1137 * if the task gets cancelled before the return-on-cancel flag could 1138 * be changed, g_task_set_return_on_cancel() will indicate this by 1139 * returning %FALSE. 1140 * 1141 * You can disable and re-enable this flag multiple times if you wish. 1142 * If the task's #GCancellable is cancelled while return-on-cancel is 1143 * %FALSE, then calling g_task_set_return_on_cancel() to set it %TRUE 1144 * again will cause the task to be cancelled at that point. 1145 * 1146 * If the task's #GCancellable is already cancelled before you call 1147 * g_task_run_in_thread()/g_task_run_in_thread_sync(), then the 1148 * #GTaskThreadFunc will still be run (for consistency), but the task 1149 * will also be completed right away. 1150 * 1151 * Params: 1152 * returnOnCancel = whether the task returns automatically when 1153 * it is cancelled. 1154 * 1155 * Returns: %TRUE if @task's return-on-cancel flag was changed to 1156 * match @return_on_cancel. %FALSE if @task has already been 1157 * cancelled. 1158 * 1159 * Since: 2.36 1160 */ 1161 public bool setReturnOnCancel(bool returnOnCancel) 1162 { 1163 return g_task_set_return_on_cancel(gTask, returnOnCancel) != 0; 1164 } 1165 1166 /** 1167 * Sets @task's source tag. You can use this to tag a task return 1168 * value with a particular pointer (usually a pointer to the function 1169 * doing the tagging) and then later check it using 1170 * g_task_get_source_tag() (or g_async_result_is_tagged()) in the 1171 * task's "finish" function, to figure out if the response came from a 1172 * particular place. 1173 * 1174 * Params: 1175 * sourceTag = an opaque pointer indicating the source of this task 1176 * 1177 * Since: 2.36 1178 */ 1179 public void setSourceTag(void* sourceTag) 1180 { 1181 g_task_set_source_tag(gTask, sourceTag); 1182 } 1183 1184 /** 1185 * Sets @task's task data (freeing the existing task data, if any). 1186 * 1187 * Params: 1188 * taskData = task-specific data 1189 * taskDataDestroy = #GDestroyNotify for @task_data 1190 * 1191 * Since: 2.36 1192 */ 1193 public void setTaskData(void* taskData, GDestroyNotify taskDataDestroy) 1194 { 1195 g_task_set_task_data(gTask, taskData, taskDataDestroy); 1196 } 1197 }