[libpeas] Fix getting and setting Seed properties



commit 2893558d550391f26bf231aa9a6a35e2a29462dd
Author: Garrett Regier <alias301 gmail com>
Date:   Thu Mar 10 05:11:52 2011 -0800

    Fix getting and setting Seed properties

 libpeas/peas-extension-subclasses.c                |   29 ++----
 libpeas/peas-extension.c                           |    2 +-
 libpeas/peas-extension.h                           |    1 -
 loaders/c/peas-extension-c.c                       |   33 ++++++-
 loaders/python/peas-extension-python.c             |   47 +++++++++-
 loaders/seed/peas-extension-seed.c                 |  100 +++++++++++++++++++-
 loaders/seed/peas-plugin-loader-seed.c             |    4 +-
 tests/libpeas/extension-seed.c                     |    4 -
 .../plugins/extension-seed/extension-seed.js       |    5 +-
 9 files changed, 189 insertions(+), 36 deletions(-)
---
diff --git a/libpeas/peas-extension-subclasses.c b/libpeas/peas-extension-subclasses.c
index 0a4601a..97e7f73 100644
--- a/libpeas/peas-extension-subclasses.c
+++ b/libpeas/peas-extension-subclasses.c
@@ -215,6 +215,12 @@ implement_interface_methods (gpointer iface,
            g_type_name (exten_type), g_type_name (proxy_type));
 }
 
+static gpointer
+get_parent_class (GObject *object)
+{
+  return g_type_class_peek (g_type_parent (G_TYPE_FROM_INSTANCE (object)));
+}
+
 static void
 extension_subclass_set_property (GObject      *object,
                                  guint         prop_id,
@@ -222,8 +228,6 @@ extension_subclass_set_property (GObject      *object,
                                  GParamSpec   *pspec)
 {
   PeasExtension *exten = PEAS_EXTENSION (object);
-  GIArgument args[2];
-  GIArgument return_value;
 
   /* This will have already been set on the real instance */
   if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) != 0)
@@ -237,13 +241,8 @@ extension_subclass_set_property (GObject      *object,
            G_OBJECT_TYPE_NAME (object),
            g_param_spec_get_name (pspec));
 
-  args[0].v_string = (gchar *) g_param_spec_get_name (pspec);
-  args[1].v_pointer = (gpointer) value;
-
-  PEAS_EXTENSION_GET_CLASS (object)->call (exten,
-                                           G_TYPE_OBJECT,
-                                           "set_property",
-                                           args, &return_value);
+  G_OBJECT_CLASS (get_parent_class (object))->set_property (object, prop_id,
+                                                            value, pspec);
 }
 
 static void
@@ -252,20 +251,12 @@ extension_subclass_get_property (GObject    *object,
                                  GValue     *value,
                                  GParamSpec *pspec)
 {
-  GIArgument args[2];
-  GIArgument return_value;
-
   g_debug ("Getting '%s:%s'",
            G_OBJECT_TYPE_NAME (object),
            g_param_spec_get_name (pspec));
 
-  args[0].v_string = (gchar *) g_param_spec_get_name (pspec);
-  args[1].v_pointer = value;
-
-  PEAS_EXTENSION_GET_CLASS (object)->call (PEAS_EXTENSION (object),
-                                           G_TYPE_OBJECT,
-                                           "get_property",
-                                           args, &return_value);
+  G_OBJECT_CLASS (get_parent_class (object))->get_property (object, prop_id,
+                                                            value, pspec);
 }
 
 static void
diff --git a/libpeas/peas-extension.c b/libpeas/peas-extension.c
index 7392766..f60d985 100644
--- a/libpeas/peas-extension.c
+++ b/libpeas/peas-extension.c
@@ -290,5 +290,5 @@ peas_extension_callv (PeasExtension *exten,
   g_return_val_if_fail (method_name != NULL, FALSE);
 
   klass = PEAS_EXTENSION_GET_CLASS (exten);
-  return klass->call (exten, G_TYPE_INVALID, method_name, args, return_value);
+  return klass->call (exten, method_name, args, return_value);
 }
