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