diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 606193538..946ac8fbb 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -488,6 +488,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; @@ -637,6 +638,7 @@ void Control::_notification(int p_notification) { } break; case NOTIFICATION_THEME_CHANGED: { + _invalidate_theme_cache(); minimum_size_changed(); update(); } break; @@ -907,9 +909,16 @@ Ref Control::get_theme_icon(const StringName &p_name, const StringName } } + 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_theme_shader(const StringName &p_name, const StringName &p_theme_type) const { @@ -962,9 +971,16 @@ Ref Control::get_theme_stylebox(const StringName &p_name, const String } } + 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_theme_font(const StringName &p_name, const StringName &p_theme_type) const { @@ -975,9 +991,16 @@ Ref Control::get_theme_font(const StringName &p_name, const StringName &p_ } } + 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_theme_color(const StringName &p_name, const StringName &p_theme_type) const { @@ -988,9 +1011,16 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_the } } + 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_theme_constant(const StringName &p_name, const StringName &p_theme_type) const { @@ -1001,9 +1031,16 @@ int Control::get_theme_constant(const StringName &p_name, const StringName &p_th } } + 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_theme_icon_override(const StringName &p_name) const { @@ -2106,6 +2143,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 b87ad7dcd..2e9ea866c 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -30,8 +30,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/math/transform_2d.h" #include "core/containers/rid.h" +#include "core/math/transform_2d.h" #include "scene/2d/canvas_item.h" #include "scene/resources/theme.h" @@ -206,6 +206,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); @@ -218,6 +224,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();