Merge pull request #64329 from jordo/fix/control-theme-cache

[3.x] Add theme item cache to `Control`
This commit is contained in:
Rémi Verschelde 2023-01-23 22:23:33 +01:00
commit 93c76825ce
No known key found for this signature in database
GPG key ID: C3336907360768E1
2 changed files with 52 additions and 5 deletions

View file

@ -485,6 +485,7 @@ void Control::_update_canvas_item_transform() {
void Control::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_ENTER_TREE: {
_invalidate_theme_cache();
} break;
case NOTIFICATION_POST_ENTER_TREE: {
data.minimum_size_valid = false;
@ -634,6 +635,7 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_THEME_CHANGED: {
_invalidate_theme_cache();
minimum_size_changed();
update();
} break;
@ -904,9 +906,15 @@ Ref<Texture> Control::get_icon(const StringName &p_name, const StringName &p_the
}
}
if (data.theme_icon_cache.has(p_theme_type) && data.theme_icon_cache[p_theme_type].has(p_name)) {
return data.theme_icon_cache[p_theme_type][p_name];
}
List<StringName> theme_types;
_get_theme_type_dependencies(p_theme_type, &theme_types);
return get_theme_item_in_types<Ref<Texture>>(data.theme_owner, Theme::DATA_TYPE_ICON, p_name, theme_types);
Ref<Texture> icon = get_theme_item_in_types<Ref<Texture>>(data.theme_owner, Theme::DATA_TYPE_ICON, p_name, theme_types);
data.theme_icon_cache[p_theme_type][p_name] = icon;
return icon;
}
Ref<Shader> Control::get_shader(const StringName &p_name, const StringName &p_theme_type) const {
@ -959,9 +967,15 @@ Ref<StyleBox> Control::get_stylebox(const StringName &p_name, const StringName &
}
}
if (data.theme_style_cache.has(p_theme_type) && data.theme_style_cache[p_theme_type].has(p_name)) {
return data.theme_style_cache[p_theme_type][p_name];
}
List<StringName> theme_types;
_get_theme_type_dependencies(p_theme_type, &theme_types);
return get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
Ref<StyleBox> style = get_theme_item_in_types<Ref<StyleBox>>(data.theme_owner, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types);
data.theme_style_cache[p_theme_type][p_name] = style;
return style;
}
Ref<Font> Control::get_font(const StringName &p_name, const StringName &p_theme_type) const {
@ -972,9 +986,15 @@ Ref<Font> Control::get_font(const StringName &p_name, const StringName &p_theme_
}
}
if (data.theme_font_cache.has(p_theme_type) && data.theme_font_cache[p_theme_type].has(p_name)) {
return data.theme_font_cache[p_theme_type][p_name];
}
List<StringName> theme_types;
_get_theme_type_dependencies(p_theme_type, &theme_types);
return get_theme_item_in_types<Ref<Font>>(data.theme_owner, Theme::DATA_TYPE_FONT, p_name, theme_types);
Ref<Font> font = get_theme_item_in_types<Ref<Font>>(data.theme_owner, Theme::DATA_TYPE_FONT, p_name, theme_types);
data.theme_font_cache[p_theme_type][p_name] = font;
return font;
}
Color Control::get_color(const StringName &p_name, const StringName &p_theme_type) const {
@ -985,9 +1005,15 @@ Color Control::get_color(const StringName &p_name, const StringName &p_theme_typ
}
}
if (data.theme_color_cache.has(p_theme_type) && data.theme_color_cache[p_theme_type].has(p_name)) {
return data.theme_color_cache[p_theme_type][p_name];
}
List<StringName> theme_types;
_get_theme_type_dependencies(p_theme_type, &theme_types);
return get_theme_item_in_types<Color>(data.theme_owner, Theme::DATA_TYPE_COLOR, p_name, theme_types);
Color color = get_theme_item_in_types<Color>(data.theme_owner, Theme::DATA_TYPE_COLOR, p_name, theme_types);
data.theme_color_cache[p_theme_type][p_name] = color;
return color;
}
int Control::get_constant(const StringName &p_name, const StringName &p_theme_type) const {
@ -998,9 +1024,15 @@ int Control::get_constant(const StringName &p_name, const StringName &p_theme_ty
}
}
if (data.theme_constant_cache.has(p_theme_type) && data.theme_constant_cache[p_theme_type].has(p_name)) {
return data.theme_constant_cache[p_theme_type][p_name];
}
List<StringName> theme_types;
_get_theme_type_dependencies(p_theme_type, &theme_types);
return get_theme_item_in_types<int>(data.theme_owner, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
int constant = get_theme_item_in_types<int>(data.theme_owner, Theme::DATA_TYPE_CONSTANT, p_name, theme_types);
data.theme_constant_cache[p_theme_type][p_name] = constant;
return constant;
}
bool Control::has_icon_override(const StringName &p_name) const {
@ -2103,6 +2135,14 @@ void Control::_theme_changed() {
_propagate_theme_changed(this, this, false);
}
void Control::_invalidate_theme_cache() {
data.theme_icon_cache.clear();
data.theme_style_cache.clear();
data.theme_font_cache.clear();
data.theme_color_cache.clear();
data.theme_constant_cache.clear();
}
void Control::set_theme(const Ref<Theme> &p_theme) {
if (data.theme == p_theme) {
return;

View file

@ -204,6 +204,12 @@ private:
HashMap<StringName, Color> color_override;
HashMap<StringName, int> constant_override;
mutable HashMap<StringName, HashMap<StringName, Ref<Texture>>> theme_icon_cache;
mutable HashMap<StringName, HashMap<StringName, Ref<StyleBox>>> theme_style_cache;
mutable HashMap<StringName, HashMap<StringName, Ref<Font>>> theme_font_cache;
mutable HashMap<StringName, HashMap<StringName, Color>> theme_color_cache;
mutable HashMap<StringName, HashMap<StringName, int>> theme_constant_cache;
} data;
void _window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, const Point2 *p_points, float p_min, float &r_closest_dist, Control **r_closest);
@ -216,6 +222,7 @@ private:
void _propagate_theme_changed(CanvasItem *p_at, Control *p_owner, bool p_assign = true);
void _theme_changed();
void _invalidate_theme_cache();
void _change_notify_margins();
void _update_minimum_size();