[gtk/css-lookup-caching] Make GtkCssLookupValue refcounted



commit d66a138b68f7b195065985c804c098df07622d1c
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Feb 13 18:47:08 2020 -0500

    Make GtkCssLookupValue refcounted

 gtk/gtkcsslookup.c        | 58 ++++++++++++++++++++++++++++++++++------
 gtk/gtkcsslookupprivate.h | 10 ++++++-
 gtk/gtkcssprovider.c      | 68 +++++++++++++++--------------------------------
 3 files changed, 81 insertions(+), 55 deletions(-)
---
diff --git a/gtk/gtkcsslookup.c b/gtk/gtkcsslookup.c
index 65d8e6d844..e7ae35c52c 100644
--- a/gtk/gtkcsslookup.c
+++ b/gtk/gtkcsslookup.c
@@ -24,6 +24,47 @@
 #include "gtkprivatetypebuiltins.h"
 #include "gtkprivate.h"
 
+GtkCssLookupValue *
+gtk_css_lookup_value_new (guint          id,
+                          GtkCssValue   *value,
+                          GtkCssSection *section)
+{
+  GtkCssLookupValue *v;
+
+  v = g_new0 (GtkCssLookupValue, 1);
+  v->ref_count = 1;
+
+  v->id = id;
+  v->value = _gtk_css_value_ref (value);
+  if (section)
+    v->section = gtk_css_section_ref (section);
+
+  return v;
+}
+
+static void
+gtk_css_lookup_value_free (GtkCssLookupValue *value)
+{
+  _gtk_css_value_unref (value->value);
+  if (value->section)
+    gtk_css_section_unref (value->section);
+  g_free (value);
+}
+
+GtkCssLookupValue *
+gtk_css_lookup_value_ref (GtkCssLookupValue *value)
+{
+  value->ref_count++;
+  return value;
+}
+
+void
+gtk_css_lookup_value_unref (GtkCssLookupValue *value)
+{
+  value->ref_count--;
+  if (value->ref_count == 0)
+    gtk_css_lookup_value_free (value);
+}
 
 GtkCssLookup *
 gtk_css_lookup_new (void)
@@ -78,9 +119,9 @@ gtk_css_lookup_unref (GtkCssLookup *lookup)
  * @lookup does not have a value yet.
  */
 void
