[glib] Add examples for GAsyncInitiable and GSimpleAsyncResult



commit 28a4fff7ec63000238c7e20ff965238027922c47
Author: Will Thompson <will willthompson co uk>
Date:   Fri Aug 13 23:34:44 2010 -0400

    Add examples for GAsyncInitiable and GSimpleAsyncResult
    
    Bug 602417

 gio/gasyncinitable.c     |   94 +++++++++++++++++++++++++++++++++++++++++
 gio/gsimpleasyncresult.c |  104 +++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 197 insertions(+), 1 deletions(-)
---
diff --git a/gio/gasyncinitable.c b/gio/gasyncinitable.c
index aa13fe5..2e8a16a 100644
--- a/gio/gasyncinitable.c
+++ b/gio/gasyncinitable.c
@@ -45,6 +45,100 @@
  * 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
  * 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,
diff --git a/gio/gsimpleasyncresult.c b/gio/gsimpleasyncresult.c
index eb47118..b76a54e 100644
--- a/gio/gsimpleasyncresult.c
+++ b/gio/gsimpleasyncresult.c
@@ -109,7 +109,109 @@
  * g_simple_async_result_get_op_res_gssize() are
  * provided, getting the operation's result as a gpointer, gboolean, and
  * 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)
+ * {
+ *   /&ast; In this example, this callback is not given a reference to the cake, so
+ *    &ast; the GSimpleAsyncResult has to take a reference to it.
+ *    &ast;/
+ *   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);
+ *
+ *
+ *   /&ast; In this example, we assume that baked_cb is called as a callback from
+ *    &ast; the mainloop, so it's safe to complete the operation synchronously here.
+ *    &ast; If, however, _baker_prepare_cake () might call its callback without
+ *    &ast; first returning to the mainloop â?? inadvisable, but some APIs do so â??
+ *    &ast; we would need to use g_simple_async_result_complete_in_idle().
+ *    &ast;/
+ *   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);
+ *       /&ast; Drop the reference returned by _baker_get_cached_cake(); the
+ *        &ast; GSimpleAsyncResult has taken its own reference.
+ *        &ast;/
+ *       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);
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]