[gtk+/wip/cssvalue: 153/164] stylecontext: Make StyleData refcounted
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/cssvalue: 153/164] stylecontext: Make StyleData refcounted
- Date: Wed, 11 Apr 2012 14:52:46 +0000 (UTC)
commit bf264056d3e908df30d92b8e206f9195cbba9151
Author: Benjamin Otte <otte redhat com>
Date: Tue Apr 10 23:24:41 2012 +0200
stylecontext: Make StyleData refcounted
This is needed for animations where we want to keep a custom StyleData
for animations.
gtk/gtkstylecontext.c | 120 ++++++++++++++++++++++++++++++------------------
1 files changed, 75 insertions(+), 45 deletions(-)
---
diff --git a/gtk/gtkstylecontext.c b/gtk/gtkstylecontext.c
index 065107c..4b18a23 100644
--- a/gtk/gtkstylecontext.c
+++ b/gtk/gtkstylecontext.c
@@ -342,6 +342,7 @@ struct StyleData
{
GtkCssComputedValues *store;
GArray *property_cache;
+ guint ref_count;
};
struct _GtkStyleContextPrivate
@@ -465,6 +466,59 @@ gtk_style_context_class_init (GtkStyleContextClass *klass)
g_type_class_add_private (object_class, sizeof (GtkStyleContextPrivate));
}
+static StyleData *
+style_data_new (void)
+{
+ StyleData *data;
+
+ data = g_slice_new0 (StyleData);
+ data->ref_count = 1;
+
+ return data;
+}
+
+static void
+clear_property_cache (StyleData *data)
+{
+ guint i;
+
+ if (!data->property_cache)
+ return;
+
+ for (i = 0; i < data->property_cache->len; i++)
+ {
+ PropertyValue *node = &g_array_index (data->property_cache, PropertyValue, i);
+
+ g_param_spec_unref (node->pspec);
+ g_value_unset (&node->value);
+ }
+
+ g_array_free (data->property_cache, TRUE);
+ data->property_cache = NULL;
+}
+
+static StyleData *
+style_data_ref (StyleData *style_data)
+{
+ style_data->ref_count++;
+
+ return style_data;
+}
+
+static void
+style_data_unref (StyleData *data)
+{
+ data->ref_count--;
+
+ if (data->ref_count > 0)
+ return;
+
+ g_object_unref (data->store);
+ clear_property_cache (data);
+
+ g_slice_free (StyleData, data);
+}
+
static GtkStyleInfo *
style_info_new (void)
{
@@ -480,6 +534,8 @@ style_info_new (void)
static void
style_info_free (GtkStyleInfo *info)
{
+ if (info->data)
+ style_data_unref (info->data);
g_array_free (info->style_classes, TRUE);
g_array_free (info->regions, TRUE);
g_slice_free (GtkStyleInfo, info);
@@ -501,7 +557,8 @@ style_info_copy (const GtkStyleInfo *info)
copy->junction_sides = info->junction_sides;
copy->state_flags = info->state_flags;
- copy->data = info->data;
+ if (info->data)
+ copy->data = style_data_ref (info->data);
return copy;
}
@@ -567,45 +624,6 @@ style_info_equal (gconstpointer elem1,
return TRUE;
}
-static StyleData *
-style_data_new (void)
-{
- StyleData *data;
-
- data = g_slice_new0 (StyleData);
-
- return data;
-}
-
-static void
-clear_property_cache (StyleData *data)
-{
- guint i;
-
- if (!data->property_cache)
- return;
-
- for (i = 0; i < data->property_cache->len; i++)
- {
- PropertyValue *node = &g_array_index (data->property_cache, PropertyValue, i);
-
- g_param_spec_unref (node->pspec);
- g_value_unset (&node->value);
- }
-
- g_array_free (data->property_cache, TRUE);
- data->property_cache = NULL;
-}
-
-static void
-style_data_free (StyleData *data)
-{
- g_object_unref (data->store);
- clear_property_cache (data);
-
- g_slice_free (StyleData, data);
-}
-
static void
gtk_style_context_cascade_changed (GtkStyleCascade *cascade,
GtkStyleContext *context)
@@ -665,7 +683,7 @@ gtk_style_context_init (GtkStyleContext *style_context)
priv->style_data = g_hash_table_new_full (style_info_hash,
style_info_equal,
(GDestroyNotify) style_info_free,
- (GDestroyNotify) style_data_free);
+ (GDestroyNotify) style_data_unref);
priv->direction = GTK_TEXT_DIR_LTR;
@@ -922,7 +940,11 @@ style_data_lookup (GtkStyleContext *context)
info->data = g_hash_table_lookup (priv->style_data, info);
- if (!info->data)
+ if (info->data)
+ {
+ style_data_ref (info->data);
+ }
+ else
{
GtkWidgetPath *path;
@@ -931,7 +953,7 @@ style_data_lookup (GtkStyleContext *context)
info->data = style_data_new ();
g_hash_table_insert (priv->style_data,
style_info_copy (info),
- info->data);
+ style_data_ref (info->data));
build_properties (context, info->data, path, info->state_flags);
@@ -983,7 +1005,11 @@ gtk_style_context_queue_invalidate_internal (GtkStyleContext *context,
if (gtk_style_context_is_saved (context))
{
- info->data = NULL;
+ if (info->data)
+ {
+ style_data_unref (info->data);
+ info->data = NULL;
+ }
}
else
{
@@ -2892,7 +2918,11 @@ gtk_style_context_clear_cache (GtkStyleContext *context)
for (list = priv->info_stack; list; list = list->next)
{
GtkStyleInfo *info = list->data;
- info->data = NULL;
+ if (info->data)
+ {
+ style_data_unref (info->data);
+ info->data = NULL;
+ }
}
g_hash_table_remove_all (priv->style_data);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]