From 7593e55527177d0dfb5ad536330b50e272bd93d4 Mon Sep 17 00:00:00 2001 From: aaronp64 Date: Mon, 24 Jun 2024 10:09:20 -0400 Subject: [PATCH] Improve Editor Inspector/Theme item lookup performance Changes to reduce the latency between changing node selection in the editor and seeing the new node reflected in the Inspector tab - Use Vector instead of List for ThemeOwner::get_theme_type_dependencies and related functions - Use Vector instead of List for ThemeContext::themes, set_themes(), and get_themes() - Add ClassDB:get_inheritance_chain_nocheck to get all parent/ancestor classes at once, to avoid repeated ClassDB locking overhead - Update BIND_THEME_ITEM macros and ThemeDB::update_class_instance_items to use provided StringNames for call to ThemeItemSetter, instead of creating a new StringName in each call These changes reduce the time taken by EditorInspector::update_tree by around 30-35% --- core/object/class_db.cpp | 23 ++++++++++++ core/object/class_db.h | 1 + editor/editor_node.cpp | 4 +-- editor/plugins/theme_editor_preview.cpp | 2 +- editor/project_manager.cpp | 2 +- scene/3d/label_3d.cpp | 8 ++--- scene/gui/control.cpp | 48 ++++++++++++------------- scene/main/window.cpp | 48 ++++++++++++------------- scene/resources/3d/primitive_meshes.cpp | 8 ++--- scene/resources/font.cpp | 12 +++---- scene/resources/theme.cpp | 8 ++--- scene/resources/theme.h | 2 +- scene/theme/theme_db.cpp | 24 ++++++------- scene/theme/theme_db.h | 45 ++++++++++++----------- scene/theme/theme_owner.cpp | 14 ++++---- scene/theme/theme_owner.h | 6 ++-- 16 files changed, 140 insertions(+), 115 deletions(-) diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index fe4345aa0d9..4e52bb3872f 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -291,6 +291,29 @@ StringName ClassDB::get_parent_class_nocheck(const StringName &p_class) { return ti->inherits; } +bool ClassDB::get_inheritance_chain_nocheck(const StringName &p_class, Vector &r_result) { + OBJTYPE_RLOCK; + + ClassInfo *start = classes.getptr(p_class); + if (!start) { + return false; + } + + int classes_to_add = 0; + for (ClassInfo *ti = start; ti; ti = ti->inherits_ptr) { + classes_to_add++; + } + + int64_t old_size = r_result.size(); + r_result.resize(old_size + classes_to_add); + StringName *w = r_result.ptrw() + old_size; + for (ClassInfo *ti = start; ti; ti = ti->inherits_ptr) { + *w++ = ti->name; + } + + return true; +} + StringName ClassDB::get_compatibility_remapped_class(const StringName &p_class) { if (classes.has(p_class)) { return p_class; diff --git a/core/object/class_db.h b/core/object/class_db.h index 37a864c1090..9e0f860a9b8 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -282,6 +282,7 @@ public: static void get_inheriters_from_class(const StringName &p_class, List *p_classes); static void get_direct_inheriters_from_class(const StringName &p_class, List *p_classes); static StringName get_parent_class_nocheck(const StringName &p_class); + static bool get_inheritance_chain_nocheck(const StringName &p_class, Vector &r_result); static StringName get_parent_class(const StringName &p_class); static StringName get_compatibility_remapped_class(const StringName &p_class); static bool class_exists(const StringName &p_class); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 55487f7896b..804d8a8426f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -487,7 +487,7 @@ void EditorNode::_update_theme(bool p_skip_creation) { DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor))); } - List> editor_themes; + Vector> editor_themes; editor_themes.push_back(theme); editor_themes.push_back(ThemeDB::get_singleton()->get_default_theme()); @@ -556,7 +556,7 @@ void EditorNode::update_preview_themes(int p_mode) { return; // Too early. } - List> preview_themes; + Vector> preview_themes; switch (p_mode) { case CanvasItemEditor::THEME_PREVIEW_PROJECT: diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp index 4d98b24ccc0..2426cec5211 100644 --- a/editor/plugins/theme_editor_preview.cpp +++ b/editor/plugins/theme_editor_preview.cpp @@ -205,7 +205,7 @@ void ThemeEditorPreview::_notification(int p_what) { } break; case NOTIFICATION_READY: { - List> preview_themes; + Vector> preview_themes; preview_themes.push_back(ThemeDB::get_singleton()->get_default_theme()); ThemeDB::get_singleton()->create_theme_context(preview_root, preview_themes); } break; diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 52d7b14b655..a1d64fe64e0 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -190,7 +190,7 @@ void ProjectManager::_update_theme(bool p_skip_creation) { DisplayServer::set_early_window_clear_color_override(true, theme->get_color(SNAME("background"), EditorStringName(Editor))); } - List> editor_themes; + Vector> editor_themes; editor_themes.push_back(theme); editor_themes.push_back(ThemeDB::get_singleton()->get_default_theme()); diff --git a/scene/3d/label_3d.cpp b/scene/3d/label_3d.cpp index 54adafbefb6..9330cd8b652 100644 --- a/scene/3d/label_3d.cpp +++ b/scene/3d/label_3d.cpp @@ -797,13 +797,13 @@ Ref Label3D::_get_font_or_default() const { } const StringName theme_name = SceneStringName(font); - List theme_types; - ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types); + Vector theme_types; + ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), theme_types); ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context(); - List> themes = global_context->get_themes(); + Vector> themes = global_context->get_themes(); if (Engine::get_singleton()->is_editor_hint()) { - themes.push_front(ThemeDB::get_singleton()->get_project_theme()); + themes.insert(0, ThemeDB::get_singleton()->get_project_theme()); } for (const Ref &theme : themes) { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 0682c11a9b2..1683fb572de 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2575,8 +2575,8 @@ Ref Control::get_theme_icon(const StringName &p_name, const StringNam return data.theme_icon_cache[p_theme_type][p_name]; } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Ref icon = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); data.theme_icon_cache[p_theme_type][p_name] = icon; return icon; @@ -2599,8 +2599,8 @@ Ref Control::get_theme_stylebox(const StringName &p_name, const String return data.theme_style_cache[p_theme_type][p_name]; } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Ref style = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); data.theme_style_cache[p_theme_type][p_name] = style; return style; @@ -2623,8 +2623,8 @@ Ref Control::get_theme_font(const StringName &p_name, const StringName &p_ return data.theme_font_cache[p_theme_type][p_name]; } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Ref font = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); data.theme_font_cache[p_theme_type][p_name] = font; return font; @@ -2647,8 +2647,8 @@ int Control::get_theme_font_size(const StringName &p_name, const StringName &p_t return data.theme_font_size_cache[p_theme_type][p_name]; } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); int font_size = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); data.theme_font_size_cache[p_theme_type][p_name] = font_size; return font_size; @@ -2671,8 +2671,8 @@ Color Control::get_theme_color(const StringName &p_name, const StringName &p_the return data.theme_color_cache[p_theme_type][p_name]; } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Color color = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); data.theme_color_cache[p_theme_type][p_name] = color; return color; @@ -2695,8 +2695,8 @@ int Control::get_theme_constant(const StringName &p_name, const StringName &p_th return data.theme_constant_cache[p_theme_type][p_name]; } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); int constant = data.theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); data.theme_constant_cache[p_theme_type][p_name] = constant; return constant; @@ -2741,8 +2741,8 @@ bool Control::has_theme_icon(const StringName &p_name, const StringName &p_theme } } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); } @@ -2758,8 +2758,8 @@ bool Control::has_theme_stylebox(const StringName &p_name, const StringName &p_t } } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } @@ -2775,8 +2775,8 @@ bool Control::has_theme_font(const StringName &p_name, const StringName &p_theme } } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); } @@ -2792,8 +2792,8 @@ bool Control::has_theme_font_size(const StringName &p_name, const StringName &p_ } } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } @@ -2809,8 +2809,8 @@ bool Control::has_theme_color(const StringName &p_name, const StringName &p_them } } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); } @@ -2826,8 +2826,8 @@ bool Control::has_theme_constant(const StringName &p_name, const StringName &p_t } } - List theme_types; - data.theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + data.theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return data.theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } diff --git a/scene/main/window.cpp b/scene/main/window.cpp index d409efbfabd..6e0513e2f16 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -2159,8 +2159,8 @@ Ref Window::get_theme_icon(const StringName &p_name, const StringName return theme_icon_cache[p_theme_type][p_name]; } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Ref icon = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); theme_icon_cache[p_theme_type][p_name] = icon; return icon; @@ -2183,8 +2183,8 @@ Ref Window::get_theme_stylebox(const StringName &p_name, const StringN return theme_style_cache[p_theme_type][p_name]; } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Ref style = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); theme_style_cache[p_theme_type][p_name] = style; return style; @@ -2207,8 +2207,8 @@ Ref Window::get_theme_font(const StringName &p_name, const StringName &p_t return theme_font_cache[p_theme_type][p_name]; } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Ref font = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); theme_font_cache[p_theme_type][p_name] = font; return font; @@ -2231,8 +2231,8 @@ int Window::get_theme_font_size(const StringName &p_name, const StringName &p_th return theme_font_size_cache[p_theme_type][p_name]; } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); int font_size = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); theme_font_size_cache[p_theme_type][p_name] = font_size; return font_size; @@ -2255,8 +2255,8 @@ Color Window::get_theme_color(const StringName &p_name, const StringName &p_them return theme_color_cache[p_theme_type][p_name]; } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); Color color = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); theme_color_cache[p_theme_type][p_name] = color; return color; @@ -2279,8 +2279,8 @@ int Window::get_theme_constant(const StringName &p_name, const StringName &p_the return theme_constant_cache[p_theme_type][p_name]; } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); int constant = theme_owner->get_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); theme_constant_cache[p_theme_type][p_name] = constant; return constant; @@ -2325,8 +2325,8 @@ bool Window::has_theme_icon(const StringName &p_name, const StringName &p_theme_ } } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_ICON, p_name, theme_types); } @@ -2342,8 +2342,8 @@ bool Window::has_theme_stylebox(const StringName &p_name, const StringName &p_th } } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_STYLEBOX, p_name, theme_types); } @@ -2359,8 +2359,8 @@ bool Window::has_theme_font(const StringName &p_name, const StringName &p_theme_ } } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT, p_name, theme_types); } @@ -2376,8 +2376,8 @@ bool Window::has_theme_font_size(const StringName &p_name, const StringName &p_t } } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_FONT_SIZE, p_name, theme_types); } @@ -2393,8 +2393,8 @@ bool Window::has_theme_color(const StringName &p_name, const StringName &p_theme } } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_COLOR, p_name, theme_types); } @@ -2410,8 +2410,8 @@ bool Window::has_theme_constant(const StringName &p_name, const StringName &p_th } } - List theme_types; - theme_owner->get_theme_type_dependencies(this, p_theme_type, &theme_types); + Vector theme_types; + theme_owner->get_theme_type_dependencies(this, p_theme_type, theme_types); return theme_owner->has_theme_item_in_types(Theme::DATA_TYPE_CONSTANT, p_name, theme_types); } diff --git a/scene/resources/3d/primitive_meshes.cpp b/scene/resources/3d/primitive_meshes.cpp index ee772f960a0..4660bd9e5d1 100644 --- a/scene/resources/3d/primitive_meshes.cpp +++ b/scene/resources/3d/primitive_meshes.cpp @@ -3468,13 +3468,13 @@ Ref TextMesh::_get_font_or_default() const { } StringName theme_name = "font"; - List theme_types; - ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types); + Vector theme_types; + ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), theme_types); ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context(); - List> themes = global_context->get_themes(); + Vector> themes = global_context->get_themes(); if (Engine::get_singleton()->is_editor_hint()) { - themes.push_front(ThemeDB::get_singleton()->get_project_theme()); + themes.insert(0, ThemeDB::get_singleton()->get_project_theme()); } for (const Ref &theme : themes) { diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index bc8e0b90156..4074f0a4c43 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -2890,13 +2890,13 @@ Ref FontVariation::_get_base_font_or_default() const { } StringName theme_name = "font"; - List theme_types; - ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types); + Vector theme_types; + ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), theme_types); ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context(); - List> themes = global_context->get_themes(); + Vector> themes = global_context->get_themes(); if (Engine::get_singleton()->is_editor_hint()) { - themes.push_front(ThemeDB::get_singleton()->get_project_theme()); + themes.insert(0, ThemeDB::get_singleton()->get_project_theme()); } for (const Ref &theme : themes) { @@ -3259,8 +3259,8 @@ Ref SystemFont::_get_base_font_or_default() const { } StringName theme_name = "font"; - List theme_types; - ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), &theme_types); + Vector theme_types; + ThemeDB::get_singleton()->get_native_type_dependencies(get_class_name(), theme_types); ThemeContext *global_context = ThemeDB::get_singleton()->get_default_theme_context(); for (const Ref &theme : global_context->get_themes()) { diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index b6cd6f6dfe3..1ac90b89803 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -1250,14 +1250,12 @@ void Theme::get_type_list(List *p_list) const { } } -void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, List *p_list) { - ERR_FAIL_NULL(p_list); - +void Theme::get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variation, Vector &r_result) { // Build the dependency chain for type variations. if (p_type_variation != StringName()) { StringName variation_name = p_type_variation; while (variation_name != StringName()) { - p_list->push_back(variation_name); + r_result.push_back(variation_name); variation_name = get_type_variation_base(variation_name); // If we have reached the base type dependency, it's safe to stop (assuming no funny business was done to the Theme). @@ -1268,7 +1266,7 @@ void Theme::get_type_dependencies(const StringName &p_base_type, const StringNam } // Continue building the chain using native class hierarchy. - ThemeDB::get_singleton()->get_native_type_dependencies(p_base_type, p_list); + ThemeDB::get_singleton()->get_native_type_dependencies(p_base_type, r_result); } // Internal methods for getting lists as a Vector of String (compatible with public API). diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 73f1167c297..14ad4ae0fd6 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -216,7 +216,7 @@ public: void add_type(const StringName &p_theme_type); void remove_type(const StringName &p_theme_type); void get_type_list(List *p_list) const; - void get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variant, List *p_list); + void get_type_dependencies(const StringName &p_base_type, const StringName &p_type_variant, Vector &r_result); void merge_with(const Ref &p_other); void clear(); diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp index 7249fd7ba82..c33c31558f9 100644 --- a/scene/theme/theme_db.cpp +++ b/scene/theme/theme_db.cpp @@ -198,21 +198,21 @@ Ref ThemeDB::get_fallback_stylebox() { return fallback_stylebox; } -void ThemeDB::get_native_type_dependencies(const StringName &p_base_type, List *p_list) { - ERR_FAIL_NULL(p_list); +void ThemeDB::get_native_type_dependencies(const StringName &p_base_type, Vector &r_result) { + if (p_base_type == StringName()) { + return; + } // TODO: It may make sense to stop at Control/Window, because their parent classes cannot be used in // a meaningful way. - StringName class_name = p_base_type; - while (class_name != StringName()) { - p_list->push_back(class_name); - class_name = ClassDB::get_parent_class_nocheck(class_name); + if (!ClassDB::get_inheritance_chain_nocheck(p_base_type, r_result)) { + r_result.push_back(p_base_type); } } // Global theme contexts. -ThemeContext *ThemeDB::create_theme_context(Node *p_node, List> &p_themes) { +ThemeContext *ThemeDB::create_theme_context(Node *p_node, Vector> &p_themes) { ERR_FAIL_COND_V(!p_node->is_inside_tree(), nullptr); ERR_FAIL_COND_V(theme_contexts.has(p_node), nullptr); ERR_FAIL_COND_V(p_themes.is_empty(), nullptr); @@ -270,7 +270,7 @@ void ThemeDB::_propagate_theme_context(Node *p_from_node, ThemeContext *p_contex void ThemeDB::_init_default_theme_context() { default_theme_context = memnew(ThemeContext); - List> themes; + Vector> themes; // Only add the project theme to the default context when running projects. @@ -365,7 +365,7 @@ void ThemeDB::update_class_instance_items(Node *p_instance) { HashMap>::Iterator E = theme_item_binds.find(class_name); if (E) { for (const KeyValue &F : E->value) { - F.value.setter(p_instance); + F.value.setter(p_instance, F.value.item_name, F.value.type_name); } } @@ -475,7 +475,7 @@ void ThemeContext::_emit_changed() { emit_signal(CoreStringName(changed)); } -void ThemeContext::set_themes(List> &p_themes) { +void ThemeContext::set_themes(Vector> &p_themes) { for (const Ref &theme : themes) { theme->disconnect_changed(callable_mp(this, &ThemeContext::_emit_changed)); } @@ -494,7 +494,7 @@ void ThemeContext::set_themes(List> &p_themes) { _emit_changed(); } -List> ThemeContext::get_themes() const { +const Vector> ThemeContext::get_themes() const { return themes; } @@ -504,7 +504,7 @@ Ref ThemeContext::get_fallback_theme() const { return ThemeDB::get_singleton()->get_default_theme(); } - return themes.back()->get(); + return themes[themes.size() - 1]; } void ThemeContext::_bind_methods() { diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h index f403c1ef20a..353894f41e4 100644 --- a/scene/theme/theme_db.h +++ b/scene/theme/theme_db.h @@ -46,26 +46,29 @@ class ThemeContext; // Macros for binding theme items of this class. This information is used for the documentation, theme // overrides, etc. This is also the basis for theme cache. -#define BIND_THEME_ITEM(m_data_type, m_class, m_prop) \ - ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, #m_prop, [](Node *p_instance) { \ - m_class *p_cast = Object::cast_to(p_instance); \ - p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, _scs_create(#m_prop)); \ - }) +#define BIND_THEME_ITEM(m_data_type, m_class, m_prop) \ + ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, #m_prop, \ + [](Node *p_instance, const StringName &p_item_name, const StringName &p_type_name) { \ + m_class *p_cast = Object::cast_to(p_instance); \ + p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, p_item_name, p_type_name); \ + }) -#define BIND_THEME_ITEM_CUSTOM(m_data_type, m_class, m_prop, m_item_name) \ - ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, m_item_name, [](Node *p_instance) { \ - m_class *p_cast = Object::cast_to(p_instance); \ - p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, _scs_create(m_item_name)); \ - }) +#define BIND_THEME_ITEM_CUSTOM(m_data_type, m_class, m_prop, m_item_name) \ + ThemeDB::get_singleton()->bind_class_item(m_data_type, get_class_static(), #m_prop, m_item_name, \ + [](Node *p_instance, const StringName &p_item_name, const StringName &p_type_name) { \ + m_class *p_cast = Object::cast_to(p_instance); \ + p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, p_item_name, p_type_name); \ + }) // Macro for binding theme items used by this class, but defined/binded by other classes. This is primarily used for // the theme cache. Can also be used to list such items in documentation. -#define BIND_THEME_ITEM_EXT(m_data_type, m_class, m_prop, m_item_name, m_type_name) \ - ThemeDB::get_singleton()->bind_class_external_item(m_data_type, get_class_static(), #m_prop, m_item_name, m_type_name, [](Node *p_instance) { \ - m_class *p_cast = Object::cast_to(p_instance); \ - p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, _scs_create(m_item_name), _scs_create(m_type_name)); \ - }) +#define BIND_THEME_ITEM_EXT(m_data_type, m_class, m_prop, m_item_name, m_type_name) \ + ThemeDB::get_singleton()->bind_class_external_item(m_data_type, get_class_static(), #m_prop, m_item_name, m_type_name, \ + [](Node *p_instance, const StringName &p_item_name, const StringName &p_type_name) { \ + m_class *p_cast = Object::cast_to(p_instance); \ + p_cast->theme_cache.m_prop = p_cast->get_theme_item(m_data_type, p_item_name, p_type_name); \ + }) class ThemeDB : public Object { GDCLASS(ThemeDB, Object); @@ -97,7 +100,7 @@ class ThemeDB : public Object { // Binding of theme items to Node classes. public: - typedef std::function ThemeItemSetter; + typedef std::function ThemeItemSetter; struct ThemeItemBind { Theme::DataType data_type; @@ -154,11 +157,11 @@ public: void set_fallback_stylebox(const Ref &p_stylebox); Ref get_fallback_stylebox(); - void get_native_type_dependencies(const StringName &p_base_type, List *p_list); + void get_native_type_dependencies(const StringName &p_base_type, Vector &r_result); // Global theme contexts. - ThemeContext *create_theme_context(Node *p_node, List> &p_themes); + ThemeContext *create_theme_context(Node *p_node, Vector> &p_themes); void destroy_theme_context(Node *p_node); ThemeContext *get_theme_context(Node *p_node) const; @@ -191,7 +194,7 @@ class ThemeContext : public Object { // Themes are stacked in the order of relevance, for easy iteration. // This means that the first theme is the one you should check first, // and the last theme is the fallback theme where every lookup ends. - List> themes; + Vector> themes; void _emit_changed(); @@ -199,8 +202,8 @@ protected: static void _bind_methods(); public: - void set_themes(List> &p_themes); - List> get_themes() const; + void set_themes(Vector> &p_themes); + const Vector> get_themes() const; Ref get_fallback_theme() const; }; diff --git a/scene/theme/theme_owner.cpp b/scene/theme/theme_owner.cpp index a25adddc098..b3d51e71c09 100644 --- a/scene/theme/theme_owner.cpp +++ b/scene/theme/theme_owner.cpp @@ -199,7 +199,7 @@ void ThemeOwner::propagate_theme_changed(Node *p_to_node, Node *p_owner_node, bo // Theme lookup. -void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List *r_list) const { +void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, Vector &r_result) const { const Control *for_c = Object::cast_to(p_for_node); const Window *for_w = Object::cast_to(p_for_node); ERR_FAIL_COND_MSG(!for_c && !for_w, "Only Control and Window nodes and derivatives can be polled for theming."); @@ -224,7 +224,7 @@ void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const Strin while (owner_node) { Ref owner_theme = _get_owner_node_theme(owner_node); if (owner_theme.is_valid() && owner_theme->get_type_variation_base(type_variation) != StringName()) { - owner_theme->get_type_dependencies(type_name, type_variation, r_list); + owner_theme->get_type_dependencies(type_name, type_variation, r_result); return; } @@ -235,21 +235,21 @@ void ThemeOwner::get_theme_type_dependencies(const Node *p_for_node, const Strin ThemeContext *global_context = _get_active_owner_context(); for (const Ref &theme : global_context->get_themes()) { if (theme.is_valid() && theme->get_type_variation_base(type_variation) != StringName()) { - theme->get_type_dependencies(type_name, type_variation, r_list); + theme->get_type_dependencies(type_name, type_variation, r_result); return; } } // If nothing was found, get the native dependencies for the current class. - ThemeDB::get_singleton()->get_native_type_dependencies(type_name, r_list); + ThemeDB::get_singleton()->get_native_type_dependencies(type_name, r_result); return; } // Otherwise, get the native dependencies for the provided theme type. - ThemeDB::get_singleton()->get_native_type_dependencies(p_theme_type, r_list); + ThemeDB::get_singleton()->get_native_type_dependencies(p_theme_type, r_result); } -Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List &p_theme_types) { +Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector &p_theme_types) { ERR_FAIL_COND_V_MSG(p_theme_types.is_empty(), Variant(), "At least one theme type must be specified."); // First, look through each control or window node in the branch, until no valid parent can be found. @@ -285,7 +285,7 @@ Variant ThemeOwner::get_theme_item_in_types(Theme::DataType p_data_type, const S return global_context->get_fallback_theme()->get_theme_item(p_data_type, p_name, StringName()); } -bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List &p_theme_types) { +bool ThemeOwner::has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector &p_theme_types) { ERR_FAIL_COND_V_MSG(p_theme_types.is_empty(), false, "At least one theme type must be specified."); // First, look through each control or window node in the branch, until no valid parent can be found. diff --git a/scene/theme/theme_owner.h b/scene/theme/theme_owner.h index 7e19279c2a6..14bfa355873 100644 --- a/scene/theme/theme_owner.h +++ b/scene/theme/theme_owner.h @@ -69,10 +69,10 @@ public: // Theme lookup. - void get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, List *r_list) const; + void get_theme_type_dependencies(const Node *p_for_node, const StringName &p_theme_type, Vector &r_result) const; - Variant get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List &p_theme_types); - bool has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const List &p_theme_types); + Variant get_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector &p_theme_types); + bool has_theme_item_in_types(Theme::DataType p_data_type, const StringName &p_name, const Vector &p_theme_types); float get_theme_default_base_scale(); Ref get_theme_default_font();