[libpeas/proxys] [Seed] Add out args support in Seed plugins



commit eb7bb6e6b87ec815bdecb9a396ba126445accc1a
Author: Steve Frécinaux <code istique net>
Date:   Sun May 23 15:48:13 2010 +0200

    [Seed] Add out args support in Seed plugins
    
    Seed plugins can now have PeasUIConfigurable support.
    It is not sure at all that our mapping between C and JS prototypes is
    conform to the way Seed does it.

 loaders/seed/peas-extension-seed.c       |  154 ++++++++++++++++++++++++++++--
 peas-demo/plugins/seedhello/seedhello.js |   14 +++
 2 files changed, 158 insertions(+), 10 deletions(-)
---
diff --git a/loaders/seed/peas-extension-seed.c b/loaders/seed/peas-extension-seed.c
index d01e7c5..924546b 100644
--- a/loaders/seed/peas-extension-seed.c
+++ b/loaders/seed/peas-extension-seed.c
@@ -32,6 +32,11 @@ enum {
   PROP_JS_OBJECT,
 };
 
+typedef struct {
+  GITypeInfo *type_info;
+  gpointer ptr;
+} OutArg;
+
 static void
 peas_extension_seed_init (PeasExtensionSeed *sexten)
 {
@@ -156,6 +161,105 @@ read_next_argument (SeedContext ctx,
     }
 }
 
