From ce5bdecf899d8ea50c22d6204089e11ac717755b Mon Sep 17 00:00:00 2001 From: Hans Goudey Date: Thu, 30 Jan 2025 15:35:00 +0100 Subject: [PATCH] Refactor: Use VectorSet for panels, menus, gizmos, lists, operators Previously, the global storage of these types either used a GHash or a blender::Map. VectorSet is preferrable to GHash because it's type safe, clearer, and faster. It's preferrable to Map because the key doesn't have to be duplicated and because iteration is faster. This PR moves these registered types to VectorSet, just like the node, node socket, and node tree types. Note that none of these types use RAII for allocation, so freeing is still done manually. Testing was manually interacting with each of these systems, including with addons that register their own types. Pull Request: https://projects.blender.org/blender/blender/pulls/133778 --- .../interface_template_search_menu.cc | 7 +- .../interface_template_search_operator.cc | 2 +- source/blender/python/intern/bpy_operator.cc | 6 +- source/blender/windowmanager/WM_api.hh | 7 +- .../windowmanager/gizmo/WM_gizmo_api.hh | 9 --- .../gizmo/intern/wm_gizmo_group_type.cc | 74 ++++++++++++------- .../gizmo/intern/wm_gizmo_type.cc | 70 +++++++++++------- .../windowmanager/intern/wm_menu_type.cc | 67 +++++++++++------ .../windowmanager/intern/wm_operator_type.cc | 61 ++++++++++----- .../windowmanager/intern/wm_panel_type.cc | 55 ++++++++++---- .../windowmanager/intern/wm_uilist_type.cc | 56 ++++++++++---- 11 files changed, 273 insertions(+), 141 deletions(-) diff --git a/source/blender/editors/interface/templates/interface_template_search_menu.cc b/source/blender/editors/interface/templates/interface_template_search_menu.cc index fc8569c32a5..23e6863368c 100644 --- a/source/blender/editors/interface/templates/interface_template_search_menu.cc +++ b/source/blender/editors/interface/templates/interface_template_search_menu.cc @@ -381,7 +381,7 @@ static void menu_items_from_all_operators(bContext *C, MenuSearch_Data *data) ListBase operator_items = {nullptr, nullptr}; MemArena *memarena = data->memarena; - for (wmOperatorType *ot : WM_operatortype_map().values()) { + for (wmOperatorType *ot : WM_operatortypes_registered_get()) { if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) { continue; } @@ -476,10 +476,7 @@ static MenuSearch_Data *menu_items_from_ui_create(bContext *C, * (exact number of items selected for example). See design doc #74158. * There is one exception, * as the outliner only exposes functionality via the context menu. */ - GHashIterator iter; - - for (WM_menutype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) { - MenuType *mt = (MenuType *)BLI_ghashIterator_getValue(&iter); + for (MenuType *mt : WM_menutypes_registered_get()) { if (BLI_str_endswith(mt->idname, "_context_menu")) { menu_tagged.add(mt); } diff --git a/source/blender/editors/interface/templates/interface_template_search_operator.cc b/source/blender/editors/interface/templates/interface_template_search_operator.cc index 8d7b7ed3ab4..a56fb000ff8 100644 --- a/source/blender/editors/interface/templates/interface_template_search_operator.cc +++ b/source/blender/editors/interface/templates/interface_template_search_operator.cc @@ -52,7 +52,7 @@ static void operator_search_update_fn(const bContext *C, const int words_len = BLI_string_find_split_words( str, str_len, ' ', (int(*)[2])words.data(), words_max); - for (wmOperatorType *ot : WM_operatortype_map().values()) { + for (wmOperatorType *ot : WM_operatortypes_registered_get()) { const char *ot_ui_name = CTX_IFACE_(ot->translation_context, ot->name); if ((ot->flag & OPTYPE_INTERNAL) && (G.debug & G_DEBUG_WM) == 0) { diff --git a/source/blender/python/intern/bpy_operator.cc b/source/blender/python/intern/bpy_operator.cc index 97f55b7a5e5..c86ea252288 100644 --- a/source/blender/python/intern/bpy_operator.cc +++ b/source/blender/python/intern/bpy_operator.cc @@ -393,11 +393,11 @@ static PyObject *pyop_as_string(PyObject * /*self*/, PyObject *args) static PyObject *pyop_dir(PyObject * /*self*/) { - const wmOperatorTypeMap &map = WM_operatortype_map(); - PyObject *list = PyList_New(map.size()); + const blender::Span types = WM_operatortypes_registered_get(); + PyObject *list = PyList_New(types.size()); int i = 0; - for (wmOperatorType *ot : map.values()) { + for (wmOperatorType *ot : types) { PyList_SET_ITEM(list, i, PyUnicode_FromString(ot->idname)); i++; } diff --git a/source/blender/windowmanager/WM_api.hh b/source/blender/windowmanager/WM_api.hh index 2394a8a6f79..dcb0775f284 100644 --- a/source/blender/windowmanager/WM_api.hh +++ b/source/blender/windowmanager/WM_api.hh @@ -23,7 +23,6 @@ #include "BLI_bounds_types.hh" #include "BLI_compiler_attrs.h" #include "BLI_function_ref.hh" -#include "BLI_map.hh" #include "BLI_math_vector_types.hh" #include "BLI_sys_types.h" @@ -31,7 +30,6 @@ #include "WM_types.hh" struct ARegion; -struct GHashIterator; struct GPUViewport; struct ID; struct IDProperty; @@ -1183,8 +1181,7 @@ std::optional WM_context_path_resolve_full(bContext *C, const Point /* `wm_operator_type.cc` */ wmOperatorType *WM_operatortype_find(const char *idname, bool quiet); -using wmOperatorTypeMap = blender::Map; -const wmOperatorTypeMap &WM_operatortype_map(); +blender::Span WM_operatortypes_registered_get(); void WM_operatortype_append(void (*opfunc)(wmOperatorType *ot)); void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType *ot, void *userdata), void *userdata); @@ -1304,7 +1301,7 @@ const char *WM_uilisttype_list_id_get(const uiListType *ult, uiList *list); */ void WM_menutype_init(); MenuType *WM_menutype_find(const char *idname, bool quiet); -void WM_menutype_iter(GHashIterator *ghi); +blender::Span WM_menutypes_registered_get(); bool WM_menutype_add(MenuType *mt); void WM_menutype_freelink(MenuType *mt); void WM_menutype_free(); diff --git a/source/blender/windowmanager/gizmo/WM_gizmo_api.hh b/source/blender/windowmanager/gizmo/WM_gizmo_api.hh index 8e77e58ae97..415c50b9035 100644 --- a/source/blender/windowmanager/gizmo/WM_gizmo_api.hh +++ b/source/blender/windowmanager/gizmo/WM_gizmo_api.hh @@ -15,7 +15,6 @@ struct ARegion; struct bContext; -struct GHashIterator; struct IDProperty; struct ListBase; struct Main; @@ -189,10 +188,6 @@ void WM_gizmotype_remove_ptr(bContext *C, Main *bmain, wmGizmoType *gzt); * Free but don't remove from #GHash. */ void WM_gizmotype_free_ptr(wmGizmoType *gzt); -/** - * Caller must free. - */ -void WM_gizmotype_iter(GHashIterator *ghi); /* `wm_gizmo_group_type.cc` */ @@ -200,10 +195,6 @@ wmGizmoGroupType *WM_gizmogrouptype_find(const char *idname, bool quiet); wmGizmoGroupType *WM_gizmogrouptype_append(void (*wtfunc)(wmGizmoGroupType *)); wmGizmoGroupType *WM_gizmogrouptype_append_ptr(void (*wtfunc)(wmGizmoGroupType *, void *), void *userdata); -/** - * Caller must free. - */ -void WM_gizmogrouptype_iter(GHashIterator *ghi); /** * Append and insert into a gizmo type-map. diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.cc b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.cc index ec50937c02a..16926732d72 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.cc +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group_type.cc @@ -8,7 +8,7 @@ #include -#include "BLI_ghash.h" +#include "BLI_vector_set.hh" #include "MEM_guardedalloc.h" @@ -28,16 +28,47 @@ * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends. * \{ */ -static GHash *global_gizmogrouptype_hash = nullptr; +using blender::StringRef; + +struct GizmoGroupTypePointerHash { + uint64_t operator()(const wmGizmoGroupType *value) const + { + return get_default_hash(StringRef(value->idname)); + } + uint64_t operator()(const StringRef name) const + { + return get_default_hash(name); + } +}; + +struct GizmoGroupTypePointerNameEqual { + bool operator()(const wmGizmoGroupType *a, const wmGizmoGroupType *b) const + { + return STREQ(a->idname, b->idname); + } + bool operator()(const StringRef idname, const wmGizmoGroupType *a) const + { + return a->idname == idname; + } +}; + +static auto &get_gizmo_group_type_map() +{ + static blender::VectorSet + map; + return map; +} wmGizmoGroupType *WM_gizmogrouptype_find(const char *idname, bool quiet) { if (idname[0]) { - wmGizmoGroupType *gzgt; - - gzgt = static_cast(BLI_ghash_lookup(global_gizmogrouptype_hash, idname)); - if (gzgt) { - return gzgt; + if (wmGizmoGroupType *const *gzgt = get_gizmo_group_type_map().lookup_key_ptr_as( + StringRef(idname))) + { + return *gzgt; } if (!quiet) { @@ -53,11 +84,6 @@ wmGizmoGroupType *WM_gizmogrouptype_find(const char *idname, bool quiet) return nullptr; } -void WM_gizmogrouptype_iter(GHashIterator *ghi) -{ - BLI_ghashIterator_init(ghi, global_gizmogrouptype_hash); -} - static wmGizmoGroupType *wm_gizmogrouptype_append__begin() { wmGizmoGroupType *gzgt = static_cast( @@ -89,7 +115,7 @@ static void wm_gizmogrouptype_append__end(wmGizmoGroupType *gzgt) } } - BLI_ghash_insert(global_gizmogrouptype_hash, (void *)gzgt->idname, gzgt); + get_gizmo_group_type_map().add(gzgt); } wmGizmoGroupType *WM_gizmogrouptype_append(void (*wtfunc)(wmGizmoGroupType *)) @@ -137,7 +163,7 @@ void WM_gizmo_group_type_free_ptr(wmGizmoGroupType *gzgt) { BLI_assert(gzgt == WM_gizmogrouptype_find(gzgt->idname, false)); - BLI_ghash_remove(global_gizmogrouptype_hash, gzgt->idname, nullptr, nullptr); + get_gizmo_group_type_map().remove(gzgt); gizmogrouptype_free(gzgt); @@ -146,34 +172,28 @@ void WM_gizmo_group_type_free_ptr(wmGizmoGroupType *gzgt) bool WM_gizmo_group_type_free(const char *idname) { - wmGizmoGroupType *gzgt = static_cast( - BLI_ghash_lookup(global_gizmogrouptype_hash, idname)); - + wmGizmoGroupType *const *gzgt = get_gizmo_group_type_map().lookup_key_ptr_as(StringRef(idname)); if (gzgt == nullptr) { return false; } - WM_gizmo_group_type_free_ptr(gzgt); + WM_gizmo_group_type_free_ptr(*gzgt); return true; } -static void wm_gizmogrouptype_ghash_free_cb(wmGizmoGroupType *gzgt) -{ - gizmogrouptype_free(gzgt); -} - void wm_gizmogrouptype_free() { - BLI_ghash_free( - global_gizmogrouptype_hash, nullptr, (GHashValFreeFP)wm_gizmogrouptype_ghash_free_cb); - global_gizmogrouptype_hash = nullptr; + for (wmGizmoGroupType *gzgt : get_gizmo_group_type_map()) { + gizmogrouptype_free(gzgt); + } + get_gizmo_group_type_map().clear(); } void wm_gizmogrouptype_init() { /* Reserve size is set based on blender default setup. */ - global_gizmogrouptype_hash = BLI_ghash_str_new_ex("wm_gizmogrouptype_init gh", 128); + get_gizmo_group_type_map().reserve(128); } /** \} */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.cc b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.cc index 22e2b4f7725..948c1ab0528 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.cc +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_type.cc @@ -8,8 +8,8 @@ #include -#include "BLI_ghash.h" #include "BLI_listbase.h" +#include "BLI_vector_set.hh" #include "BKE_main.hh" #include "BKE_screen.hh" @@ -37,16 +37,45 @@ * \note This follows conventions from #WM_operatortype_find #WM_operatortype_append & friends. * \{ */ -static GHash *global_gizmotype_hash = nullptr; +using blender::StringRef; + +struct GizmoTypePointerHash { + uint64_t operator()(const wmGizmoType *value) const + { + return get_default_hash(StringRef(value->idname)); + } + uint64_t operator()(const StringRef name) const + { + return get_default_hash(name); + } +}; + +struct GizmoTypePointerNameEqual { + bool operator()(const wmGizmoType *a, const wmGizmoType *b) const + { + return STREQ(a->idname, b->idname); + } + bool operator()(const StringRef idname, const wmGizmoType *a) const + { + return a->idname == idname; + } +}; + +static auto &get_gizmo_type_map() +{ + static blender::VectorSet + map; + return map; +} const wmGizmoType *WM_gizmotype_find(const char *idname, bool quiet) { if (idname[0]) { - wmGizmoType *gzt; - - gzt = static_cast(BLI_ghash_lookup(global_gizmotype_hash, idname)); - if (gzt) { - return gzt; + if (wmGizmoType *const *gzt = get_gizmo_type_map().lookup_key_ptr_as(StringRef(idname))) { + return *gzt; } if (!quiet) { @@ -62,11 +91,6 @@ const wmGizmoType *WM_gizmotype_find(const char *idname, bool quiet) return nullptr; } -void WM_gizmotype_iter(GHashIterator *ghi) -{ - BLI_ghashIterator_init(ghi, global_gizmotype_hash); -} - static wmGizmoType *wm_gizmotype_append__begin() { wmGizmoType *gzt = static_cast(MEM_callocN(sizeof(wmGizmoType), "gizmotype")); @@ -84,7 +108,7 @@ static void wm_gizmotype_append__end(wmGizmoType *gzt) RNA_def_struct_identifier(&BLENDER_RNA, gzt->srna, gzt->idname); - BLI_ghash_insert(global_gizmotype_hash, (void *)gzt->idname, gzt); + get_gizmo_type_map().add(gzt); } void WM_gizmotype_append(void (*gtfunc)(wmGizmoType *)) @@ -150,39 +174,35 @@ void WM_gizmotype_remove_ptr(bContext *C, Main *bmain, wmGizmoType *gzt) { BLI_assert(gzt == WM_gizmotype_find(gzt->idname, false)); - BLI_ghash_remove(global_gizmotype_hash, gzt->idname, nullptr, nullptr); + get_gizmo_type_map().remove(gzt); gizmotype_unlink(C, bmain, gzt); } bool WM_gizmotype_remove(bContext *C, Main *bmain, const char *idname) { - wmGizmoType *gzt = static_cast(BLI_ghash_lookup(global_gizmotype_hash, idname)); - + wmGizmoType *const *gzt = get_gizmo_type_map().lookup_key_ptr_as(StringRef(idname)); if (gzt == nullptr) { return false; } - WM_gizmotype_remove_ptr(C, bmain, gzt); + WM_gizmotype_remove_ptr(C, bmain, *gzt); return true; } -static void wm_gizmotype_ghash_free_cb(wmGizmoType *gzt) -{ - WM_gizmotype_free_ptr(gzt); -} - void wm_gizmotype_free() { - BLI_ghash_free(global_gizmotype_hash, nullptr, (GHashValFreeFP)wm_gizmotype_ghash_free_cb); - global_gizmotype_hash = nullptr; + for (wmGizmoType *gzt : get_gizmo_type_map()) { + WM_gizmotype_free_ptr(gzt); + } + get_gizmo_type_map().clear(); } void wm_gizmotype_init() { /* Reserve size is set based on blender default setup. */ - global_gizmotype_hash = BLI_ghash_str_new_ex("wm_gizmotype_init gh", 128); + get_gizmo_type_map().reserve(128); } /** \} */ diff --git a/source/blender/windowmanager/intern/wm_menu_type.cc b/source/blender/windowmanager/intern/wm_menu_type.cc index 596d44ae46e..57df1452c18 100644 --- a/source/blender/windowmanager/intern/wm_menu_type.cc +++ b/source/blender/windowmanager/intern/wm_menu_type.cc @@ -16,8 +16,8 @@ #include "MEM_guardedalloc.h" -#include "BLI_ghash.h" #include "BLI_utildefines.h" +#include "BLI_vector_set.hh" #include "BKE_context.hh" #include "BKE_screen.hh" @@ -26,14 +26,45 @@ #include "WM_api.hh" #include "WM_types.hh" -static GHash *menutypes_hash = nullptr; +using blender::StringRef; + +struct MenuTypePointerHash { + uint64_t operator()(const MenuType *value) const + { + return get_default_hash(StringRef(value->idname)); + } + uint64_t operator()(const StringRef name) const + { + return get_default_hash(name); + } +}; + +struct MenuTypePointerNameEqual { + bool operator()(const MenuType *a, const MenuType *b) const + { + return STREQ(a->idname, b->idname); + } + bool operator()(const StringRef idname, const MenuType *a) const + { + return a->idname == idname; + } +}; + +static auto &get_menu_type_map() +{ + static blender::VectorSet + map; + return map; +} MenuType *WM_menutype_find(const char *idname, bool quiet) { if (idname[0]) { - MenuType *mt = static_cast(BLI_ghash_lookup(menutypes_hash, idname)); - if (mt) { - return mt; + if (MenuType *const *mt = get_menu_type_map().lookup_key_ptr_as(StringRef(idname))) { + return *mt; } } @@ -44,21 +75,22 @@ MenuType *WM_menutype_find(const char *idname, bool quiet) return nullptr; } -void WM_menutype_iter(GHashIterator *ghi) +blender::Span WM_menutypes_registered_get() { - BLI_ghashIterator_init(ghi, menutypes_hash); + return get_menu_type_map(); } bool WM_menutype_add(MenuType *mt) { BLI_assert((mt->description == nullptr) || (mt->description[0])); - BLI_ghash_insert(menutypes_hash, mt->idname, mt); + get_menu_type_map().add(mt); return true; } void WM_menutype_freelink(MenuType *mt) { - bool ok = BLI_ghash_remove(menutypes_hash, mt->idname, nullptr, MEM_freeN); + bool ok = get_menu_type_map().remove(mt); + MEM_freeN(mt); BLI_assert(ok); UNUSED_VARS_NDEBUG(ok); @@ -67,22 +99,18 @@ void WM_menutype_freelink(MenuType *mt) void WM_menutype_init() { /* Reserve size is set based on blender default setup. */ - menutypes_hash = BLI_ghash_str_new_ex("menutypes_hash gh", 512); + get_menu_type_map().reserve(512); } void WM_menutype_free() { - GHashIterator gh_iter; - - GHASH_ITER (gh_iter, menutypes_hash) { - MenuType *mt = static_cast(BLI_ghashIterator_getValue(&gh_iter)); + for (MenuType *mt : get_menu_type_map()) { if (mt->rna_ext.free) { mt->rna_ext.free(mt->rna_ext.data); } + MEM_freeN(mt); } - - BLI_ghash_free(menutypes_hash, nullptr, MEM_freeN); - menutypes_hash = nullptr; + get_menu_type_map().clear(); } bool WM_menutype_poll(bContext *C, MenuType *mt) @@ -108,10 +136,7 @@ void WM_menutype_idname_visit_for_search( const char * /*edit_text*/, blender::FunctionRef visit_fn) { - GHashIterator gh_iter; - GHASH_ITER (gh_iter, menutypes_hash) { - MenuType *mt = static_cast(BLI_ghashIterator_getValue(&gh_iter)); - + for (MenuType *mt : get_menu_type_map()) { StringPropertySearchVisitParams visit_params{}; visit_params.text = mt->idname; visit_params.info = mt->label; diff --git a/source/blender/windowmanager/intern/wm_operator_type.cc b/source/blender/windowmanager/intern/wm_operator_type.cc index c0b9068baeb..2aab2987277 100644 --- a/source/blender/windowmanager/intern/wm_operator_type.cc +++ b/source/blender/windowmanager/intern/wm_operator_type.cc @@ -18,6 +18,7 @@ #include "BLT_translation.hh" #include "BLI_blenlib.h" +#include "BLI_vector_set.hh" #include "BKE_context.hh" #include "BKE_idprop.hh" @@ -45,10 +46,38 @@ static void wm_operatortype_free_macro(wmOperatorType *ot); /** \name Operator Type Registry * \{ */ -static wmOperatorTypeMap &get_operators_map() +using blender::StringRef; + +struct OperatorTypePointerHash { + uint64_t operator()(const wmOperatorType *value) const + { + return get_default_hash(StringRef(value->idname)); + } + uint64_t operator()(const StringRef name) const + { + return get_default_hash(name); + } +}; + +struct OperatorTypePointerNameEqual { + bool operator()(const wmOperatorType *a, const wmOperatorType *b) const + { + return STREQ(a->idname, b->idname); + } + bool operator()(const StringRef idname, const wmOperatorType *a) const + { + return a->idname == idname; + } +}; + +static auto &get_operators_map() { - static wmOperatorTypeMap map = []() { - wmOperatorTypeMap map; + static auto map = []() { + blender::VectorSet + map; /* Reserve size is set based on blender default setup. */ map.reserve(2048); return map; @@ -56,7 +85,7 @@ static wmOperatorTypeMap &get_operators_map() return map; } -const wmOperatorTypeMap &WM_operatortype_map() +blender::Span WM_operatortypes_registered_get() { return get_operators_map(); } @@ -67,15 +96,12 @@ static int ot_prop_basic_count = -1; wmOperatorType *WM_operatortype_find(const char *idname, bool quiet) { if (idname[0]) { - wmOperatorType *ot; - /* Needed to support python style names without the `_OT_` syntax. */ char idname_bl[OP_MAX_TYPENAME]; WM_operator_bl_idname(idname_bl, idname); - ot = get_operators_map().lookup_default_as(idname_bl, nullptr); - if (ot) { - return ot; + if (wmOperatorType *const *ot = get_operators_map().lookup_key_ptr_as(StringRef(idname_bl))) { + return *ot; } if (!quiet) { @@ -128,7 +154,7 @@ static void wm_operatortype_append__end(wmOperatorType *ot) RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname); BLI_assert(WM_operator_bl_idname_is_valid(ot->idname)); - get_operators_map().add_new(ot->idname, ot); + get_operators_map().add_new(ot); } /* All ops in 1 list (for time being... needs evaluation later). */ @@ -171,7 +197,7 @@ void WM_operatortype_remove_ptr(wmOperatorType *ot) wm_operatortype_free_macro(ot); } - get_operators_map().remove(ot->idname); + get_operators_map().remove(ot); WM_keyconfig_update_operatortype(); @@ -211,11 +237,10 @@ static void operatortype_ghash_free_cb(wmOperatorType *ot) void wm_operatortype_free() { - wmOperatorTypeMap &map = get_operators_map(); - for (wmOperatorType *ot : map.values()) { + for (wmOperatorType *ot : get_operators_map()) { operatortype_ghash_free_cb(ot); } - map.clear(); + get_operators_map().clear(); } void WM_operatortype_props_advanced_begin(wmOperatorType *ot) @@ -251,7 +276,7 @@ void WM_operatortype_props_advanced_end(wmOperatorType *ot) void WM_operatortype_last_properties_clear_all() { - for (wmOperatorType *ot : get_operators_map().values()) { + for (wmOperatorType *ot : get_operators_map()) { if (ot->last_properties) { IDP_FreeProperty(ot->last_properties); ot->last_properties = nullptr; @@ -266,7 +291,7 @@ void WM_operatortype_idname_visit_for_search( const char * /*edit_text*/, blender::FunctionRef visit_fn) { - for (wmOperatorType *ot : get_operators_map().values()) { + for (wmOperatorType *ot : get_operators_map()) { char idname_py[OP_MAX_TYPENAME]; WM_operator_py_idname(idname_py, ot->idname); @@ -511,7 +536,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, ot->translation_context = i18n_context; BLI_assert(WM_operator_bl_idname_is_valid(ot->idname)); - get_operators_map().add_new(ot->idname, ot); + get_operators_map().add_new(ot); return ot; } @@ -544,7 +569,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *ot, void *u RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname); BLI_assert(WM_operator_bl_idname_is_valid(ot->idname)); - get_operators_map().add_new(ot->idname, ot); + get_operators_map().add_new(ot); } wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname) diff --git a/source/blender/windowmanager/intern/wm_panel_type.cc b/source/blender/windowmanager/intern/wm_panel_type.cc index 2cfef43689d..809c16219fb 100644 --- a/source/blender/windowmanager/intern/wm_panel_type.cc +++ b/source/blender/windowmanager/intern/wm_panel_type.cc @@ -16,21 +16,52 @@ #include "DNA_windowmanager_types.h" -#include "BLI_ghash.h" #include "BLI_utildefines.h" +#include "BLI_vector_set.hh" #include "BKE_screen.hh" #include "WM_api.hh" -static GHash *g_paneltypes_hash = nullptr; +using blender::StringRef; + +struct PanelTypePointerHash { + uint64_t operator()(const PanelType *value) const + { + return get_default_hash(StringRef(value->idname)); + } + uint64_t operator()(const StringRef name) const + { + return get_default_hash(name); + } +}; + +struct PanelTypePointerNameEqual { + bool operator()(const PanelType *a, const PanelType *b) const + { + return STREQ(a->idname, b->idname); + } + bool operator()(const StringRef idname, const PanelType *a) const + { + return a->idname == idname; + } +}; + +static auto &get_panel_type_map() +{ + static blender::VectorSet + map; + return map; +} PanelType *WM_paneltype_find(const char *idname, bool quiet) { if (idname[0]) { - PanelType *pt = static_cast(BLI_ghash_lookup(g_paneltypes_hash, idname)); - if (pt) { - return pt; + if (PanelType *const *pt = get_panel_type_map().lookup_key_ptr_as(StringRef(idname))) { + return *pt; } } @@ -43,14 +74,13 @@ PanelType *WM_paneltype_find(const char *idname, bool quiet) bool WM_paneltype_add(PanelType *pt) { - BLI_ghash_insert(g_paneltypes_hash, pt->idname, pt); + get_panel_type_map().add(pt); return true; } void WM_paneltype_remove(PanelType *pt) { - const bool ok = BLI_ghash_remove(g_paneltypes_hash, pt->idname, nullptr, nullptr); - + const bool ok = get_panel_type_map().remove(pt); BLI_assert(ok); UNUSED_VARS_NDEBUG(ok); } @@ -58,12 +88,12 @@ void WM_paneltype_remove(PanelType *pt) void WM_paneltype_init() { /* Reserve size is set based on blender default setup. */ - g_paneltypes_hash = BLI_ghash_str_new_ex("g_paneltypes_hash gh", 512); + get_panel_type_map().reserve(512); } void WM_paneltype_clear() { - BLI_ghash_free(g_paneltypes_hash, nullptr, nullptr); + get_panel_type_map().clear(); } void WM_paneltype_idname_visit_for_search( @@ -73,10 +103,7 @@ void WM_paneltype_idname_visit_for_search( const char * /*edit_text*/, blender::FunctionRef visit_fn) { - GHashIterator gh_iter; - GHASH_ITER (gh_iter, g_paneltypes_hash) { - PanelType *pt = static_cast(BLI_ghashIterator_getValue(&gh_iter)); - + for (PanelType *pt : get_panel_type_map()) { StringPropertySearchVisitParams visit_params{}; visit_params.text = pt->idname; visit_params.info = pt->label; diff --git a/source/blender/windowmanager/intern/wm_uilist_type.cc b/source/blender/windowmanager/intern/wm_uilist_type.cc index 22a90714115..1d4a5f0c4fd 100644 --- a/source/blender/windowmanager/intern/wm_uilist_type.cc +++ b/source/blender/windowmanager/intern/wm_uilist_type.cc @@ -20,9 +20,9 @@ #include "UI_interface.hh" -#include "BLI_ghash.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLI_vector_set.hh" #include "BKE_main.hh" #include "BKE_screen.hh" @@ -30,14 +30,45 @@ #include "WM_api.hh" #include "WM_types.hh" -static GHash *uilisttypes_hash = nullptr; +using blender::StringRef; + +struct ListTypePointerHash { + uint64_t operator()(const uiListType *value) const + { + return get_default_hash(StringRef(value->idname)); + } + uint64_t operator()(const StringRef name) const + { + return get_default_hash(name); + } +}; + +struct ListTypePointerNameEqual { + bool operator()(const uiListType *a, const uiListType *b) const + { + return STREQ(a->idname, b->idname); + } + bool operator()(const StringRef idname, const uiListType *a) const + { + return a->idname == idname; + } +}; + +static auto &get_list_type_map() +{ + static blender::VectorSet + map; + return map; +} uiListType *WM_uilisttype_find(const char *idname, bool quiet) { if (idname[0]) { - uiListType *ult = static_cast(BLI_ghash_lookup(uilisttypes_hash, idname)); - if (ult) { - return ult; + if (uiListType *const *ult = get_list_type_map().lookup_key_ptr_as(StringRef(idname))) { + return *ult; } } @@ -50,7 +81,7 @@ uiListType *WM_uilisttype_find(const char *idname, bool quiet) bool WM_uilisttype_add(uiListType *ult) { - BLI_ghash_insert(uilisttypes_hash, ult->idname, ult); + get_list_type_map().add(ult); return true; } @@ -115,7 +146,8 @@ void WM_uilisttype_remove_ptr(Main *bmain, uiListType *ult) { wm_uilisttype_unlink(bmain, ult); - bool ok = BLI_ghash_remove(uilisttypes_hash, ult->idname, nullptr, MEM_freeN); + bool ok = get_list_type_map().remove(ult); + MEM_freeN(ult); BLI_assert(ok); UNUSED_VARS_NDEBUG(ok); @@ -123,21 +155,19 @@ void WM_uilisttype_remove_ptr(Main *bmain, uiListType *ult) void WM_uilisttype_init() { - uilisttypes_hash = BLI_ghash_str_new_ex("uilisttypes_hash gh", 16); + get_list_type_map().reserve(16); } void WM_uilisttype_free() { - GHashIterator gh_iter; - GHASH_ITER (gh_iter, uilisttypes_hash) { - uiListType *ult = static_cast(BLI_ghashIterator_getValue(&gh_iter)); + for (uiListType *ult : get_list_type_map()) { if (ult->rna_ext.free) { ult->rna_ext.free(ult->rna_ext.data); } + MEM_freeN(ult); } - BLI_ghash_free(uilisttypes_hash, nullptr, MEM_freeN); - uilisttypes_hash = nullptr; + get_list_type_map().clear(); } void WM_uilisttype_to_full_list_id(const uiListType *ult,