diff --git a/libpeas/peas-extension.h b/libpeas/peas-extension.h
index 4245801..c1f3a56 100644
--- a/libpeas/peas-extension.h
+++ b/libpeas/peas-extension.h
@@ -66,7 +66,6 @@ struct _PeasExtensionClass {
 
   /*< private >*/
   gboolean   (*call)                      (PeasExtension  *exten,
-                                           GType           gtype,
                                            const gchar    *method,
                                            GIArgument     *args,
                                            GIArgument     *return_value);
diff --git a/loaders/c/peas-extension-c.c b/loaders/c/peas-extension-c.c
index 4344e9d..319738b 100644
--- a/loaders/c/peas-extension-c.c
+++ b/loaders/c/peas-extension-c.c
@@ -37,20 +37,45 @@ peas_extension_c_init (PeasExtensionC *cexten)
 
 static gboolean
 peas_extension_c_call (PeasExtension *exten,
-                       GType          gtype,
                        const gchar   *method_name,
                        GIArgument    *args,
                        GIArgument    *retval)
 {
   PeasExtensionC *cexten = PEAS_EXTENSION_C (exten);
+  GType gtype;
 
-  if (gtype == G_TYPE_INVALID)
-    gtype = peas_extension_get_extension_type (exten);
+  gtype = peas_extension_get_extension_type (exten);
 
   return peas_method_apply (cexten->instance, gtype, method_name, args, retval);
 }
 
 static void
+peas_extension_c_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  PeasExtensionC *cexten = PEAS_EXTENSION_C (object);
+
+  /* Don't add properties as they could shadow the instance's */
+
+  g_object_set_property (cexten->instance, pspec->name, value);
+}
+
+static void
+peas_extension_c_get_property (GObject      *object,
+                               guint         prop_id,
+                               GValue       *value,
+                               GParamSpec   *pspec)
+{
+  PeasExtensionC *cexten = PEAS_EXTENSION_C (object);
+
+  /* Don't add properties as they could shadow the instance's */
+
+  g_object_get_property (cexten->instance, pspec->name, value);
+}
+
+static void
 peas_extension_c_dispose (GObject *object)
 {
   PeasExtensionC *cexten = PEAS_EXTENSION_C (object);
@@ -71,6 +96,8 @@ peas_extension_c_class_init (PeasExtensionCClass *klass)
   PeasExtensionClass *extension_class = PEAS_EXTENSION_CLASS (klass);
 
   object_class->dispose = peas_extension_c_dispose;
+  object_class->get_property = peas_extension_c_get_property;
+  object_class->set_property = peas_extension_c_set_property;
 
   extension_class->call = peas_extension_c_call;
 }
