From 75e97e144cb4279cf2f98225c99776dcab82aa4e Mon Sep 17 00:00:00 2001 From: Gustavo Sverzut Barbieri Date: Wed, 3 Mar 2010 21:37:52 +0000 Subject: [PATCH] postpone module list construction to idler. Create the list later so the dialog shows up immediately and is later populated. The creation of the list is quite expensive, with disk, efreet and later computation of the final list. It seems good now, but if required it could be split a bit more, instead of doing one directory per idle run, do one file. SVN revision: 46843 --- src/bin/e_int_config_modules.c | 91 +++++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 18 deletions(-) diff --git a/src/bin/e_int_config_modules.c b/src/bin/e_int_config_modules.c index f7df6f0..2e1ca84 100644 --- a/src/bin/e_int_config_modules.c +++ b/src/bin/e_int_config_modules.c @@ -37,6 +37,14 @@ struct _E_Config_Dialog_Data Eina_List *loaded, *unloaded; Ecore_Idler *idler; } selected; + + /* just exists while loading: */ + Eina_List *modules_paths; + Eina_List *modules_path_current; + Eina_Hash *types_hash; + Ecore_Timer *data_delay; + Ecore_Idler *data_loader; + Eina_Bool did_modules_list; }; struct _CFTypes @@ -112,6 +120,16 @@ _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) { CFType *cft; + if (cfdata->data_delay) + ecore_timer_del(cfdata->data_delay); + else if (cfdata->data_loader) + ecore_idler_del(cfdata->data_loader); + + if (cfdata->modules_paths) + e_path_dir_list_free(cfdata->modules_paths); + if (cfdata->types_hash) + eina_hash_free(cfdata->types_hash); + EINA_LIST_FREE(cfdata->types, cft) _cftype_free(cft); eina_list_free(cfdata->selected.loaded); @@ -131,7 +149,6 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) of = e_widget_frametable_add(evas, _("Modules"), 0); ol = e_widget_ilist_add(evas, 24, 24, NULL); cfdata->l_modules = ol; - _widget_list_populate(cfdata); e_widget_size_min_get(cfdata->l_modules, &w, NULL); if (w < 200 * e_scale) w = 200 * e_scale; @@ -369,28 +386,66 @@ _types_list_sort(const void *data1, const void *data2) return strcmp(t1->name, t2->name); } -static Eina_Bool -_fill_data(E_Config_Dialog_Data *cfdata) +static int +_fill_data_loader_iterate(void *data) { - Eina_List *mdirs, *l; - E_Path_Dir *epd; - Eina_Hash *types_hash = eina_hash_string_superfast_new(NULL); - if (!types_hash) return EINA_FALSE; - - // TODO: postpone this to idler? segment the job? - /* loop each path_modules dir and load modules for that path */ - mdirs = e_path_dir_list_get(path_modules); - EINA_LIST_FOREACH(mdirs, l, epd) + E_Config_Dialog_Data *cfdata = data; + + if (cfdata->modules_path_current) { - if (!ecore_file_is_dir(epd->dir)) continue; - _load_modules(epd->dir, types_hash); + E_Path_Dir *epd = cfdata->modules_path_current->data; + cfdata->modules_path_current = cfdata->modules_path_current->next; + + if (ecore_file_is_dir(epd->dir)) + _load_modules(epd->dir, cfdata->types_hash); } - if (mdirs) e_path_dir_list_free(mdirs); + else if (!cfdata->did_modules_list) + { + cfdata->did_modules_list = EINA_TRUE; - eina_hash_foreach(types_hash, _types_list_create_foreach_cb, cfdata); - eina_hash_free(types_hash); - cfdata->types = eina_list_sort(cfdata->types, -1, _types_list_sort); + e_path_dir_list_free(cfdata->modules_paths); + cfdata->modules_paths = NULL; + + eina_hash_foreach + (cfdata->types_hash, _types_list_create_foreach_cb, cfdata); + eina_hash_free(cfdata->types_hash); + cfdata->types_hash = NULL; + cfdata->types = eina_list_sort(cfdata->types, -1, _types_list_sort); + } + else + { + _widget_list_populate(cfdata); + cfdata->data_loader = NULL; + return 0; + } + return 1; +} + +static int +_fill_data_delayed(void *data) +{ + E_Config_Dialog_Data *cfdata = data; + cfdata->data_loader = ecore_idler_add(_fill_data_loader_iterate, cfdata); + cfdata->data_delay = NULL; + return 0; +} + +static Eina_Bool +_fill_data(E_Config_Dialog_Data *cfdata) +{ + cfdata->types_hash = eina_hash_string_superfast_new(NULL); + if (!cfdata->types_hash) return EINA_FALSE; + + cfdata->modules_paths = e_path_dir_list_get(path_modules); + if (!cfdata->modules_paths) + { + eina_hash_free(cfdata->types_hash); + cfdata->types_hash = NULL; + return EINA_FALSE; + } + cfdata->modules_path_current = cfdata->modules_paths; + cfdata->data_delay = ecore_timer_add(0.2, _fill_data_delayed, cfdata); return EINA_TRUE; } -- 2.7.4