From bd8655fdeeaf864ee12e8a6d99ac060df54ef95a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Tue, 26 Nov 2019 18:59:34 +0100 Subject: expression: Add GtkObjectExpression Weak refs break cycles... --- gtk/gtkexpression.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) (limited to 'gtk/gtkexpression.c') diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c index dbd100c767..d6b0c78206 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 (>K_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; -- cgit v1.2.1