diff --git a/loaders/python/peas-extension-python.c b/loaders/python/peas-extension-python.c
index 4ee6a65..70ff896 100644
--- a/loaders/python/peas-extension-python.c
+++ b/loaders/python/peas-extension-python.c
@@ -42,18 +42,17 @@ peas_extension_python_init (PeasExtensionPython *pyexten)
 
 static gboolean
 peas_extension_python_call (PeasExtension *exten,
-                            GType          gtype,
                             const gchar   *method_name,
                             GIArgument    *args,
                             GIArgument    *retval)
 {
   PeasExtensionPython *pyexten = PEAS_EXTENSION_PYTHON (exten);
+  GType gtype;
   PyGILState_STATE state;
   GObject *instance;
   gboolean success;
 
-  if (gtype == G_TYPE_INVALID)
-    gtype = peas_extension_get_extension_type (exten);
+  gtype = peas_extension_get_extension_type (exten);
 
   state = pyg_gil_state_ensure ();
 
@@ -65,6 +64,46 @@ peas_extension_python_call (PeasExtension *exten,
 }
 
 static void
+peas_extension_python_set_property (GObject      *object,
+                                    guint         prop_id,
+                                    const GValue *value,
+                                    GParamSpec   *pspec)
+{
+  PeasExtensionPython *pyexten = PEAS_EXTENSION_PYTHON (object);
+  PyGILState_STATE state;
+  GObject *instance;
+
+  /* Don't add properties as they could shadow the instance's */
+
+  state = pyg_gil_state_ensure ();
+
+  instance = pygobject_get (pyexten->instance);
+  g_object_set_property (instance, pspec->name, value);
+
+  pyg_gil_state_release (state);
+}
+
+static void
+peas_extension_python_get_property (GObject      *object,
+                                    guint         prop_id,
+                                    GValue       *value,
+                                    GParamSpec   *pspec)
+{
+  PeasExtensionPython *pyexten = PEAS_EXTENSION_PYTHON (object);
+  PyGILState_STATE state;
+  GObject *instance;
+
+  /* Don't add properties as they could shadow the instance's */
+
+  state = pyg_gil_state_ensure ();
+
+  instance = pygobject_get (pyexten->instance);
+  g_object_get_property (instance, pspec->name, value);
+
+  pyg_gil_state_release (state);
+}
+
+static void
 peas_extension_python_dispose (GObject *object)
 {
   PeasExtensionPython *pyexten = PEAS_EXTENSION_PYTHON (object);
@@ -89,6 +128,8 @@ peas_extension_python_class_init (PeasExtensionPythonClass *klass)
   PeasExtensionClass *extension_class = PEAS_EXTENSION_CLASS (klass);
 
   object_class->dispose = peas_extension_python_dispose;
+  object_class->get_property = peas_extension_python_get_property;
+  object_class->set_property = peas_extension_python_set_property;
 
   extension_class->call = peas_extension_python_call;
 }
diff --git a/loaders/seed/peas-extension-seed.c b/loaders/seed/peas-extension-seed.c
index 27f0a47..4c3b66e 100644
--- a/loaders/seed/peas-extension-seed.c
+++ b/loaders/seed/peas-extension-seed.c
@@ -36,11 +36,104 @@ typedef struct {
 } OutArg;
 
 
+gboolean seed_gvalue_from_seed_value (SeedContext    ctx,
+                                      SeedValue      val,
+                                      GType          type,
+                                      GValue        *gval,
+                                      SeedException *exception);
+
 static void
 peas_extension_seed_init (PeasExtensionSeed *sexten)
 {
 }
 
+static gchar *
+convert_property_name (const gchar *pname)
+{
+  gint i;
+  gchar *prop_name;
+
+  prop_name = g_strdup (pname);
+
+  for (i = 0; prop_name[i] != '\0'; ++i)
+    {
+      if (prop_name[i] == '-')
+        prop_name[i] = '_';
+    }
+
+  return prop_name;
+}
+
+static void
+peas_extension_seed_get_property (GObject    *object,
+                                  guint       prop_id,
+                                  GValue     *value,
+                                  GParamSpec *pspec)
+{
+  PeasExtensionSeed *sexten = PEAS_EXTENSION_SEED (object);
+  SeedValue seed_value;
+  SeedException exc = NULL;
+  gchar *prop_name;
+
+  /* Don't add properties as they could shadow the instance's */
+
+  prop_name = convert_property_name (pspec->name);
+
+  seed_value = seed_object_get_property (sexten->js_context, sexten->js_object,
+                                         prop_name);
+
+  g_free (prop_name);
+
+
+  seed_gvalue_from_seed_value (sexten->js_context, seed_value,
+                               pspec->value_type, value, &exc);
+
+  if (exc != NULL)
+    {
+      gchar *exc_string;
+
+      exc_string = seed_exception_to_string (sexten->js_context, exc);
+      g_warning ("Seed Exception: %s", exc_string);
+
+      g_free (exc_string);
+    }
+}
+
+static void
+peas_extension_seed_set_property (GObject      *object,
+                                  guint         prop_id,
+                                  const GValue *value,
+                                  GParamSpec   *pspec)
+{
+  PeasExtensionSeed *sexten = PEAS_EXTENSION_SEED (object);
+  SeedValue seed_value;
+  SeedException exc = NULL;
+  gchar *prop_name;
+
+  /* Don't add properties as they could shadow the instance's */
+
+  seed_value = seed_value_from_gvalue (sexten->js_context,
+                                       (GValue *) value, &exc);
+
+  if (exc != NULL)
+    {
+      gchar *exc_string;
+
+      exc_string = seed_exception_to_string (sexten->js_context, exc);
+      g_warning ("Seed Exception: %s", exc_string);
+
+      g_free (exc_string);
+      return;
+    }
+
+  prop_name = convert_property_name (pspec->name);
+
+  seed_object_set_property (sexten->js_context, sexten->js_object,
+                            prop_name, seed_value);
+
+  g_free (prop_name);
+}
+
 static void
 peas_extension_seed_dispose (GObject *object)
 {
@@ -196,12 +289,12 @@ set_return_value (OutArg        *arg,
 
 static gboolean
 peas_extension_seed_call (PeasExtension *exten,
-                          GType          exten_type,
                           const gchar   *method_name,
                           GIArgument    *args,
                           GIArgument    *retval)
 {
   PeasExtensionSeed *sexten = PEAS_EXTENSION_SEED (exten);
+  GType exten_type;
   SeedValue js_method;
   GICallableInfo *func_info;
   GITypeInfo *retval_info;
@@ -216,8 +309,7 @@ peas_extension_seed_call (PeasExtension *exten,
   g_return_val_if_fail (sexten->js_context != NULL, FALSE);
   g_return_val_if_fail (sexten->js_object != NULL, FALSE);
 
-  if (exten_type == G_TYPE_INVALID)
-    exten_type = peas_extension_get_extension_type (exten);
+  exten_type = peas_extension_get_extension_type (exten);
 
   /* Fetch the JS method we want to call */
   js_method = seed_object_get_property (sexten->js_context,
@@ -347,6 +439,8 @@ peas_extension_seed_class_init (PeasExtensionSeedClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   PeasExtensionClass *extension_class = PEAS_EXTENSION_CLASS (klass);
 
+  object_class->set_property = peas_extension_seed_set_property;
+  object_class->get_property = peas_extension_seed_get_property;
   object_class->dispose = peas_extension_seed_dispose;
 
   extension_class->call = peas_extension_seed_call;
diff --git a/loaders/seed/peas-plugin-loader-seed.c b/loaders/seed/peas-plugin-loader-seed.c
index 62d6af6..37e2b0a 100644
--- a/loaders/seed/peas-plugin-loader-seed.c
+++ b/loaders/seed/peas-plugin-loader-seed.c
@@ -176,7 +176,9 @@ peas_plugin_loader_seed_create_extension (PeasPluginLoader *loader,
                                 value);
     }
 
-  /* Set the properties as well */
+  /* Set the properties as well, cannot use
+   * g_object_set_property because it may be construct-only
+   */
   for (i = 0; i < n_parameters; i++)
     {
       gchar *key;
diff --git a/tests/libpeas/extension-seed.c b/tests/libpeas/extension-seed.c
index 96d7493..ea4315a 100644
--- a/tests/libpeas/extension-seed.c
+++ b/tests/libpeas/extension-seed.c
@@ -53,14 +53,10 @@ main (int   argc,
   _EXTENSION_TEST (seed, "call-multi-args", call_multi_args);
 #endif
 
-#ifdef SEED_EXTENSION_PROPERTIES_DONT_WORK
-  /* Some tests don't fail when they should */
-
   _EXTENSION_TEST (seed, "properties-construct-only", properties_construct_only);
   _EXTENSION_TEST (seed, "properties-read-only", properties_read_only);
   _EXTENSION_TEST (seed, "properties-write-only", properties_write_only);
   _EXTENSION_TEST (seed, "properties-readwrite", properties_readwrite);
-#endif
 
   return testing_run_tests ();
 }
diff --git a/tests/libpeas/plugins/extension-seed/extension-seed.js b/tests/libpeas/plugins/extension-seed/extension-seed.js
index a50ba75..f69057b 100644
--- a/tests/libpeas/plugins/extension-seed/extension-seed.js
+++ b/tests/libpeas/plugins/extension-seed/extension-seed.js
@@ -12,7 +12,10 @@ callable_extension = {
   }
 };
 
-properties_extension = {};
+properties_extension = {
+  read_only: "read-only",
+  readwrite: "readwrite"
+};
 
 extensions = {
   "IntrospectionCallable": callable_extension,



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