diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 9867b5aaf8c..105544415e3 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -475,6 +475,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; @@ -624,6 +625,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_THEME_CHANGED: { + _invalidate_theme_cache(); minimum_size_changed(); update(); } break; @@ -894,9 +896,15 @@ Ref 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 theme_types; _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types>(data.theme_owner, Theme::DATA_TYPE_ICON, p_name, theme_types); + Ref icon = get_theme_item_in_types>(data.theme_owner, Theme::DATA_TYPE_ICON, p_name, theme_types); + data.theme_icon_cache[p_theme_type][p_name] = icon; + return icon; } Ref Control::get_shader(const StringName &p_name, const StringName &p_theme_type) const { @@ -949,9 +957,15 @@ Ref 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 theme_types; _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types>(data.theme_owner, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + Ref style = get_theme_item_in_types>(data.theme_owner, Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); + data.theme_style_cache[p_theme_type][p_name] = style; + return style; } Ref Control::get_font(const StringName &p_name, const StringName &p_theme_type) const { @@ -962,9 +976,15 @@ Ref 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 theme_types; _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types>(data.theme_owner, Theme::DATA_TYPE_FONT, p_name, theme_types); + Ref font = get_theme_item_in_types>(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 { @@ -975,9 +995,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 theme_types; _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types(data.theme_owner, Theme::DATA_TYPE_COLOR, p_name, theme_types); + Color color = get_theme_item_in_types(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 { @@ -988,9 +1014,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 theme_types; _get_theme_type_dependencies(p_theme_type, &theme_types); - return get_theme_item_in_types(data.theme_owner, Theme::DATA_TYPE_CONSTANT, p_name, theme_types); + int constant = get_theme_item_in_types(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 { @@ -2093,6 +2125,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 &p_theme) { if (data.theme == p_theme) { return; diff --git a/scene/gui/control.h b/scene/gui/control.h index a8a4c555fa8..b90753d7bd0 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -204,6 +204,12 @@ private: HashMap color_override; HashMap constant_override; + mutable HashMap>> theme_icon_cache; + mutable HashMap>> theme_style_cache; + mutable HashMap>> theme_font_cache; + mutable HashMap> theme_color_cache; + mutable HashMap> 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();