mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-11-10 19:00:08 +00:00
css: Speed up name matching
We use the new g_type_get_type_registration_serial() so that we can cache and properly invalidate the result of g_type_from_name(). This bumps the glib requirement to 2.35.3 to get the new function. https://bugzilla.gnome.org/show_bug.cgi?id=689847
This commit is contained in:
parent
089eafb468
commit
a1ee2b7b82
@ -39,7 +39,7 @@ AC_CONFIG_AUX_DIR([build-aux])
|
||||
m4_define([gtk_binary_version], [3.0.0])
|
||||
|
||||
# required versions of other packages
|
||||
m4_define([glib_required_version], [2.35.0])
|
||||
m4_define([glib_required_version], [2.35.3])
|
||||
m4_define([pango_required_version], [1.32.4])
|
||||
m4_define([atk_required_version], [2.5.3])
|
||||
m4_define([cairo_required_version], [1.10.0])
|
||||
|
@ -62,13 +62,11 @@ gtk_css_matcher_widget_path_get_state (const GtkCssMatcher *matcher)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_widget_path_has_name (const GtkCssMatcher *matcher,
|
||||
const char *name)
|
||||
gtk_css_matcher_widget_path_has_type (const GtkCssMatcher *matcher,
|
||||
GType type)
|
||||
{
|
||||
const GtkWidgetPath *siblings;
|
||||
GType type;
|
||||
|
||||
type = g_type_from_name (name);
|
||||
|
||||
siblings = gtk_widget_path_iter_get_siblings (matcher->path.path, matcher->path.index);
|
||||
if (siblings && matcher->path.sibling_index != gtk_widget_path_iter_get_sibling_index (matcher->path.path, matcher->path.index))
|
||||
return g_type_is_a (gtk_widget_path_iter_get_object_type (siblings, matcher->path.sibling_index), type);
|
||||
@ -179,7 +177,7 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_WIDGET_PATH = {
|
||||
gtk_css_matcher_widget_path_get_parent,
|
||||
gtk_css_matcher_widget_path_get_previous,
|
||||
gtk_css_matcher_widget_path_get_state,
|
||||
gtk_css_matcher_widget_path_has_name,
|
||||
gtk_css_matcher_widget_path_has_type,
|
||||
gtk_css_matcher_widget_path_has_class,
|
||||
gtk_css_matcher_widget_path_has_id,
|
||||
gtk_css_matcher_widget_path_has_regions,
|
||||
@ -236,8 +234,8 @@ gtk_css_matcher_any_get_state (const GtkCssMatcher *matcher)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_any_has_name (const GtkCssMatcher *matcher,
|
||||
const char *name)
|
||||
gtk_css_matcher_any_has_type (const GtkCssMatcher *matcher,
|
||||
GType type)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@ -283,7 +281,7 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_ANY = {
|
||||
gtk_css_matcher_any_get_parent,
|
||||
gtk_css_matcher_any_get_previous,
|
||||
gtk_css_matcher_any_get_state,
|
||||
gtk_css_matcher_any_has_name,
|
||||
gtk_css_matcher_any_has_type,
|
||||
gtk_css_matcher_any_has_class,
|
||||
gtk_css_matcher_any_has_id,
|
||||
gtk_css_matcher_any_has_regions,
|
||||
@ -332,11 +330,11 @@ gtk_css_matcher_superset_get_state (const GtkCssMatcher *matcher)
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_matcher_superset_has_name (const GtkCssMatcher *matcher,
|
||||
const char *name)
|
||||
gtk_css_matcher_superset_has_type (const GtkCssMatcher *matcher,
|
||||
GType type)
|
||||
{
|
||||
if (matcher->superset.relevant & GTK_CSS_CHANGE_NAME)
|
||||
return _gtk_css_matcher_has_name (matcher->superset.subset, name);
|
||||
return _gtk_css_matcher_has_type (matcher->superset.subset, type);
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
@ -402,7 +400,7 @@ static const GtkCssMatcherClass GTK_CSS_MATCHER_SUPERSET = {
|
||||
gtk_css_matcher_superset_get_parent,
|
||||
gtk_css_matcher_superset_get_previous,
|
||||
gtk_css_matcher_superset_get_state,
|
||||
gtk_css_matcher_superset_has_name,
|
||||
gtk_css_matcher_superset_has_type,
|
||||
gtk_css_matcher_superset_has_class,
|
||||
gtk_css_matcher_superset_has_id,
|
||||
gtk_css_matcher_superset_has_regions,
|
||||
|
@ -36,8 +36,8 @@ struct _GtkCssMatcherClass {
|
||||
const GtkCssMatcher *next);
|
||||
|
||||
GtkStateFlags (* get_state) (const GtkCssMatcher *matcher);
|
||||
gboolean (* has_name) (const GtkCssMatcher *matcher,
|
||||
const char *name);
|
||||
gboolean (* has_type) (const GtkCssMatcher *matcher,
|
||||
GType type);
|
||||
gboolean (* has_class) (const GtkCssMatcher *matcher,
|
||||
GQuark class_name);
|
||||
gboolean (* has_id) (const GtkCssMatcher *matcher,
|
||||
@ -103,10 +103,10 @@ _gtk_css_matcher_get_state (const GtkCssMatcher *matcher)
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
_gtk_css_matcher_has_name (const GtkCssMatcher *matcher,
|
||||
const char *name)
|
||||
_gtk_css_matcher_has_type (const GtkCssMatcher *matcher,
|
||||
GType type)
|
||||
{
|
||||
return matcher->klass->has_name (matcher, name);
|
||||
return matcher->klass->has_type (matcher, type);
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
|
@ -682,18 +682,74 @@ static const GtkCssSelectorClass GTK_CSS_SELECTOR_ANY = {
|
||||
|
||||
/* NAME */
|
||||
|
||||
typedef struct {
|
||||
GType type;
|
||||
const char *name;
|
||||
} TypeReference;
|
||||
|
||||
static GHashTable *type_refs_ht = NULL;
|
||||
static guint type_refs_last_serial = 0;
|
||||
|
||||
static TypeReference *
|
||||
get_type_reference (const char *name)
|
||||
{
|
||||
TypeReference *ref;
|
||||
|
||||
|
||||
if (type_refs_ht == NULL)
|
||||
type_refs_ht = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
|
||||
ref = g_hash_table_lookup (type_refs_ht, name);
|
||||
|
||||
if (ref != NULL)
|
||||
return ref;
|
||||
|
||||
ref = g_slice_new (TypeReference);
|
||||
ref->name = g_intern_string (name);
|
||||
ref->type = g_type_from_name (ref->name);
|
||||
|
||||
g_hash_table_insert (type_refs_ht,
|
||||
(gpointer)ref->name, ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static void
|
||||
update_type_references (void)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
guint serial;
|
||||
gpointer value;
|
||||
|
||||
serial = g_type_get_type_registration_serial ();
|
||||
|
||||
if (serial == type_refs_last_serial)
|
||||
return;
|
||||
|
||||
type_refs_last_serial = serial;
|
||||
|
||||
g_hash_table_iter_init (&iter, type_refs_ht);
|
||||
while (g_hash_table_iter_next (&iter,
|
||||
NULL, &value))
|
||||
{
|
||||
TypeReference *ref = value;
|
||||
if (ref->type == G_TYPE_INVALID)
|
||||
ref->type = g_type_from_name (ref->name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_css_selector_name_print (const GtkCssSelector *selector,
|
||||
GString *string)
|
||||
{
|
||||
g_string_append (string, selector->data);
|
||||
g_string_append (string, ((TypeReference *)selector->data)->name);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_css_selector_name_match (const GtkCssSelector *selector,
|
||||
const GtkCssMatcher *matcher)
|
||||
{
|
||||
if (!_gtk_css_matcher_has_name (matcher, selector->data))
|
||||
if (!_gtk_css_matcher_has_type (matcher, ((TypeReference *)selector->data)->type))
|
||||
return FALSE;
|
||||
|
||||
return gtk_css_selector_match (gtk_css_selector_previous (selector), matcher);
|
||||
@ -704,7 +760,7 @@ gtk_css_selector_name_tree_match (const GtkCssSelectorTree *tree,
|
||||
const GtkCssMatcher *matcher,
|
||||
GHashTable *res)
|
||||
{
|
||||
if (!_gtk_css_matcher_has_name (matcher, tree->selector.data))
|
||||
if (!_gtk_css_matcher_has_type (matcher, ((TypeReference *)tree->selector.data)->type))
|
||||
return;
|
||||
|
||||
gtk_css_selector_tree_found_match (tree, res);
|
||||
@ -718,7 +774,7 @@ gtk_css_selector_name_tree_get_change (const GtkCssSelectorTree *tree,
|
||||
{
|
||||
GtkCssChange change, previous_change;
|
||||
|
||||
if (!_gtk_css_matcher_has_name (matcher, tree->selector.data))
|
||||
if (!_gtk_css_matcher_has_type (matcher, ((TypeReference *)tree->selector.data)->type))
|
||||
return 0;
|
||||
|
||||
change = 0;
|
||||
@ -745,7 +801,8 @@ static int
|
||||
gtk_css_selector_name_compare_one (const GtkCssSelector *a,
|
||||
const GtkCssSelector *b)
|
||||
{
|
||||
return strcmp (a->data, b->data);
|
||||
return strcmp (((TypeReference *)a->data)->name,
|
||||
((TypeReference *)b->data)->name);
|
||||
}
|
||||
|
||||
static const GtkCssSelectorClass GTK_CSS_SELECTOR_NAME = {
|
||||
@ -1805,11 +1862,14 @@ try_parse_name (GtkCssParser *parser,
|
||||
name = _gtk_css_parser_try_ident (parser, FALSE);
|
||||
if (name)
|
||||
{
|
||||
selector = gtk_css_selector_new (_gtk_style_context_check_region_name (name)
|
||||
? >K_CSS_SELECTOR_REGION
|
||||
: >K_CSS_SELECTOR_NAME,
|
||||
selector,
|
||||
g_intern_string (name));
|
||||
if (_gtk_style_context_check_region_name (name))
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_REGION,
|
||||
selector,
|
||||
g_intern_string (name));
|
||||
else
|
||||
selector = gtk_css_selector_new (>K_CSS_SELECTOR_NAME,
|
||||
selector,
|
||||
get_type_reference (name));
|
||||
g_free (name);
|
||||
}
|
||||
else if (_gtk_css_parser_try (parser, "*", FALSE))
|
||||
@ -1916,6 +1976,8 @@ _gtk_css_selector_tree_match_get_change (const GtkCssSelectorTree *tree)
|
||||
{
|
||||
GtkCssChange change = 0;
|
||||
|
||||
update_type_references ();
|
||||
|
||||
while (tree)
|
||||
{
|
||||
change = tree->selector.class->get_change (&tree->selector, change);
|
||||
@ -1947,6 +2009,8 @@ _gtk_css_selector_matches (const GtkCssSelector *selector,
|
||||
g_return_val_if_fail (selector != NULL, FALSE);
|
||||
g_return_val_if_fail (matcher != NULL, FALSE);
|
||||
|
||||
update_type_references ();
|
||||
|
||||
return gtk_css_selector_match (selector, matcher);
|
||||
}
|
||||
|
||||
@ -2085,6 +2149,8 @@ _gtk_css_selector_tree_match_all (const GtkCssSelectorTree *tree,
|
||||
GHashTableIter iter;
|
||||
gpointer key;
|
||||
|
||||
update_type_references ();
|
||||
|
||||
res = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
|
||||
for (; tree != NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user