Browse Source

Add dumb theme item cache to Control

(cherry picked from commit 9f88300007cd1d418e2c63c663ca660e46d72fa4)

Co-authored-by: Jordan Schidlowsky <[email protected]>
Yuri Sizov 3 years ago
parent
commit
1647f4d85e
2 changed files with 52 additions and 5 deletions
  1. 45 5
      scene/gui/control.cpp
  2. 7 0
      scene/gui/control.h

+ 45 - 5
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<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 {
@@ -949,9 +957,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 {
@@ -962,9 +976,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 {
@@ -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<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 {
@@ -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<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 {
@@ -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<Theme> &p_theme) {
 	if (data.theme == p_theme) {
 		return;

+ 7 - 0
scene/gui/control.h

@@ -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();