mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-05 08:53:39 +02:00
Add examples for GAsyncInitiable and GSimpleAsyncResult
Bug 602417
This commit is contained in:
committed by
Matthias Clasen
parent
7a32e34f7c
commit
28a4fff7ec
@@ -45,6 +45,100 @@
|
|||||||
* directly, or indirectly via a foo_thing_new_async() wrapper. This will call
|
* directly, or indirectly via a foo_thing_new_async() wrapper. This will call
|
||||||
* g_async_initable_init_async() under the cover, calling back with %NULL and
|
* g_async_initable_init_async() under the cover, calling back with %NULL and
|
||||||
* a set %GError on failure.
|
* a set %GError on failure.
|
||||||
|
*
|
||||||
|
* A typical implementation might look something like this:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* enum {
|
||||||
|
* NOT_INITIALIZED,
|
||||||
|
* INITIALIZING,
|
||||||
|
* INITIALIZED
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* static void
|
||||||
|
* _foo_ready_cb (Foo *self)
|
||||||
|
* {
|
||||||
|
* GList *l;
|
||||||
|
*
|
||||||
|
* self->priv->state = INITIALIZED;
|
||||||
|
*
|
||||||
|
* for (l = self->priv->init_results; l != NULL; l = l->next)
|
||||||
|
* {
|
||||||
|
* GSimpleAsyncResult *simple = l->data;
|
||||||
|
*
|
||||||
|
* if (!self->priv->success)
|
||||||
|
* g_simple_async_result_set_error (simple, ...);
|
||||||
|
*
|
||||||
|
* g_simple_async_result_complete (simple);
|
||||||
|
* g_object_unref (simple);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* g_list_free (self->priv->init_results);
|
||||||
|
* self->priv->init_results = NULL;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static void
|
||||||
|
* foo_init_async (GAsyncInitable *initable,
|
||||||
|
* int io_priority,
|
||||||
|
* GCancellable *cancellable,
|
||||||
|
* GAsyncReadyCallback callback,
|
||||||
|
* gpointer user_data)
|
||||||
|
* {
|
||||||
|
* Foo *self = FOO (initable);
|
||||||
|
* GSimpleAsyncResult *simple;
|
||||||
|
*
|
||||||
|
* simple = g_simple_async_result_new (G_OBJECT (initable)
|
||||||
|
* callback,
|
||||||
|
* user_data,
|
||||||
|
* foo_init_async);
|
||||||
|
*
|
||||||
|
* switch (self->priv->state)
|
||||||
|
* {
|
||||||
|
* case NOT_INITIALIZED:
|
||||||
|
* _foo_get_ready (self);
|
||||||
|
* self->priv->init_results = g_list_append (self->priv->init_results,
|
||||||
|
* simple);
|
||||||
|
* self->priv->state = INITIALIZING;
|
||||||
|
* break;
|
||||||
|
* case INITIALIZING:
|
||||||
|
* self->priv->init_results = g_list_append (self->priv->init_results,
|
||||||
|
* simple);
|
||||||
|
* break;
|
||||||
|
* case INITIALIZED:
|
||||||
|
* if (!self->priv->success)
|
||||||
|
* g_simple_async_result_set_error (simple, ...);
|
||||||
|
*
|
||||||
|
* g_simple_async_result_complete_in_idle (simple);
|
||||||
|
* g_object_unref (simple);
|
||||||
|
* break;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static gboolean
|
||||||
|
* foo_init_finish (GAsyncInitable *initable,
|
||||||
|
* GAsyncResult *result,
|
||||||
|
* GError **error)
|
||||||
|
* {
|
||||||
|
* g_return_val_if_fail (g_simple_async_result_is_valid (result,
|
||||||
|
* G_OBJECT (initable), foo_init_async), FALSE);
|
||||||
|
*
|
||||||
|
* if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result),
|
||||||
|
* error))
|
||||||
|
* return FALSE;
|
||||||
|
*
|
||||||
|
* return TRUE;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* static void
|
||||||
|
* foo_async_initable_iface_init (gpointer g_iface,
|
||||||
|
* gpointer data)
|
||||||
|
* {
|
||||||
|
* GAsyncInitableIface *iface = g_iface;
|
||||||
|
*
|
||||||
|
* iface->init_async = foo_init_async;
|
||||||
|
* iface->init_finish = foo_init_finish;
|
||||||
|
* }
|
||||||
|
* ]|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void g_async_initable_real_init_async (GAsyncInitable *initable,
|
static void g_async_initable_real_init_async (GAsyncInitable *initable,
|
||||||
|
@@ -109,7 +109,109 @@
|
|||||||
* g_simple_async_result_get_op_res_gssize() are
|
* g_simple_async_result_get_op_res_gssize() are
|
||||||
* provided, getting the operation's result as a gpointer, gboolean, and
|
* provided, getting the operation's result as a gpointer, gboolean, and
|
||||||
* gssize, respectively.
|
* gssize, respectively.
|
||||||
**/
|
*
|
||||||
|
* For the details of the requirements implementations must respect, see
|
||||||
|
* #GAsyncResult. A typical implementation of an asynchronous operation
|
||||||
|
* using GSimpleAsyncResult looks something like this:
|
||||||
|
*
|
||||||
|
* |[
|
||||||
|
* static void
|
||||||
|
* baked_cb (Cake *cake,
|
||||||
|
* gpointer user_data)
|
||||||
|
* {
|
||||||
|
* /* In this example, this callback is not given a reference to the cake, so
|
||||||
|
* * the GSimpleAsyncResult has to take a reference to it.
|
||||||
|
* */
|
||||||
|
* GSimpleAsyncResult *result = user_data;
|
||||||
|
*
|
||||||
|
* if (cake == NULL)
|
||||||
|
* g_simple_async_result_set_error (result,
|
||||||
|
* BAKER_ERRORS,
|
||||||
|
* BAKER_ERROR_NO_FLOUR,
|
||||||
|
* "Go to the supermarket");
|
||||||
|
* else
|
||||||
|
* g_simple_async_result_set_op_res_gpointer (result,
|
||||||
|
* g_object_ref (cake),
|
||||||
|
* g_object_unref);
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* /* In this example, we assume that baked_cb is called as a callback from
|
||||||
|
* * the mainloop, so it's safe to complete the operation synchronously here.
|
||||||
|
* * If, however, _baker_prepare_cake () might call its callback without
|
||||||
|
* * first returning to the mainloop — inadvisable, but some APIs do so —
|
||||||
|
* * we would need to use g_simple_async_result_complete_in_idle().
|
||||||
|
* */
|
||||||
|
* g_simple_async_result_complete (result);
|
||||||
|
* g_object_unref (result);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void
|
||||||
|
* baker_bake_cake_async (Baker *self,
|
||||||
|
* guint radius,
|
||||||
|
* GAsyncReadyCallback callback,
|
||||||
|
* gpointer user_data)
|
||||||
|
* {
|
||||||
|
* GSimpleAsyncResult *simple;
|
||||||
|
* Cake *cake;
|
||||||
|
*
|
||||||
|
* if (radius < 3)
|
||||||
|
* {
|
||||||
|
* g_simple_async_report_error_in_idle (G_OBJECT (self),
|
||||||
|
* callback,
|
||||||
|
* user_data,
|
||||||
|
* BAKER_ERRORS,
|
||||||
|
* BAKER_ERROR_TOO_SMALL,
|
||||||
|
* "%ucm radius cakes are silly",
|
||||||
|
* radius);
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* simple = g_simple_async_result_new (G_OBJECT (self),
|
||||||
|
* callback,
|
||||||
|
* user_data,
|
||||||
|
* baker_bake_cake_async);
|
||||||
|
* cake = _baker_get_cached_cake (self, radius);
|
||||||
|
*
|
||||||
|
* if (cake != NULL)
|
||||||
|
* {
|
||||||
|
* g_simple_async_result_set_op_res_gpointer (simple,
|
||||||
|
* g_object_ref (cake),
|
||||||
|
* g_object_unref);
|
||||||
|
* g_simple_async_result_complete_in_idle (simple);
|
||||||
|
* g_object_unref (simple);
|
||||||
|
* /* Drop the reference returned by _baker_get_cached_cake(); the
|
||||||
|
* * GSimpleAsyncResult has taken its own reference.
|
||||||
|
* */
|
||||||
|
* g_object_unref (cake);
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* _baker_prepare_cake (self, radius, baked_cb, user_data);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* Cake *
|
||||||
|
* baker_bake_cake_finish (Baker *self,
|
||||||
|
* GAsyncResult *result,
|
||||||
|
* GError **error)
|
||||||
|
* {
|
||||||
|
* GSimpleAsyncResult *simple;
|
||||||
|
* Cake *cake;
|
||||||
|
*
|
||||||
|
* g_return_val_if_fail (g_simple_async_result_is_valid (result,
|
||||||
|
* G_OBJECT (self),
|
||||||
|
* baker_bake_cake_async),
|
||||||
|
* NULL);
|
||||||
|
*
|
||||||
|
* simple = (GSimpleAsyncResult *) result;
|
||||||
|
*
|
||||||
|
* if (g_simple_async_result_propagate_error (simple, error))
|
||||||
|
* return NULL;
|
||||||
|
*
|
||||||
|
* cake = CAKE (g_simple_async_result_get_op_res_gpointer (simple));
|
||||||
|
* return g_object_ref (cake);
|
||||||
|
* }
|
||||||
|
* ]|
|
||||||
|
*/
|
||||||
|
|
||||||
static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface);
|
static void g_simple_async_result_async_result_iface_init (GAsyncResultIface *iface);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user