[gegl] Add gegl_operation_meta_watch_node



commit 37363997c9452a884d9f65cf2c7a723607cd6d08
Author: Daniel Sabo <DanielSabo gmail com>
Date:   Sun Feb 2 03:23:46 2014 -0800

    Add gegl_operation_meta_watch_node
    
    Passing nodes to gegl_operation_meta_watch_node or
    gegl_operation_meta_watch_nodes will cause them to
    be removed when the operation is destroyed. This
    prevents the meta operation's children from leaking
    if the root node's operation changes.
    
    The watch holds a weak reference to the watched node,
    so it is also safe to remove them prior to destroying
    the operation.

 gegl/operation/gegl-operation-meta.c |   51 ++++++++++++++++++++++++++++++++++
 gegl/operation/gegl-operation-meta.h |    7 ++++
 2 files changed, 58 insertions(+), 0 deletions(-)
---
diff --git a/gegl/operation/gegl-operation-meta.c b/gegl/operation/gegl-operation-meta.c
index f921e86..942718c 100644
--- a/gegl/operation/gegl-operation-meta.c
+++ b/gegl/operation/gegl-operation-meta.c
@@ -167,6 +167,57 @@ gegl_operation_meta_redirect (GeglOperation *operation,
                                     redirect->internal_name);
 }
 
+typedef struct
+{
+  GeglNode *parent;
+  GeglNode *child;
+} GeglOperationMetaNodeCleanupContext;
+
+static void
+_gegl_operation_meta_node_cleanup (gpointer data,
+                                   GObject *where_the_object_was)
+{
+  GeglOperationMetaNodeCleanupContext *ctx = data;
+
+  if (ctx->child)
+    {
+      g_object_remove_weak_pointer (G_OBJECT (ctx->child), (void**)&ctx->child);
+      gegl_node_remove_child (ctx->parent, ctx->child);
+    }
+
+  g_free (data);
+}
+
+void
+gegl_operation_meta_watch_node (GeglOperation     *operation,
+                                GeglNode          *node)
+{
+  GeglOperationMetaNodeCleanupContext *ctx;
+  ctx = g_new0 (GeglOperationMetaNodeCleanupContext, 1);
+
+  ctx->parent = operation->node;
+  ctx->child  = node;
+
+  g_object_add_weak_pointer (G_OBJECT (ctx->child), (void**)&ctx->child);
+  g_object_weak_ref (G_OBJECT (operation), _gegl_operation_meta_node_cleanup, ctx);
+}
+
+void
+gegl_operation_meta_watch_nodes (GeglOperation     *operation,
+                                 GeglNode          *node,
+                                 ...)
+{
+  va_list var_args;
+
+  va_start (var_args, node);
+  while (node)
+    {
+      gegl_operation_meta_watch_node (operation, node);
+      node = va_arg (var_args, GeglNode *);
+    }
+  va_end (var_args);
+}
+
 void
 gegl_operation_meta_property_changed (GeglOperationMeta *self,
                                       GParamSpec        *pspec,
diff --git a/gegl/operation/gegl-operation-meta.h b/gegl/operation/gegl-operation-meta.h
index 5841145..b0cef20 100644
--- a/gegl/operation/gegl-operation-meta.h
+++ b/gegl/operation/gegl-operation-meta.h
@@ -59,6 +59,13 @@ void  gegl_operation_meta_redirect         (GeglOperation     *operation,
                                             GeglNode          *internal,
                                             const gchar       *internal_name);
 
+void  gegl_operation_meta_watch_node       (GeglOperation     *operation,
+                                            GeglNode          *node);
+
+void  gegl_operation_meta_watch_nodes      (GeglOperation     *operation,
+                                            GeglNode          *node,
+                                            ...) G_GNUC_NULL_TERMINATED;
+
 void  gegl_operation_meta_property_changed (GeglOperationMeta *self,
                                             GParamSpec        *pspec,
                                             gpointer           user_data);


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