[gegl/meta-json: 12/18] meta-json: Can forward property changes
- From: Jon Nordby <jonnor src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gegl/meta-json: 12/18] meta-json: Can forward property changes
- Date: Mon, 19 Jan 2015 23:52:54 +0000 (UTC)
commit 129da204c97bec3466239cbc2fd964df23815417
Author: Jon Nordby <jononor gmail com>
Date: Mon Jan 19 22:08:22 2015 +0100
meta-json: Can forward property changes
operations/core/json.c | 171 ++++++++++++++++++++++++++++++++++++++---------
1 files changed, 138 insertions(+), 33 deletions(-)
---
diff --git a/operations/core/json.c b/operations/core/json.c
index a912308..593af7d 100644
--- a/operations/core/json.c
+++ b/operations/core/json.c
@@ -44,15 +44,38 @@ typedef struct _JsonOp
{
GeglOperationMetaJson parent_instance;
JsonObject *json_root;
- GHashTable *nodes;
+ GHashTable *nodes; // gchar* -> GeglNode *, owned by parent node
} JsonOp;
typedef struct
{
GeglOperationMetaJsonClass parent_class;
JsonObject *json_root;
+ 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?
/*
@@ -113,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,};
@@ -133,7 +156,37 @@ set_prop(GeglNode *t, const gchar *port, GParamSpec *paramspec, GValue *value)
return FALSE;
}
-static void
+static GParamSpec *
+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, 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, 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, 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, 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, flags);
+ } else {
+ g_critical("json: Unknown param spec type");
+ }
+ return out;
+}
+
+static guint
install_properties(JsonOpClass *json_op_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (json_op_class);
@@ -152,14 +205,29 @@ install_properties(JsonOpClass *json_op_class)
JsonObject *conn = json_object_get_object_member(inports, name);
const gchar *proc = json_object_get_string_member(conn, "process");
const gchar *port = json_object_get_string_member(conn, "port");
- GParamSpec *spec = NULL;
-
- g_print("adding property %s, pointing to %s %s\n", name, port, proc);
-
- // TODO: look up property on the class/op the port points to and use that paramspec
- spec = g_param_spec_int (name, name, "DUMMY description", 0, 1000, 1,
- (GParamFlags) (G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
GEGL_PARAM_PAD_INPUT));
- g_object_class_install_property (object_class, prop++, spec);
+ JsonObject *processes = json_object_get_object_member(root, "processes");
+ JsonObject *p = json_object_get_object_member(processes, proc);
+ const gchar *component = json_object_get_string_member(p, "component");
+
+ {
+ GParamSpec *target_spec = NULL;
+ gchar *opname = component2geglop(component);
+ // HACK: should avoid instantiating node to determine prop
+ GeglNode *n = gegl_node_new();
+ g_assert(n);
+ gegl_node_set(n, "operation", opname, NULL);
+ target_spec = gegl_node_find_property(n, port);
+ if (target_spec) {
+ GParamSpec *spec = copy_param_spec(target_spec, name);
+ 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);
+ }
}
}
@@ -176,7 +244,7 @@ install_properties(JsonOpClass *json_op_class)
}
}
*/
-
+ return prop-1;
}
static GObject *
@@ -193,19 +261,28 @@ constructor (GType type,
return obj;
}
-
static void
get_property (GObject *gobject,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
- switch (property_id)
- {
- default:
-// G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
- break;
+ JsonOpClass * json_op_class = (JsonOpClass *)G_OBJECT_GET_CLASS(gobject);
+ JsonOp * self = (JsonOp *)(gobject);
+
+ 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
@@ -214,12 +291,23 @@ set_property (GObject *gobject,
const GValue *value,
GParamSpec *pspec)
{
- switch (property_id)
- {
- default:
-// G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, property_id, pspec);
- break;
+ JsonOpClass * json_op_class = (JsonOpClass *)G_OBJECT_GET_CLASS(gobject);
+ JsonOp * self = (JsonOp *)(gobject);
+ 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
@@ -241,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);
}
@@ -333,6 +422,23 @@ attach (GeglOperation *operation)
}
static void
+json_op_init (JsonOp *self)
+{
+ 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(gobject);
+
+ g_hash_table_unref (self->nodes);
+
+// FIXME: causes infinite loop GEGL_OPERATION_CLASS(json_op_class)->finalize(gobject);
+}
+
+static void
json_op_class_init (gpointer klass, gpointer class_data)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -343,14 +449,17 @@ json_op_class_init (gpointer klass, gpointer class_data)
object_class->set_property = set_property;
object_class->get_property = get_property;
object_class->constructor = constructor;
+ object_class->finalize = finalize;
operation_class->attach = attach;
+ 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,
- "name", "gegl:dropshadow2",
+ "name", "gegl:greyy",
"categories", "effects:light",
"description", "Creates a dropshadow effect on the input buffer",
NULL);
@@ -360,15 +469,10 @@ json_op_class_init (gpointer klass, gpointer class_data)
static void
json_op_class_finalize (JsonOpClass *self)
{
-}
-
-
-static void
-json_op_init (JsonOp *self)
-{
- self->nodes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); // FIXME: free
+ g_hash_table_unref(self->properties);
}
+
static GType
json_op_register_type (GTypeModule *type_module, const gchar *name, gpointer klass_data)
{
@@ -408,7 +512,7 @@ json_op_register_type_for_file (GTypeModule *type_module, const gchar *filepath)
g_assert(root_node);
g_print("%s: %p\n", __PRETTY_FUNCTION__, root_node);
// FIXME: unhardoce name, look up in json structure, fallback to basename
- ret = json_op_register_type(type_module, "dropshadow_json", root);
+ ret = json_op_register_type(type_module, "grey_json", root);
}
// g_object_unref(parser);
@@ -421,7 +525,8 @@ static void
json_register_operations(GTypeModule *module)
{
// FIXME: unhardcode, follow GEGL_PATH properly
- json_op_register_type_for_file (module, JSON_OP_DIR "/dropshadow2.json");
+// json_op_register_type_for_file (module, JSON_OP_DIR "/dropshadow2.json");
+ json_op_register_type_for_file (module, JSON_OP_DIR "/grey2.json");
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]