-gtk_css_lookup_fill (GtkCssLookup      *lookup,
-                     GtkCssLookupValue *values,
-                     guint              n_values)
+gtk_css_lookup_fill (GtkCssLookup       *lookup,
+                     GtkCssLookupValue **values,
+                     guint               n_values)
 {
   int i, j;
 
@@ -88,7 +129,8 @@ gtk_css_lookup_fill (GtkCssLookup      *lookup,
   gtk_internal_return_if_fail (values != NULL);
 
   if (!lookup->values)
-    lookup->values = g_ptr_array_sized_new (MAX (16, n_values));
+    lookup->values = g_ptr_array_new_full (MAX (16, n_values),
+                                           (GDestroyNotify)gtk_css_lookup_value_unref);
 
   for (i = 0, j = 0; j < n_values; j++, i++)
     {
@@ -97,14 +139,14 @@ gtk_css_lookup_fill (GtkCssLookup      *lookup,
       for (; i < lookup->values->len; i++)
         {
           v =  g_ptr_array_index (lookup->values, i);
-          if (v->id >= values[j].id)
+          if (v->id >= values[j]->id)
             break;
         }
 
-      if (i == lookup->values->len || v->id > values[j].id)
+      if (i == lookup->values->len || v->id > values[j]->id)
         {
-          g_ptr_array_insert (lookup->values, i, &values[j]);
-          lookup->set_values = _gtk_bitmask_set (lookup->set_values, values[j].id, TRUE);
+          g_ptr_array_insert (lookup->values, i, gtk_css_lookup_value_ref (values[j]));
+          lookup->set_values = _gtk_bitmask_set (lookup->set_values, values[j]->id, TRUE);
         }
     }
 }
diff --git a/gtk/gtkcsslookupprivate.h b/gtk/gtkcsslookupprivate.h
index b7113076a4..2b585e3a90 100644
--- a/gtk/gtkcsslookupprivate.h
+++ b/gtk/gtkcsslookupprivate.h
@@ -31,11 +31,19 @@ G_BEGIN_DECLS
 typedef struct _GtkCssLookup GtkCssLookup;
 
 typedef struct {
+  int ref_count;
   guint                id;
   GtkCssValue         *value;
   GtkCssSection       *section;
 } GtkCssLookupValue;
 
+GtkCssLookupValue *      gtk_css_lookup_value_new   (guint          id,
+                                                     GtkCssValue   *value,
+                                                     GtkCssSection *section);
+GtkCssLookupValue *      gtk_css_lookup_value_ref   (GtkCssLookupValue *value);
+void                     gtk_css_lookup_value_unref (GtkCssLookupValue *value);
+
+
 struct _GtkCssLookup {
   int ref_count;
   GtkBitmask *set_values;
@@ -47,7 +55,7 @@ GtkCssLookup *           gtk_css_lookup_ref (GtkCssLookup *lookup);
 void                     gtk_css_lookup_unref (GtkCssLookup *lookup);
 
 void                     gtk_css_lookup_fill                    (GtkCssLookup               *lookup,
-                                                                 GtkCssLookupValue          *values,
+                                                                 GtkCssLookupValue         **values,
                                                                  guint                       n_values);
 GtkCssSection *          gtk_css_lookup_get_section             (GtkCssLookup               *lookup,
                                                                  guint                       id);
diff --git a/gtk/gtkcssprovider.c b/gtk/gtkcssprovider.c
index aa2aa49ba4..1674f07685 100644
--- a/gtk/gtkcssprovider.c
+++ b/gtk/gtkcssprovider.c
@@ -85,7 +85,6 @@ struct _GtkCssProviderClass
 
 typedef struct GtkCssRuleset GtkCssRuleset;
 typedef struct _GtkCssScanner GtkCssScanner;
-typedef GtkCssLookupValue PropertyValue;
 typedef enum ParserScope ParserScope;
 typedef enum ParserSymbol ParserSymbol;
 
@@ -94,9 +93,8 @@ struct GtkCssRuleset
 {
   GtkCssSelector *selector;
   GtkCssSelectorTree *selector_match;
-  PropertyValue *styles;
+  GtkCssLookupValue **styles;
   guint n_styles;
-  guint owns_styles : 1;
 };
 
 struct _GtkCssScanner
@@ -225,30 +223,23 @@ gtk_css_ruleset_init_copy (GtkCssRuleset       *new,
                            GtkCssRuleset       *ruleset,
                            GtkCssSelector      *selector)
 {
+  int i;
+
   memcpy (new, ruleset, sizeof (GtkCssRuleset));
 
   new->selector = selector;
-  /* First copy takes over ownership */
-  if (ruleset->owns_styles)
-    ruleset->owns_styles = FALSE;
+  for (i = 0; i < new->n_styles; i++)
+    gtk_css_lookup_value_ref (new->styles[i]);
 }
 
 static void
 gtk_css_ruleset_clear (GtkCssRuleset *ruleset)
 {
-  if (ruleset->owns_styles)
-    {
-      guint i;
+  int i;
+
+  for (i = 0; i < ruleset->n_styles; i++)
+    gtk_css_lookup_value_unref (ruleset->styles[i]);
 
-      for (i = 0; i < ruleset->n_styles; i++)
-        {
-          _gtk_css_value_unref (ruleset->styles[i].value);
-         ruleset->styles[i].value = NULL;
-         if (ruleset->styles[i].section)
-           gtk_css_section_unref (ruleset->styles[i].section);
-        }
-      g_free (ruleset->styles);
-    }
   if (ruleset->selector)
     _gtk_css_selector_free (ruleset->selector);
 
@@ -264,43 +255,28 @@ gtk_css_ruleset_add (GtkCssRuleset       *ruleset,
   guint i;
   guint id;
 
-  g_return_if_fail (ruleset->owns_styles || ruleset->n_styles == 0);
-
-  ruleset->owns_styles = TRUE;
-
   id = _gtk_css_style_property_get_id (property);
 
   for (i = 0; i < ruleset->n_styles; i++)
     {
-      if (ruleset->styles[i].id > id)
+      if (ruleset->styles[i]->id > id)
         break;
-      if (ruleset->styles[i].id == id)
+      if (ruleset->styles[i]->id == id)
         {
-          _gtk_css_value_unref (ruleset->styles[i].value);
-         ruleset->styles[i].value = NULL;
-         if (ruleset->styles[i].section)
-           gtk_css_section_unref (ruleset->styles[i].section);
-          break;
+          gtk_css_lookup_value_unref (ruleset->styles[i]);
+          ruleset->styles[i] = gtk_css_lookup_value_new (id, value, section);
+          return;
         }
     }
-  if (i == ruleset->n_styles || ruleset->styles[i].id != id)
-    {
-      ruleset->styles = g_realloc (ruleset->styles, (ruleset->n_styles + 1) * sizeof (PropertyValue));
 
-      if (i < ruleset->n_styles)
-        memmove (&ruleset->styles[i + 1], &ruleset->styles[i], (ruleset->n_styles - i) * sizeof 
(PropertyValue));
+  ruleset->styles = g_realloc (ruleset->styles, (ruleset->n_styles + 1) * sizeof (GtkCssLookupValue *));
 
-      ruleset->n_styles++;
+  if (i < ruleset->n_styles)
+    memmove (&ruleset->styles[i + 1], &ruleset->styles[i], (ruleset->n_styles - i) * sizeof 
(GtkCssLookupValue *));
 
-      ruleset->styles[i].value = NULL;
-      ruleset->styles[i].id = id;
-    }
+  ruleset->n_styles++;
 
-  ruleset->styles[i].value = value;
-  if (gtk_keep_css_sections)
-    ruleset->styles[i].section = gtk_css_section_ref (section);
-  else
-    ruleset->styles[i].section = NULL;
+  ruleset->styles[i] = gtk_css_lookup_value_new (id, value, section);
 }
 
 static void
@@ -479,7 +455,7 @@ gtk_css_style_provider_lookup (GtkStyleProvider             *provider,
           if (ruleset->styles == NULL)
             continue;
 
-          gtk_css_lookup_fill (lookup, (GtkCssLookupValue *)ruleset->styles, ruleset->n_styles);
+          gtk_css_lookup_fill (lookup, ruleset->styles, ruleset->n_styles);
         }
 
       g_ptr_array_free (tree_rules, TRUE);
@@ -1386,7 +1362,7 @@ compare_properties (gconstpointer a, gconstpointer b, gpointer style)
 {
   const guint *ua = a;
   const guint *ub = b;
-  PropertyValue *styles = style;
+  GtkCssLookupValue *styles = style;
 
   return strcmp (_gtk_style_property_get_name (GTK_STYLE_PROPERTY (_gtk_css_style_property_lookup_by_id 
(styles[*ua].id))),
                  _gtk_style_property_get_name (GTK_STYLE_PROPERTY (_gtk_css_style_property_lookup_by_id 
(styles[*ub].id))));
@@ -1414,7 +1390,7 @@ gtk_css_ruleset_print (const GtkCssRuleset *ruleset,
 
       for (i = 0; i < ruleset->n_styles; i++)
         {
-          PropertyValue *prop = &ruleset->styles[sorted[i]];
+          GtkCssLookupValue *prop = ruleset->styles[sorted[i]];
           g_string_append (str, "  ");
           g_string_append (str, _gtk_style_property_get_name (GTK_STYLE_PROPERTY 
(_gtk_css_style_property_lookup_by_id (prop->id))));
           g_string_append (str, ": ");


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