[gtk/wip/otte/listview: 42/199] expression: Add GtkObjectExpression



commit 0e3087ce67b55bf79ad66e58b0e41b2529f34027
Author: Benjamin Otte <otte redhat com>
Date:   Tue Nov 26 18:59:34 2019 +0100

    expression: Add GtkObjectExpression
    
    Weak refs break cycles...

 gtk/gtkexpression.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkexpression.h |  2 ++
 2 files changed, 81 insertions(+)
---
diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c
index 4aaf575ef2..4ec4e0066a 100644
--- a/gtk/gtkexpression.c
+++ b/gtk/gtkexpression.c
@@ -208,6 +208,85 @@ gtk_constant_expression_new_for_value (const GValue *value)
   return (GtkExpression *) result;
 }
 
+/*** OBJECT ***/
+
+typedef struct _GtkObjectExpression GtkObjectExpression;
+
+struct _GtkObjectExpression
+{
+  GtkExpression parent;
+
+  GObject *object;
+};
+
+static void
+gtk_object_expression_weak_ref_cb (gpointer  data,
+                                   GObject  *object)
+{
+  GtkObjectExpression *self = (GtkObjectExpression *) data;
+
+  self->object = NULL;
+}
+
+static void
+gtk_object_expression_finalize (GtkExpression *expr)
+{
+  GtkObjectExpression *self = (GtkObjectExpression *) expr;
+
+  if (self->object)
+    g_object_weak_unref (self->object, gtk_object_expression_weak_ref_cb, self);
+}
+
+static gboolean
+gtk_object_expression_evaluate (GtkExpression *expr,
+                                gpointer       this,
+                                GValue        *value)
+{
+  GtkObjectExpression *self = (GtkObjectExpression *) expr;
+
+  if (self->object == NULL)
+    return FALSE;
+
+  g_value_init (value, gtk_expression_get_value_type (expr));
+  g_value_set_object (value, self->object);
+  return TRUE;
+}
+
+static const GtkExpressionClass GTK_OBJECT_EXPRESSION_CLASS =
+{
+  sizeof (GtkObjectExpression),
+  "GtkObjectExpression",
+  gtk_object_expression_finalize,
+  gtk_object_expression_evaluate
+};
+
+/**
+ * gtk_object_expression_new:
+ * @object: (transfer none): object to watch
+ *
+ * Creates an expression evaluating to the given @object with a weak reference.
+ * Once the @object is disposed, it will fail to evaluate.
+ * This expression is meant to break reference cycles.
+ *
+ * If you want to keep a reference to @object, use gtk_constant_expression_new().
+ *
+ * Returns: a new #GtkExpression
+ **/
+GtkExpression *
+gtk_object_expression_new (GObject *object)
+{
+  GtkObjectExpression *result;
+
+  g_return_val_if_fail (G_IS_OBJECT (object), NULL);
+
+  result = gtk_expression_alloc (&GTK_OBJECT_EXPRESSION_CLASS, G_OBJECT_TYPE (object));
+
+  result->object = object;
+  g_object_weak_ref (object, gtk_object_expression_weak_ref_cb, result);
+
+  return (GtkExpression *) result;
+}
+
 /*** PROPERTY ***/
 
 typedef struct _GtkPropertyExpression GtkPropertyExpression;
diff --git a/gtk/gtkexpression.h b/gtk/gtkexpression.h
index c65cba336a..22d2f9fc22 100644
--- a/gtk/gtkexpression.h
+++ b/gtk/gtkexpression.h
@@ -55,6 +55,8 @@ GtkExpression *         gtk_constant_expression_new             (GType
 GDK_AVAILABLE_IN_ALL
 GtkExpression *         gtk_constant_expression_new_for_value   (const GValue                   *value);     
                      
 GDK_AVAILABLE_IN_ALL
+GtkExpression *         gtk_object_expression_new               (GObject                        *object);
+GDK_AVAILABLE_IN_ALL
 GtkExpression *         gtk_closure_expression_new              (GType                           value_type,
                                                                  GClosure                       *closure,
                                                                  guint                           n_params,


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