Enlightenment CVS committal Author : raster Project : e17 Module : apps/e
Dir : e17/apps/e/src/bin Modified Files: e_apps.c e_apps.h e_apps_cache.c e_apps_cache.h Log Message: a start on the eap cache - it can load and save right now but not update once saved. its disabled atm. BUT i have reduced the data needing to be loaded at startup from opening 200 eap files totalling something like 6.5Mb of disk space used (though actual loads will be less - likely), down to loading 1 file of about 7kb and doing a stat or 2 on each file (my next phase is to remove the stat on startup here and cache that info too, and then add in the code to have e slowly run over the cache data and match it up against real life data and see if its still valid or not etc. and write it out as well as make sure new caches are written out whenever eapp dirs change, and then finally make a cmd-line tool to do it per dir) =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/e/src/bin/e_apps.c,v retrieving revision 1.67 retrieving revision 1.68 diff -u -3 -r1.67 -r1.68 --- e_apps.c 15 Sep 2005 06:25:28 -0000 1.67 +++ e_apps.c 24 Sep 2005 17:25:48 -0000 1.68 @@ -32,8 +32,6 @@ static void _e_app_free (E_App *a); static void _e_app_fields_fill (E_App *a, const char *path); -static void _e_app_fields_empty (E_App *a); -static Ecore_List *_e_app_dir_file_list_get (E_App *a); static E_App *_e_app_subapp_file_find (E_App *a, const char *file); static void _e_app_change (E_App *a, E_App_Change ch); static int _e_apps_cb_exit (void *data, int type, void *event); @@ -66,6 +64,7 @@ char *home; char buf[PATH_MAX]; + e_app_cache_init(); home = e_user_homedir_get(); snprintf(buf, sizeof(buf), "%s/.e/e/applications/trash", home); _e_apps_path_trash = strdup(buf); @@ -114,15 +113,124 @@ printf("BUG: References %d %s\n", E_OBJECT(a)->references, a->path); } } + e_app_cache_shutdown(); return 1; } E_App * -e_app_new(const char *path, int scan_subdirs) +e_app_raw_new(void) { E_App *a; + + a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); + return a; +} + +static void +_e_app_cache_copy(E_App_Cache *ac, E_App *a) +{ +#define IF_DUP(x) if (ac->x) a->x = strdup(ac->x) + IF_DUP(name); + IF_DUP(generic); + IF_DUP(comment); + IF_DUP(exe); + IF_DUP(win_name); + IF_DUP(win_class); + IF_DUP(win_title); + IF_DUP(win_role); + IF_DUP(icon_class); + a->startup_notify = ac->startup_notify; + a->wait_exit = ac->wait_exit; +} + +static E_App * +_e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs) +{ + Evas_List *l; + E_App *a; char buf[PATH_MAX]; + + a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); + _e_app_cache_copy(ac, a); + a->path = strdup(path); + a->scanned = 1; + for (l = ac->subapps; l; l = l->next) + { + E_App_Cache *ac2; + E_App *a2; + int is_dir; + + ac2 = l->data; + snprintf(buf, sizeof(buf), "%s/%s", path, ac2->file); + is_dir = ecore_file_is_dir(buf); + if ((is_dir) && (scan_subdirs)) + { + a2 = e_app_new(buf, scan_subdirs); + a2->parent = a; + a->subapps = evas_list_append(a->subapps, a2); + } + else + { + if (ecore_file_exists(buf)) + { + a2 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); + _e_app_cache_copy(ac2, a2); + if (is_dir) + { + E_FREE(a2->exe); + } + a2->parent = a; + a2->path = strdup(buf); + a->subapps = evas_list_append(a->subapps, a2); + _e_apps = evas_hash_add(_e_apps, a2->path, a2); + _e_apps_list = evas_list_prepend(_e_apps_list, a2); + } + else + { + E_App *a3; + Evas_List *pl; + pl = _e_apps_repositories; + a2 = NULL; + while ((!a2) && (pl)) + { + snprintf(buf, sizeof(buf), "%s/%s", (char *)pl->data, ac2->file); + a2 = e_app_new(buf, scan_subdirs); + pl = pl->next; + } + if (a2) + { + a3 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); + if (a3) + { + if (_e_app_copy(a3, a2)) + { + a3->parent = a; + a->subapps = evas_list_append(a->subapps, a3); + a2->references = evas_list_append(a2->references, a3); + } + else + e_object_del(E_OBJECT(a3)); + } + } + } + } + } + + /* FIXME: create timer object to scan this slowly and fixup */ + + // and at the end of the slow scan add this: + // a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a); + return a; +} + +E_App * +e_app_new(const char *path, int scan_subdirs) +{ + E_App *a; + char buf[PATH_MAX]; + E_App_Cache *ac; + a = evas_hash_find(_e_apps, path); if (a) { @@ -131,46 +239,64 @@ e_object_ref(E_OBJECT(a)); return a; } - - if (ecore_file_exists(path)) +/* + ac = e_app_cache_load((char *)path); + if (ac) { - a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); - /* record the path */ - a->path = strdup(path); - - if (ecore_file_is_dir(a->path)) + a = _e_app_cache_new(ac, path, scan_subdirs); + if (a) { - snprintf(buf, sizeof(buf), "%s/.directory.eap", path); - if (ecore_file_exists(buf)) - _e_app_fields_fill(a, buf); - else - a->name = strdup(ecore_file_get_file(a->path)); - if (scan_subdirs) e_app_subdir_scan(a, scan_subdirs); - - a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a); + _e_apps = evas_hash_add(_e_apps, a->path, a); + _e_apps_list = evas_list_prepend(_e_apps_list, a); } - else if (_e_app_is_eapp(path)) + e_app_cache_free(ac); + } + else + */ + { + if (ecore_file_exists(path)) { - _e_app_fields_fill(a, path); - - /* no exe field.. not valid. drop it */ - if (!a->exe) + a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free); + /* record the path */ + a->path = strdup(path); + + if (ecore_file_is_dir(a->path)) + { + snprintf(buf, sizeof(buf), "%s/.directory.eap", path); + if (ecore_file_exists(buf)) + e_app_fields_fill(a, buf); + else + a->name = strdup(ecore_file_get_file(a->path)); + if (scan_subdirs) e_app_subdir_scan(a, scan_subdirs); + + a->monitor = ecore_file_monitor_add(a->path, _e_app_cb_monitor, a); + } + else if (_e_app_is_eapp(path)) + { + e_app_fields_fill(a, path); + + /* no exe field.. not valid. drop it */ + if (!a->exe) + goto error; + } + else goto error; } else - goto error; + return NULL; + _e_apps = evas_hash_add(_e_apps, a->path, a); + _e_apps_list = evas_list_prepend(_e_apps_list, a); + + ac = e_app_cache_generate(a); + e_app_cache_save(ac, a->path); + e_app_cache_free(ac); } - else - return NULL; - - _e_apps = evas_hash_add(_e_apps, a->path, a); - _e_apps_list = evas_list_prepend(_e_apps_list, a); return a; error: if (a->monitor) ecore_file_monitor_del(a->monitor); if (a->path) free(a->path); - _e_app_fields_empty(a); + e_app_fields_empty(a); free(a); return NULL; } @@ -198,7 +324,8 @@ Ecore_List *files; char *s; char buf[PATH_MAX]; - + E_App_Cache *ac; + E_OBJECT_CHECK(a); E_OBJECT_TYPE_CHECK(a, E_APP_TYPE); if (a->exe) return; @@ -212,7 +339,7 @@ return; } a->scanned = 1; - files = _e_app_dir_file_list_get(a); + files = e_app_dir_file_list_get(a); if (files) { while ((s = ecore_list_next(files))) @@ -263,6 +390,10 @@ } ecore_list_destroy(files); } + + ac = e_app_cache_generate(a); + e_app_cache_save(ac, a->path); + e_app_cache_free(ac); } int @@ -766,14 +897,14 @@ ecore_file_monitor_del(a->monitor); _e_apps = evas_hash_del(_e_apps, a->path, a); _e_apps_list = evas_list_remove(_e_apps_list, a); - _e_app_fields_empty(a); + e_app_fields_empty(a); E_FREE(a->path); free(a); } } -static void -_e_app_fields_fill(E_App *a, const char *path) +void +e_app_fields_fill(E_App *a, const char *path) { Eet_File *ef; char buf[PATH_MAX]; @@ -912,8 +1043,8 @@ eet_close(ef); } -static void -_e_app_fields_empty(E_App *a) +void +e_app_fields_empty(E_App *a) { E_FREE(a->name); E_FREE(a->generic); @@ -926,8 +1057,8 @@ E_FREE(a->win_role); } -static Ecore_List * -_e_app_dir_file_list_get(E_App *a) +Ecore_List * +e_app_dir_file_list_get(E_App *a) { Ecore_List *files, *files2; char *file; @@ -1137,13 +1268,13 @@ if ((event == ECORE_FILE_EVENT_CREATED_FILE) || (event == ECORE_FILE_EVENT_MODIFIED)) { - _e_app_fields_empty(app); - _e_app_fields_fill(app, path); + e_app_fields_empty(app); + e_app_fields_fill(app, path); _e_app_change(app, E_APP_CHANGE); } else if (event == ECORE_FILE_EVENT_DELETED_FILE) { - _e_app_fields_empty(app); + e_app_fields_empty(app); app->name = strdup(ecore_file_get_file(app->path)); } else @@ -1162,8 +1293,8 @@ { Evas_List *l; - _e_app_fields_empty(a2); - _e_app_fields_fill(a2, path); + e_app_fields_empty(a2); + e_app_fields_fill(a2, path); _e_app_change(a2, E_APP_CHANGE); for (l = a2->references; l; l = l->next) @@ -1240,7 +1371,7 @@ char buf[PATH_MAX]; char *s; - files = _e_app_dir_file_list_get(app); + files = e_app_dir_file_list_get(app); if (files) { while ((s = ecore_list_next(files))) =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/e/src/bin/e_apps.h,v retrieving revision 1.19 retrieving revision 1.20 diff -u -3 -r1.19 -r1.20 --- e_apps.h 14 Sep 2005 06:39:59 -0000 1.19 +++ e_apps.h 24 Sep 2005 17:25:48 -0000 1.20 @@ -96,6 +96,11 @@ EAPI E_App *e_app_name_find(char *name); EAPI E_App *e_app_generic_find(char *generic); EAPI E_App *e_app_exe_find(char *exe); + +EAPI void e_app_fields_fill(E_App *a, const char *path); +EAPI E_App *e_app_raw_new(void); +EAPI Ecore_List *e_app_dir_file_list_get(E_App *a); +EAPI void e_app_fields_empty(E_App *a); #endif #endif =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/e/src/bin/e_apps_cache.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- e_apps_cache.c 24 Sep 2005 10:29:31 -0000 1.1 +++ e_apps_cache.c 24 Sep 2005 17:25:48 -0000 1.2 @@ -2,3 +2,229 @@ * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #include "e.h" + +#define NEWD(str, typ) \ + eet_data_descriptor_new(str, sizeof(typ), \ + (void *(*) (void *))evas_list_next, \ + (void *(*) (void *, void *))evas_list_append, \ + (void *(*) (void *))evas_list_data, \ + (void *(*) (void *))evas_list_free, \ + (void (*) (void *, int (*) (void *, const char *, void *, void *), void *))evas_hash_foreach, \ + (void *(*) (void *, const char *, void *))evas_hash_add, \ + (void (*) (void *))evas_hash_free) + +#define FREED(eed) \ + if (eed) \ + { \ + eet_data_descriptor_free((eed)); \ + (eed) = NULL; \ + } +#define NEWI(str, it, type) \ + EET_DATA_DESCRIPTOR_ADD_BASIC(_e_app_cache_edd, E_App_Cache, str, it, type) +#define NEWL(str, it, type) \ + EET_DATA_DESCRIPTOR_ADD_LIST(_e_app_cache_edd, E_App_Cache, str, it, type) + +static void _e_eapp_cache_fill(E_App_Cache *ac, E_App *a); + +static Eet_Data_Descriptor *_e_app_cache_edd = NULL; + +int +e_app_cache_init(void) +{ + _e_app_cache_edd = NEWD("E_App_Cache", E_App_Cache); + NEWI("nm", name, EET_T_STRING); + NEWI("gn", generic, EET_T_STRING); + NEWI("cm", comment, EET_T_STRING); + NEWI("ex", exe, EET_T_STRING); + NEWI("fl", file, EET_T_STRING); + NEWI("fm", file_mod_time, EET_T_ULONG_LONG); + NEWI("wn", win_name, EET_T_STRING); + NEWI("wc", win_class, EET_T_STRING); + NEWI("wt", win_title, EET_T_STRING); + NEWI("wr", win_role, EET_T_STRING); + NEWI("ic", icon_class, EET_T_STRING); + NEWL("ap", subapps, _e_app_cache_edd); + NEWI("sn", startup_notify, EET_T_UCHAR); + NEWI("wx", wait_exit, EET_T_UCHAR); + return 1; +} + +int +e_app_cache_shutdown(void) +{ + FREED(_e_app_cache_edd); + return 1; +} + +E_App_Cache * +e_app_cache_load(char *path) +{ + Eet_File *ef; + char buf[PATH_MAX]; + E_App_Cache *ac; + + if (!path) return NULL; + snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", path); + ef = eet_open(buf, EET_FILE_MODE_READ); + if (!ef) return NULL; + ac = eet_data_read(ef, _e_app_cache_edd, "cache"); + eet_close(ef); + return ac; +} + +E_App_Cache * +e_app_cache_generate(E_App *a) +{ + E_App_Cache *ac; + Evas_List *l; + + if (!a) return NULL; + ac = calloc(1, sizeof(E_App_Cache)); + if (!ac) return NULL; + _e_eapp_cache_fill(ac, a); + for (l = a->subapps; l; l = l->next) + { + E_App *a2; + E_App_Cache *ac2; + + a2 = l->data; + ac2 = calloc(1, sizeof(E_App_Cache)); + if (ac2) + { + _e_eapp_cache_fill(ac2, a2); + ac->subapps = evas_list_append(ac->subapps, ac2); + ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2); + } + } + return ac; +} + +E_App_Cache * +e_app_cache_path_generate(char *path) +{ + E_App_Cache *ac; + E_App *a; + char buf[PATH_MAX]; + Ecore_List *files; + + if (!path) return NULL; + ac = calloc(1, sizeof(E_App_Cache)); + if (!ac) return NULL; + a = e_app_raw_new(); + a->path = strdup(path); + _e_eapp_cache_fill(ac, a); + if (ecore_file_is_dir(a->path)) + { + snprintf(buf, sizeof(buf), "%s/.directory.eap", path); + if (ecore_file_exists(buf)) + e_app_fields_fill(a, buf); + else + a->name = strdup(ecore_file_get_file(a->path)); + + files = e_app_dir_file_list_get(a); + if (files) + { + char *s = NULL; + + while ((s = ecore_list_next(files))) + { + E_App *a2; + E_App_Cache *ac2; + + ac2 = calloc(1, sizeof(E_App_Cache)); + if (ac2) + { + a2 = e_app_raw_new(); + if (a2) + { + snprintf(buf, sizeof(buf), "%s/%s", a->path, s); + a2->path = strdup(buf); + if (ecore_file_is_dir(a2->path)) + { + snprintf(buf, sizeof(buf), "%s/.directory.eap", a2->path); + e_app_fields_fill(a2, buf); + } + else + e_app_fields_fill(a2, a2->path); + _e_eapp_cache_fill(ac2, a2); + e_app_fields_empty(a2); + free(a2); + } + ac->subapps = evas_list_append(ac->subapps, ac2); + ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2); + } + } + ecore_list_destroy(files); + } + } + e_app_fields_empty(a); + free(a); + + return ac; +} + +void +e_app_cache_free(E_App_Cache *ac) +{ + if (!ac) return; + E_FREE(ac->name); + E_FREE(ac->generic); + E_FREE(ac->comment); + E_FREE(ac->exe); + E_FREE(ac->file); + E_FREE(ac->win_name); + E_FREE(ac->win_class); + E_FREE(ac->win_title); + E_FREE(ac->win_role); + E_FREE(ac->icon_class); + while (ac->subapps) + { + E_App_Cache *ac2; + + ac2 = ac->subapps->data; + ac->subapps = evas_list_remove_list(ac->subapps, ac->subapps); + e_app_cache_free(ac2); + } + evas_hash_free(ac->subapps_hash); + free(ac); +} + + + +int +e_app_cache_save(E_App_Cache *ac, char *path) +{ + Eet_File *ef; + char buf[4096]; + int ret; + + if ((!ac) || (!path)) return 0; + snprintf(buf, sizeof(buf), "%s/.eap.cache.cfg", path); + ef = eet_open(buf, EET_FILE_MODE_WRITE); + if (!ef) return 0; + ret = eet_data_write(ef, _e_app_cache_edd, "cache", ac, 1); + eet_close(ef); + return ret; +} + + + +static void +_e_eapp_cache_fill(E_App_Cache *ac, E_App *a) +{ +#define IF_DUP(x) if (a->x) ac->x = strdup(a->x) + IF_DUP(name); + IF_DUP(generic); + IF_DUP(comment); + IF_DUP(exe); + ac->file = strdup(ecore_file_get_file(a->path)); + ac->file_mod_time = ecore_file_mod_time(a->path); + IF_DUP(win_name); + IF_DUP(win_class); + IF_DUP(win_title); + IF_DUP(win_role); + IF_DUP(icon_class); + ac->startup_notify = a->startup_notify; + ac->wait_exit = a->wait_exit; +} + =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/e/src/bin/e_apps_cache.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- e_apps_cache.h 24 Sep 2005 10:29:31 -0000 1.1 +++ e_apps_cache.h 24 Sep 2005 17:25:48 -0000 1.2 @@ -3,9 +3,46 @@ */ #ifdef E_TYPEDEFS +typedef struct _E_App_Cache E_App_Cache; + #else #ifndef E_APPS_CACHE_H -#define E_APPS_CAHCE_H - +#define E_APPS_CACHE_H + +struct _E_App_Cache +{ + char *name; /* app name */ + char *generic; /* generic app name */ + char *comment; /* a longer description */ + char *exe; /* command to execute, NULL if directory */ + + char *file; /* the .eap filename */ + unsigned long long file_mod_time; /* the last modified time of the file */ + + char *win_name; /* window name */ + char *win_class; /* window class */ + char *win_title; /* window title */ + char *win_role; /* window role */ + + char *icon_class; /* icon_class */ + + Evas_List *subapps; /* if this a directory, a list of more E_App's */ + + unsigned char startup_notify; /* disable while starting etc. */ + unsigned char wait_exit; /* wait for app to exit before execing next */ + + /* these are generated post-load */ + Evas_Hash *subapps_hash; /* a quick lookup hash */ +}; + +EAPI int e_app_cache_init(void); +EAPI int e_app_cache_shutdown(void); + +EAPI E_App_Cache *e_app_cache_load(char *path); +EAPI E_App_Cache *e_app_cache_generate(E_App *a); +EAPI E_App_Cache *e_app_cache_path_generate(char *path); +EAPI void e_app_cache_free(E_App_Cache *ac); +EAPI int e_app_cache_save(E_App_Cache *ac, char *path); + #endif #endif ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs