use ghash for operator and menu types, was doing string lookup in the operator list (containing over 1000 items) for each button draw.

gives small speedup for UI drawing and overall startup time.
This commit is contained in:
Campbell Barton 2011-08-11 06:06:17 +00:00
parent 0fac849d44
commit a7663cc377
10 changed files with 110 additions and 61 deletions

View File

@ -39,6 +39,7 @@
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BKE_animsys.h"
#include "BKE_colortools.h"
@ -2322,10 +2323,11 @@ static void operator_call_cb(bContext *C, void *UNUSED(arg1), void *arg2)
static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
{
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
GHashIterator *iter= WM_operatortype_iter();
for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot= BLI_ghashIterator_getValue(iter);
if(BLI_strcasestr(ot->name, str)) {
if(WM_operator_poll((bContext*)C, ot)) {
char name[256];
@ -2345,6 +2347,7 @@ static void operator_search_cb(const bContext *C, void *UNUSED(arg), const char
}
}
}
BLI_ghashIterator_free(iter);
}
void uiTemplateOperatorSearch(uiLayout *layout)

View File

@ -66,6 +66,8 @@
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BLI_ghash.h"
#include "ED_armature.h"
#include "ED_object.h"
#include "ED_screen.h"
@ -584,9 +586,10 @@ static void operator_call_cb(struct bContext *UNUSED(C), void *arg_kmi, void *ar
static void operator_search_cb(const struct bContext *UNUSED(C), void *UNUSED(arg_kmi), const char *str, uiSearchItems *items)
{
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
GHashIterator *iter= WM_operatortype_iter();
for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot= BLI_ghashIterator_getValue(iter);
if(BLI_strcasestr(ot->idname, str)) {
char name[OP_MAX_TYPENAME];
@ -598,6 +601,7 @@ static void operator_search_cb(const struct bContext *UNUSED(C), void *UNUSED(ar
break;
}
}
BLI_ghashIterator_free(iter);
}
/* operator Search browse menu, open */

View File

@ -46,6 +46,7 @@
#include "BLI_editVert.h"
#include "BLI_rand.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BKE_context.h"
#include "BKE_idprop.h"
@ -140,10 +141,11 @@ static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
{
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
GHashIterator *iter= WM_operatortype_iter();
for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot= BLI_ghashIterator_getValue(iter);
if(BLI_strcasestr(ot->name, str)) {
if(WM_operator_poll((bContext*)C, ot)) {
@ -152,6 +154,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons
}
}
}
BLI_ghashIterator_free(iter);
}

View File

@ -52,6 +52,9 @@
#include "WM_types.h"
#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
#include "BKE_report.h"
#include "BKE_context.h"
@ -359,15 +362,18 @@ static PyObject *pyop_as_string(PyObject *UNUSED(self), PyObject *args)
static PyObject *pyop_dir(PyObject *UNUSED(self))
{
GHashIterator *iter= WM_operatortype_iter();
PyObject *list= PyList_New(0), *name;
wmOperatorType *ot;
for(ot= WM_operatortype_first(); ot; ot= ot->next) {
for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot= BLI_ghashIterator_getValue(iter);
name= PyUnicode_FromString(ot->idname);
PyList_Append(list, name);
Py_DECREF(name);
}
BLI_ghashIterator_free(iter);
return list;
}

View File

@ -179,7 +179,7 @@ void WM_operator_free (struct wmOperator *op);
void WM_operator_stack_clear(struct wmWindowManager *wm);
struct wmOperatorType *WM_operatortype_find(const char *idnamem, int quiet);
struct wmOperatorType *WM_operatortype_first(void);
struct GHashIterator *WM_operatortype_iter(void);
void WM_operatortype_append (void (*opfunc)(struct wmOperatorType*));
void WM_operatortype_append_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
void WM_operatortype_append_macro_ptr (void (*opfunc)(struct wmOperatorType*, void *), void *userdata);
@ -230,6 +230,7 @@ void WM_operator_bl_idname(char *to, const char *from);
void WM_operator_py_idname(char *to, const char *from);
/* *************** menu types ******************** */
void WM_menutype_init(void);
struct MenuType *WM_menutype_find(const char *idname, int quiet);
int WM_menutype_add(struct MenuType* mt);
int WM_menutype_contains(struct MenuType* mt);

View File

@ -423,8 +423,6 @@ typedef struct wmTimer {
typedef struct wmOperatorType {
struct wmOperatorType *next, *prev;
const char *name; /* text for ui, undo */
const char *idname; /* unique identifier */
const char *description; /* tooltips and python docs */

View File

@ -40,7 +40,11 @@
#include "GHOST_C-api.h"
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_ghash.h"
#include "BKE_blender.h"
#include "BKE_context.h"
@ -59,8 +63,6 @@
#include "wm_draw.h"
#include "wm.h"
#include "MEM_guardedalloc.h"
#include "ED_screen.h"
#ifdef WITH_PYTHON
@ -151,14 +153,14 @@ void WM_operator_stack_clear(wmWindowManager *wm)
/* ****************************************** */
static ListBase menutypes = {NULL, NULL}; /* global menutype list */
static GHash *menutypes_hash= NULL;
MenuType *WM_menutype_find(const char *idname, int quiet)
{
MenuType* mt;
if (idname[0]) {
mt= BLI_findstring(&menutypes, idname, offsetof(MenuType, idname));
mt= BLI_ghash_lookup(menutypes_hash, idname);
if(mt)
return mt;
}
@ -171,35 +173,55 @@ MenuType *WM_menutype_find(const char *idname, int quiet)
int WM_menutype_add(MenuType* mt)
{
BLI_addtail(&menutypes, mt);
BLI_ghash_insert(menutypes_hash, (void *)mt->idname, mt);
return 1;
}
/* inefficient but only used for tooltip code */
int WM_menutype_contains(MenuType* mt)
{
return (mt != NULL && BLI_findindex(&menutypes, mt) != -1);
int found= FALSE;
if(mt) {
GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash);
for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
if(mt == BLI_ghashIterator_getValue(iter)) {
found= TRUE;
break;
}
}
BLI_ghashIterator_free(iter);
}
return found;
}
void WM_menutype_freelink(MenuType* mt)
{
BLI_freelinkN(&menutypes, mt);
BLI_ghash_remove(menutypes_hash, mt->idname, NULL, (GHashValFreeFP)MEM_freeN);
}
/* called on initialize WM_init() */
void WM_menutype_init(void)
{
menutypes_hash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "menutypes_hash gh");
}
void WM_menutype_free(void)
{
MenuType* mt= menutypes.first, *mt_next;
GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash);
while(mt) {
mt_next= mt->next;
if(mt->ext.free)
for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
MenuType *mt= BLI_ghashIterator_getValue(iter);
if(mt->ext.free) {
mt->ext.free(mt->ext.data);
WM_menutype_freelink(mt);
mt= mt_next;
}
}
BLI_ghashIterator_free(iter);
BLI_ghash_free(menutypes_hash, NULL, (GHashValFreeFP)MEM_freeN);
menutypes_hash= NULL;
}
/* ****************************************** */

View File

@ -127,7 +127,8 @@ void WM_init(bContext *C, int argc, const char **argv)
}
GHOST_CreateSystemPaths();
wm_operatortype_init();
WM_menutype_init();
set_free_windowmanager_cb(wm_close_and_free); /* library.c */
set_blender_test_break_cb(wm_window_testbreak); /* blender.c */
DAG_editors_update_cb(ED_render_id_flush_update); /* depsgraph.c */

View File

@ -58,6 +58,7 @@
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLO_readfile.h"
@ -100,7 +101,7 @@
#include "wm_subwindow.h"
#include "wm_window.h"
static ListBase global_ops= {NULL, NULL};
static GHash *global_ops_hash= NULL;
/* ************ operator API, exported ********** */
@ -113,7 +114,7 @@ wmOperatorType *WM_operatortype_find(const char *idname, int quiet)
WM_operator_bl_idname(idname_bl, idname);
if (idname_bl[0]) {
ot= (wmOperatorType *)BLI_findstring_ptr(&global_ops, idname_bl, offsetof(wmOperatorType, idname));
ot= BLI_ghash_lookup(global_ops_hash, idname_bl);
if(ot) {
return ot;
}
@ -125,9 +126,10 @@ wmOperatorType *WM_operatortype_find(const char *idname, int quiet)
return NULL;
}
wmOperatorType *WM_operatortype_first(void)
/* caller must free */
GHashIterator *WM_operatortype_iter(void)
{
return global_ops.first;
return BLI_ghashIterator_new(global_ops_hash);
}
/* all ops in 1 list (for time being... needs evaluation later) */
@ -147,7 +149,8 @@ void WM_operatortype_append(void (*opfunc)(wmOperatorType*))
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)"); // XXX All ops should have a description but for now allow them not to.
RNA_def_struct_identifier(ot->srna, ot->idname);
BLI_addtail(&global_ops, ot);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
}
void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType*, void*), void *userdata)
@ -159,7 +162,8 @@ void WM_operatortype_append_ptr(void (*opfunc)(wmOperatorType*, void*), void *us
opfunc(ot, userdata);
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description:"(undocumented operator)");
RNA_def_struct_identifier(ot->srna, ot->idname);
BLI_addtail(&global_ops, ot);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
}
/* ********************* macro operator ******************** */
@ -351,7 +355,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description); // XXX All ops should have a description but for now allow them not to.
RNA_def_struct_identifier(ot->srna, ot->idname);
BLI_addtail(&global_ops, ot);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
return ot;
}
@ -378,7 +382,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType*, void*), vo
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
RNA_def_struct_identifier(ot->srna, ot->idname);
BLI_addtail(&global_ops, ot);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
}
wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname)
@ -426,14 +430,14 @@ int WM_operatortype_remove(const char *idname)
if (ot==NULL)
return 0;
BLI_remlink(&global_ops, ot);
RNA_struct_free(&BLENDER_RNA, ot->srna);
if(ot->macro.first)
wm_operatortype_free_macro(ot);
MEM_freeN(ot);
BLI_ghash_remove(global_ops_hash, (void *)ot->idname, NULL, NULL);
MEM_freeN(ot);
return 1;
}
@ -1311,9 +1315,10 @@ static void operator_call_cb(struct bContext *C, void *UNUSED(arg1), void *arg2)
static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
{
wmOperatorType *ot = WM_operatortype_first();
for(; ot; ot= ot->next) {
GHashIterator *iter= WM_operatortype_iter();
for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
wmOperatorType *ot= BLI_ghashIterator_getValue(iter);
if((ot->flag & OPTYPE_INTERNAL) && (G.f & G_DEBUG) == 0)
continue;
@ -1337,6 +1342,7 @@ static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), cons
}
}
}
BLI_ghashIterator_free(iter);
}
static uiBlock *wm_block_search_menu(bContext *C, ARegion *ar, void *UNUSED(arg_op))
@ -3457,26 +3463,31 @@ static void WM_OT_ndof_sensitivity_change(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "fast", 0, "Fast NDOF sensitivity change", "If true then sensitivity changes 50%, otherwise 10%");
}
static void operatortype_ghash_free_cb(wmOperatorType *ot)
{
if(ot->macro.first)
wm_operatortype_free_macro(ot);
if(ot->ext.srna) /* python operator, allocs own string */
MEM_freeN((void *)ot->idname);
MEM_freeN(ot);
}
/* ******************************************************* */
/* called on initialize WM_exit() */
void wm_operatortype_free(void)
{
wmOperatorType *ot;
for(ot= global_ops.first; ot; ot= ot->next) {
if(ot->macro.first)
wm_operatortype_free_macro(ot);
if(ot->ext.srna) /* python operator, allocs own string */
MEM_freeN((void *)ot->idname);
}
BLI_freelistN(&global_ops);
BLI_ghash_free(global_ops_hash, NULL, (GHashValFreeFP)operatortype_ghash_free_cb);
global_ops_hash= NULL;
}
/* called on initialize WM_init() */
void wm_operatortype_init(void)
{
global_ops_hash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wm_operatortype_init gh");
WM_operatortype_append(WM_OT_window_duplicate);
WM_operatortype_append(WM_OT_read_homefile);
WM_operatortype_append(WM_OT_read_factory_settings);

View File

@ -384,7 +384,7 @@ void RE_engine_report(struct RenderEngine *engine, int type, const char *msg) {}
/* python */
struct wmOperatorType *WM_operatortype_find(const char *idname, int quiet){return (struct wmOperatorType *) NULL;}
struct wmOperatorType *WM_operatortype_first(){return (struct wmOperatorType *) NULL;}
struct GHashIterator *WM_operatortype_iter(){return (struct GHashIterator *) NULL;}
struct wmOperatorType *WM_operatortype_exists(const char *idname){return (struct wmOperatorType *) NULL;}
struct wmOperatorTypeMacro *WM_operatortype_macro_define(struct wmOperatorType *ot, const char *idname){return (struct wmOperatorTypeMacro *) NULL;}
int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int context, struct PointerRNA *properties, struct ReportList *reports){return 0;}