+static void
+set_return_value (OutArg        *arg,
+                  SeedContext    ctx,
+                  SeedValue      value,
+                  SeedException *exc)
+{
+  g_debug (G_STRFUNC);
+  switch (g_type_info_get_tag (arg->type_info))
+    {
+    case GI_TYPE_TAG_BOOLEAN:
+      *((gboolean *) arg->ptr) = seed_value_to_boolean (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_INT8:
+      *((gint8 *) arg->ptr) = seed_value_to_int (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_UINT8:
+      *((guint8 *) arg->ptr) = seed_value_to_uint (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_INT16:
+      *((gint16 *) arg->ptr) = seed_value_to_int (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_UINT16:
+      *((guint16 *) arg->ptr) = seed_value_to_uint (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_INT32:
+      *((gint32 *) arg->ptr) = seed_value_to_long (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_UINT32:
+      *((guint32 *) arg->ptr) = seed_value_to_ulong (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_INT64:
+      *((gint64 *) arg->ptr) = seed_value_to_int64 (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_UINT64:
+      *((guint64 *) arg->ptr) = seed_value_to_uint64 (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_SHORT:
+      *((gshort *) arg->ptr) = seed_value_to_int (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_USHORT:
+      *((gushort *) arg->ptr) = seed_value_to_uint (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_INT:
+      *((gint *) arg->ptr) = seed_value_to_int (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_UINT:
+      *((guint *) arg->ptr) = seed_value_to_uint (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_LONG:
+      *((glong *) arg->ptr) = seed_value_to_long (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_ULONG:
+      *((gulong *) arg->ptr) = seed_value_to_ulong (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_FLOAT:
+      *((gfloat *) arg->ptr) = seed_value_to_float (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_DOUBLE:
+      *((gdouble *) arg->ptr) = seed_value_to_double (ctx, value, exc);
+      break;
+
+    case GI_TYPE_TAG_SSIZE:
+      *((gssize *) arg->ptr) = seed_value_to_ulong (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_SIZE:
+      *((gsize *) arg->ptr) = seed_value_to_long (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_TIME_T:
+      *((time_t *) arg->ptr) = seed_value_to_int64 (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_GTYPE:
+      /* apparently, GType is meant to be a gsize, from gobject/gtype.h in glib */
+      *((GType *) arg->ptr) = seed_value_to_ulong (ctx, value, exc);
+      break;
+
+    case GI_TYPE_TAG_UTF8:
+      *((gchar **) arg->ptr) = seed_value_to_string (ctx, value, exc);
+      break;
+    case GI_TYPE_TAG_FILENAME:
+      *((gchar **) arg->ptr) = seed_value_to_filename (ctx, value, exc);
+      break;
+
+    case GI_TYPE_TAG_INTERFACE:
+      *((GObject **) arg->ptr) = seed_value_to_object (ctx, value, exc);
+      break;
+
+    /* FIXME */
+    case GI_TYPE_TAG_ARRAY:
+    case GI_TYPE_TAG_GLIST:
+    case GI_TYPE_TAG_GSLIST:
+    case GI_TYPE_TAG_GHASH:
+    case GI_TYPE_TAG_ERROR:
+      *((gpointer *) arg->ptr) = NULL;
+
+    default:
+      g_return_if_reached ();
+    }
+}
+
 static gboolean
 peas_extension_seed_call (PeasExtension *exten,
                           const gchar   *method_name,
@@ -166,6 +270,8 @@ peas_extension_seed_call (PeasExtension *exten,
   GICallableInfo *func_info;
   guint n_args, n_in_args, n_out_args, i;
   SeedValue *js_in_args;
+  OutArg *out_args;
+  SeedValue js_ret, val;
   SeedException exc = NULL;
   gchar *exc_string;
 
@@ -198,6 +304,7 @@ peas_extension_seed_call (PeasExtension *exten,
   n_out_args = 0;
 
   js_in_args = g_new0 (SeedValue, n_args);
+  out_args = g_new0 (OutArg, n_args);
 
   for (i = 0; i < n_args && exc == NULL; i++)
     {
@@ -215,29 +322,56 @@ peas_extension_seed_call (PeasExtension *exten,
                                                             arg_type_info,
                                                             &exc);
           break;
+        case GI_DIRECTION_OUT:
+          out_args[n_out_args].ptr = va_arg (args, gpointer);
+          out_args[n_out_args].type_info = arg_type_info;
+          g_base_info_ref ((GIBaseInfo *) arg_type_info);
+          n_out_args++;
+          break;
         default:
           seed_make_exception (sexten->js_context,
                                &exc,
                                "dir_not_supported",
-                               "Argument direction '%s' not supported yet",
-                               g_arg_info_get_direction (arg_info) == GI_DIRECTION_OUT ? "out" : "inout");
+                               "Argument direction 'inout' not supported yet");
           break;
         }
 
       g_base_info_unref ((GIBaseInfo *) arg_type_info);
       g_base_info_unref ((GIBaseInfo *) arg_info);
     }
-
-  if (exc == NULL)
+  if (exc != NULL)
+    goto cleanup;
+
+  js_ret = seed_object_call (sexten->js_context,
+                             js_method,
+                             sexten->js_object,
+                             n_in_args,
+                             js_in_args,
+                             &exc);
+  if (exc != NULL)
+    goto cleanup;
+
+  switch (n_out_args)
     {
-      seed_object_call (sexten->js_context,
-                        js_method,
-                        sexten->js_object,
-                        n_in_args,
-                        js_in_args,
-                        &exc);
+    case 0:
+      break;
+    case 1:
+      set_return_value (&out_args[0], sexten->js_context, js_ret, exc);
+      break;
+    default:
+      if (seed_value_is_object (sexten->js_context, js_ret))
+        for (i = 0; i < n_out_args && exc == NULL; i++)
+          {
+            val = seed_object_get_property_at_index (sexten->js_context, js_ret, i, exc);
+            if (exc == NULL)
+              set_return_value (&out_args[i], sexten->js_context, val, exc);
+          }
     }
 
+cleanup:
+  for (i = 0; i < n_out_args; i++)
+    g_base_info_unref ((GIBaseInfo *) out_args[i].type_info);
+  g_free (out_args);
   g_free (js_in_args);
   g_base_info_unref ((GIBaseInfo *) func_info);
 
diff --git a/peas-demo/plugins/seedhello/seedhello.js b/peas-demo/plugins/seedhello/seedhello.js
index d19e6d7..8484fdd 100644
--- a/peas-demo/plugins/seedhello/seedhello.js
+++ b/peas-demo/plugins/seedhello/seedhello.js
@@ -22,6 +22,20 @@ activatable_extension = {
 };
 
 configurable_extension = {
+  create_configure_dialog: function () {
+    var dialog = new Gtk.Dialog({ title: "Seedhello Config Dialog" });
+    var label = new Gtk.Label({ label: "Example of configuration dialog for a Seed plugin" });
+
+    dialog.get_content_area().pack_start(label);
+    dialog.add_button(Gtk.STOCK_OK, 1);
+
+    dialog.signal.response.connect(function (w, response_id) {
+      print("Dialog button clicked");
+      dialog.destroy();
+    });
+
+    return dialog;
+  }
 };
 
 extensions = {



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