[gegl/meta-json] TEMP: can forward property changes



commit 19b6a9acf071a8c21474d413a0adbcd0e7af7ff6
Author: Jon Nordby <jononor gmail com>
Date:   Mon Jan 19 22:08:22 2015 +0100

    TEMP: can forward property changes

 operations/core/json.c           |  114 ++++++++++++++++++++++++--------------
 tests/compositions/grey-json.xml |    2 +-
 2 files changed, 74 insertions(+), 42 deletions(-)
---
diff --git a/operations/core/json.c b/operations/core/json.c
index 9da154b..593af7d 100644
--- a/operations/core/json.c
+++ b/operations/core/json.c
@@ -44,17 +44,38 @@ typedef struct _JsonOp
 {
   GeglOperationMetaJson parent_instance;
   JsonObject *json_root;
-  GHashTable *nodes;
-  GValue *properties;
+  GHashTable *nodes; // gchar* -> GeglNode *, owned by parent node
 } JsonOp;
 
 typedef struct
 {
   GeglOperationMetaJsonClass parent_class;
   JsonObject *json_root;
-  guint no_props;
+  GHashTable *properties; // guint property_id -> PropertyTarget
 } JsonOpClass;
 
+typedef struct
+{
+  gchar *node;
+  gchar *port;
+} PropertyTarget;
+
+PropertyTarget *
+property_target_new(gchar *node, gchar *port)
+{
+    PropertyTarget *self = g_new(PropertyTarget, 1);
+    self->node = node;
+    self->port = port;
+    return self;
+}
+
+void
+property_target_free(PropertyTarget *self)
+{
+    g_free(self->node);
+    g_free(self->port);
+    g_free(self);
+}
 
 // FIXME: needed?
 /*
@@ -115,7 +136,7 @@ gvalue_from_string(GValue *value, GType target_type, GValue *dest_value) {
     return TRUE;
 }
 
-gboolean
+static gboolean
 set_prop(GeglNode *t, const gchar *port, GParamSpec *paramspec, GValue *value)  {
     GType target_type = G_PARAM_SPEC_VALUE_TYPE(paramspec);
     GValue dest_value = {0,};
@@ -141,24 +162,26 @@ copy_param_spec(GParamSpec *in, const gchar *name) {
   const gchar * blurb = g_param_spec_get_blurb(in);
   GParamSpec *out = NULL;
 
+  GParamFlags flags = G_PARAM_READWRITE;
+
   // TODO: handle more things
   if (G_IS_PARAM_SPEC_FLOAT(in)) {
     GParamSpecFloat *f = G_PARAM_SPEC_FLOAT(in);
-    out = g_param_spec_double(name, name, blurb, f->minimum, f->maximum, f->default_value, in->flags);       
+    out = g_param_spec_double(name, name, blurb, f->minimum, f->maximum, f->default_value, flags);
   } else if (G_IS_PARAM_SPEC_DOUBLE(in)) {
     GParamSpecDouble *d = G_PARAM_SPEC_DOUBLE(in);
-    out = g_param_spec_double(name, name, blurb, d->minimum, d->maximum, d->default_value, in->flags);
+    out = g_param_spec_double(name, name, blurb, d->minimum, d->maximum, d->default_value, flags);
   } else if (G_IS_PARAM_SPEC_INT(in)) {
     GParamSpecInt *i = G_PARAM_SPEC_INT(in);
-    out = g_param_spec_int(name, name, blurb, i->minimum, i->maximum, i->default_value, in->flags);
+    out = g_param_spec_int(name, name, blurb, i->minimum, i->maximum, i->default_value, flags);
   } else if (G_IS_PARAM_SPEC_UINT(in)) {
     GParamSpecUInt *u = G_PARAM_SPEC_UINT(in);
-    out = g_param_spec_int(name, name, blurb, u->minimum, u->maximum, u->default_value, in->flags);
+    out = g_param_spec_int(name, name, blurb, u->minimum, u->maximum, u->default_value, flags);
   } else if (G_IS_PARAM_SPEC_LONG(in)) {
     GParamSpecLong *l = G_PARAM_SPEC_LONG(in);
-    out = g_param_spec_int(name, name, blurb, l->minimum, l->maximum, l->default_value, in->flags);
+    out = g_param_spec_int(name, name, blurb, l->minimum, l->maximum, l->default_value, flags);
   } else {
-    g_critical("Unknown param spec type");
+    g_critical("json: Unknown param spec type");
   }
   return out;
 }
@@ -195,11 +218,12 @@ install_properties(JsonOpClass *json_op_class)
               gegl_node_set(n, "operation", opname, NULL);
               target_spec = gegl_node_find_property(n, port);
               if (target_spec) {
-//                GParamSpec *spec = g_param_spec_override (name, target_spec);
-
                 GParamSpec *spec = copy_param_spec(target_spec, name);
-                g_print("adding property %s, pointing to %s %s\n", name, port, proc);              
-                g_object_class_install_property (object_class, prop++, spec);
+                g_print("adding property %s, pointing to %s %s\n", name, port, proc);
+                PropertyTarget *t = property_target_new(g_strdup(proc), g_strdup(port));
+                g_hash_table_insert(json_op_class->properties, GINT_TO_POINTER(prop), t);
+                g_object_class_install_property (object_class, prop, spec);
+                prop++;
               }
               g_object_unref(n);
               g_free(opname);
@@ -237,7 +261,6 @@ constructor (GType                  type,
   return obj;
 }
 
-
 static void
 get_property (GObject      *gobject,
               guint         property_id,
@@ -246,11 +269,20 @@ get_property (GObject      *gobject,
 {
   JsonOpClass * json_op_class = (JsonOpClass *)G_OBJECT_GET_CLASS(gobject);
   JsonOp * self = (JsonOp *)(gobject);
-  if (property_id <= json_op_class->no_props) {
-    g_value_copy (self->properties+property_id, value);
-  } else {
-    G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
+
+  PropertyTarget *target = g_hash_table_lookup(json_op_class->properties, property_id);
+  if (!target) {
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+    return;
   }
+
+  GeglNode *node = g_hash_table_lookup(self->nodes, target->node);  
+  if (!node) {
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+    return;
+  }
+
+  gegl_node_get_property(node, target->port, value);
 }
 
 static void
@@ -261,11 +293,21 @@ set_property (GObject      *gobject,
 {
   JsonOpClass * json_op_class = (JsonOpClass *)G_OBJECT_GET_CLASS(gobject);
   JsonOp * self = (JsonOp *)(gobject);
-  if (property_id <= json_op_class->no_props) {
-    g_value_copy (value, self->properties+property_id);
-  } else {
-    G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
+  g_assert(self);
+
+  PropertyTarget *target = g_hash_table_lookup(json_op_class->properties, property_id);
+  if (!target) {
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+    return;
+  }
+
+  GeglNode *node = g_hash_table_lookup(self->nodes, target->node);  
+  if (!node) {
+    G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
+    return;
   }
+
+  gegl_node_set_property(node, target->port, value);
 }
 
 static void
@@ -287,6 +329,7 @@ attach (GeglOperation *operation)
       g_print("creating node %s with operation %s\n", name, opname);
       GeglNode *node = gegl_node_new_child (gegl, "operation", opname, NULL);
       gegl_operation_meta_watch_node (operation, node);
+      g_assert(node);
       g_hash_table_insert(self->nodes, (gpointer)g_strdup(name), (gpointer)node);
       g_free(opname);
   }
@@ -381,31 +424,18 @@ attach (GeglOperation *operation)
 static void
 json_op_init (JsonOp *self)
 {
-  JsonOpClass *json_op_class = (JsonOpClass *)G_OBJECT_GET_CLASS(self);
-
-  self->nodes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref);
-
-  const guint n = json_op_class->no_props+1;
-  self->properties = g_new(GValue, n);
-  for (int i=0; i<n; ++) {
-    g_value_unset(self->properties+i);
-  }
+  self->nodes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
 }
 
 static void
 finalize (GObject *gobject)
 {
   JsonOp *self = (JsonOp *)(gobject);
-  JsonOpClass *json_op_class = (JsonOpClass *)G_OBJECT_GET_CLASS(self);
+  JsonOpClass *json_op_class = (JsonOpClass *)G_OBJECT_GET_CLASS(gobject);
 
   g_hash_table_unref (self->nodes);
 
-  const guint n = json_op_class->no_props+1;
-  for (int i=0; i<n; ++) {
-    g_value_unset(self->properties+i);
-  }
-
-  G_OBJECT_GET_CLASS(gobject)->finalize (gobject);
+// FIXME: causes infinite loop GEGL_OPERATION_CLASS(json_op_class)->finalize(gobject);
 }
 
 static void
@@ -423,7 +453,9 @@ json_op_class_init (gpointer klass, gpointer class_data)
 
   operation_class->attach = attach;
 
-  json_op_class->no_props = install_properties(json_op_class);
+  json_op_class->properties = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+                                                    NULL, (GDestroyNotify)property_target_free);
+  install_properties(json_op_class);
 
   // FIXME: unharcode, look up in properties
   gegl_operation_class_set_keys (operation_class,
@@ -437,7 +469,7 @@ json_op_class_init (gpointer klass, gpointer class_data)
 static void
 json_op_class_finalize (JsonOpClass *self)
 {
-
+  g_hash_table_unref(self->properties);
 }
 
 
diff --git a/tests/compositions/grey-json.xml b/tests/compositions/grey-json.xml
index 8f8ab41..5968587 100644
--- a/tests/compositions/grey-json.xml
+++ b/tests/compositions/grey-json.xml
@@ -2,7 +2,7 @@
 <gegl>
   <node operation='gegl:greyy'>
     <params>
-      <param name='height'>100</param>
+      <param name='height'>200</param>
       <param name='width'>100</param>
     </params>
   </node>


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