eapp cache works - or well, should. it should update the caches if dirs

change contents or files change etc. etc. etc. theres also a cmd-line util
that can pre-generate caches for a directory or a dir tree for you :)


SVN revision: 16926
This commit is contained in:
Carsten Haitzler 2005-09-25 04:58:18 +00:00
parent de28ccb8ed
commit 29ee91dd3c
7 changed files with 302 additions and 102 deletions

View File

@ -8,7 +8,11 @@ INCLUDES = -I$(includedir) \
@cf_cflags@ \
@EDJE_DEF@
bin_PROGRAMS = enlightenment enlightenment_remote enlightenment_eapp
bin_PROGRAMS = \
enlightenment \
enlightenment_remote \
enlightenment_eapp \
enlightenment_eapp_cache_gen
ENLIGHTENMENTHEADERS = \
e.h \
@ -32,7 +36,6 @@ e_menu.h \
e_object.h \
e_icon.h \
e_box.h \
e_entry.h \
e_int_menus.h \
e_module.h \
e_apps.h \
@ -74,10 +77,10 @@ e_dialog.h \
e_configure.h \
e_about.h \
e_theme_about.h \
e_apps_cache.h
e_apps_cache.h \
e_entry.h
enlightenment_SOURCES = \
e_main.c \
enlightenment_src = \
e_user.c \
e_manager.c \
e_path.c \
@ -94,7 +97,6 @@ e_menu.c \
e_object.c \
e_icon.c \
e_box.c \
e_entry.c \
e_int_menus.c \
e_module.c \
e_apps.c \
@ -137,8 +139,13 @@ e_configure.c \
e_about.c \
e_theme_about.c \
e_apps_cache.c \
e_entry.c \
$(ENLIGHTENMENTHEADERS)
enlightenment_SOURCES = \
e_main.c \
$(enlightenment_src)
enlightenment_LDFLAGS = -export-dynamic @e_libs@ @x_libs@ @dlopen_libs@ @cf_libs@
enlightenment_remote_SOURCES = \
@ -154,6 +161,13 @@ e_eapp_main.c
enlightenment_eapp_LDFLAGS = @e_libs@ @dlopen_libs@
enlightenment_eapp_cache_gen_SOURCES = \
e_eapp_cache_gen_main.c \
$(enlightenment_src)
enlightenment_eapp_cache_gen_LDFLAGS = @e_libs@ @dlopen_libs@
installed_headersdir = $(prefix)/include/enlightenment
installed_headers_DATA = $(ENLIGHTENMENTHEADERS)

View File

@ -16,6 +16,7 @@
/* local subsystem functions */
typedef struct _E_App_Change_Info E_App_Change_Info;
typedef struct _E_App_Callback E_App_Callback;
typedef struct _E_App_Scan_Cache E_App_Scan_Cache;
struct _E_App_Change_Info
{
@ -30,6 +31,16 @@ struct _E_App_Callback
unsigned char delete_me : 1;
};
struct _E_App_Scan_Cache
{
char *path;
E_App_Cache *cache;
E_App *app;
Ecore_List *files;
Ecore_Timer *timer;
unsigned char need_rewrite : 1;
};
static void _e_app_free (E_App *a);
static void _e_app_fields_fill (E_App *a, const char *path);
static E_App *_e_app_subapp_file_find (E_App *a, const char *file);
@ -143,12 +154,92 @@ _e_app_cache_copy(E_App_Cache *ac, E_App *a)
a->wait_exit = ac->wait_exit;
}
Evas_Bool
_e_app_cb_scan_hash_foreach(Evas_Hash *hash, const char *key, void *data, void *fdata)
{
E_App_Scan_Cache *sc;
E_App_Cache *ac;
char *s;
char buf[4096];
sc = fdata;
s = (char *)key;
ac = data;
/* file "s" has been deleted */
printf("Cache %s - DELETED\n", s);
sc->need_rewrite = 1;
return 1;
}
static int
_e_app_cb_scan_cache_timer(void *data)
{
E_App_Scan_Cache *sc;
char *s;
char buf[4096];
E_App_Cache *ac;
int is_dir = 0;
sc = data;
s = ecore_list_next(sc->files);
if (!s)
{
evas_hash_foreach(sc->cache->subapps_hash, _e_app_cb_scan_hash_foreach, sc);
if (sc->need_rewrite)
_e_app_subdir_rescan(sc->app);
sc->app->monitor = ecore_file_monitor_add(sc->app->path, _e_app_cb_monitor, sc->app);
e_object_unref(E_OBJECT(sc->app));
ecore_list_destroy(sc->files);
e_app_cache_free(sc->cache);
ecore_timer_del(sc->timer);
free(sc->path);
free(sc);
printf("Cache scan finish.\n");
return 0;
}
snprintf(buf, sizeof(buf), "%s/%s", sc->path, s);
is_dir = ecore_file_is_dir(buf);
if (e_util_glob_match(s, "*.eap") || is_dir)
{
ac = evas_hash_find(sc->cache->subapps_hash, s);
if (ac)
{
if (is_dir != ac->is_dir)
{
printf("Cache %s - CHANGED TYPE\n", s);
sc->need_rewrite =1 ;
}
else if (!is_dir)
{
unsigned long long mtime;
mtime = ecore_file_mod_time(buf);
if (mtime != ac->file_mod_time)
{
/* file "s" has changed */
printf("Cache %s - MODIFIED\n", s);
sc->need_rewrite = 1;
}
}
sc->cache->subapps_hash = evas_hash_del(sc->cache->subapps_hash, s, ac);
}
else
{
/* file "s" has been added */
printf("Cache %s - MODIFIED\n", s);
sc->need_rewrite = 1;
}
}
return 1;
}
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];
E_App_Scan_Cache *sc;
a = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
_e_app_cache_copy(ac, a);
@ -158,12 +249,10 @@ _e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs)
{
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))
if ((ac2->is_dir) && (scan_subdirs))
{
a2 = e_app_new(buf, scan_subdirs);
a2->parent = a;
@ -171,11 +260,11 @@ _e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs)
}
else
{
if (ecore_file_exists(buf))
if (!ac2->is_link)
{
a2 = E_OBJECT_ALLOC(E_App, E_APP_TYPE, _e_app_free);
_e_app_cache_copy(ac2, a2);
if (is_dir)
if (ac2->is_dir)
{
E_FREE(a2->exe);
}
@ -216,11 +305,19 @@ _e_app_cache_new(E_App_Cache *ac, char *path, int scan_subdirs)
}
}
}
/* 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);
sc = calloc(1, sizeof(E_App_Scan_Cache));
if (sc)
{
sc->path = strdup(path);
sc->cache = ac;
sc->app = a;
sc->files = e_app_dir_file_list_get(a);
sc->timer = ecore_timer_add(0.001, _e_app_cb_scan_cache_timer, sc);
e_object_ref(E_OBJECT(sc->app));
}
else
e_app_cache_free(ac);
return a;
}
@ -239,20 +336,19 @@ e_app_new(const char *path, int scan_subdirs)
e_object_ref(E_OBJECT(a));
return a;
}
/*
ac = e_app_cache_load((char *)path);
if (ac)
{
a = _e_app_cache_new(ac, path, scan_subdirs);
a = _e_app_cache_new(ac, (char *)path, scan_subdirs);
if (a)
{
_e_apps = evas_hash_add(_e_apps, a->path, a);
_e_apps_list = evas_list_prepend(_e_apps_list, a);
}
e_app_cache_free(ac);
// e_app_cache_free(ac);
}
else
*/
{
if (ecore_file_exists(path))
{
@ -1480,6 +1576,14 @@ _e_app_subdir_rescan(E_App *app)
e_object_unref(E_OBJECT(ch->app));
free(ch);
}
if (changes)
{
E_App_Cache *ac;
ac = e_app_cache_generate(app);
e_app_cache_save(ac, app->path);
e_app_cache_free(ac);
}
evas_list_free(changes);
}

View File

@ -46,6 +46,8 @@ e_app_cache_init(void)
NEWL("ap", subapps, _e_app_cache_edd);
NEWI("sn", startup_notify, EET_T_UCHAR);
NEWI("wx", wait_exit, EET_T_UCHAR);
NEWI("il", is_link, EET_T_UCHAR);
NEWI("id", is_dir, EET_T_UCHAR);
return 1;
}
@ -69,6 +71,18 @@ e_app_cache_load(char *path)
if (!ef) return NULL;
ac = eet_data_read(ef, _e_app_cache_edd, "cache");
eet_close(ef);
if (ac)
{
Evas_List *l;
for (l = ac->subapps; l; l = l->next)
{
E_App_Cache *ac2;
ac2 = l->data;
ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2);
}
}
return ac;
}
@ -77,6 +91,7 @@ e_app_cache_generate(E_App *a)
{
E_App_Cache *ac;
Evas_List *l;
char buf[PATH_MAX];
if (!a) return NULL;
ac = calloc(1, sizeof(E_App_Cache));
@ -92,6 +107,11 @@ e_app_cache_generate(E_App *a)
if (ac2)
{
_e_eapp_cache_fill(ac2, a2);
ac2->is_dir = ecore_file_is_dir(a2->path);
snprintf(buf, sizeof(buf), "%s/%s", a->path, ecore_file_get_file(a2->path));
if (a2->orig) ac2->is_link = 1;
if ((!ac2->is_link) && (!ac2->is_dir))
ac2->file_mod_time = ecore_file_mod_time(buf);
ac->subapps = evas_list_append(ac->subapps, ac2);
ac->subapps_hash = evas_hash_add(ac->subapps_hash, ac2->file, ac2);
}
@ -99,70 +119,6 @@ e_app_cache_generate(E_App *a)
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)
{
@ -189,8 +145,6 @@ e_app_cache_free(E_App_Cache *ac)
free(ac);
}
int
e_app_cache_save(E_App_Cache *ac, char *path)
{
@ -218,7 +172,6 @@ _e_eapp_cache_fill(E_App_Cache *ac, E_App *a)
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);
@ -227,4 +180,3 @@ _e_eapp_cache_fill(E_App_Cache *ac, E_App *a)
ac->startup_notify = a->startup_notify;
ac->wait_exit = a->wait_exit;
}

View File

@ -30,6 +30,9 @@ struct _E_App_Cache
unsigned char startup_notify; /* disable while starting etc. */
unsigned char wait_exit; /* wait for app to exit before execing next */
unsigned char is_link; /* cached .order logic info */
unsigned char is_dir; /* cached stat info */
/* these are generated post-load */
Evas_Hash *subapps_hash; /* a quick lookup hash */
@ -40,7 +43,6 @@ 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);

View File

@ -0,0 +1,128 @@
/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
static void _e_gen_cache(char *path, int recurse);
static int _e_cb_signal_exit(void *data, int ev_type, void *ev);
static void _e_help(void);
/* local subsystem globals */
int
main(int argc, char **argv)
{
int i;
char *dir = NULL;
int recurse = 0;
for (i = 1; i < argc; i++)
{
if ((!strcmp(argv[i], "-h")) ||
(!strcmp(argv[i], "-help")) ||
(!strcmp(argv[i], "--h")) ||
(!strcmp(argv[i], "--help")))
{
_e_help();
exit(0);
}
else if (!strcmp(argv[i], "-r"))
{
recurse = 1;
}
else
{
dir = argv[i];
}
}
if (!dir)
{
printf("ERROR: No directory specified!\n");
_e_help();
exit(0);
}
/* basic ecore init */
if (!ecore_init())
{
printf("ERROR: Enlightenment_eapp_cache_gen cannot Initialize Ecore!\n"
"Perhaps you are out of memory?\n");
exit(-1);
}
ecore_app_args_set((int)argc, (const char **)argv);
/* setup a handler for when e is asked to exit via a system signal */
if (!ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, _e_cb_signal_exit, NULL))
{
printf("ERROR: Enlightenment_eapp_cache_gen cannot set up an exit signal handler.\n"
"Perhaps you are out of memory?\n");
exit(-1);
}
e_app_init();
_e_gen_cache(dir, recurse);
e_app_shutdown();
ecore_shutdown();
/* just return 0 to keep the compiler quiet */
return 0;
}
static void
_e_gen_cache(char *path, int recurse)
{
E_App_Cache *ac;
E_App *a;
char buf[PATH_MAX], *file;
a = e_app_new(path, recurse);
if (!a) return;
ac = e_app_cache_generate(a);
if (!ac) return;
e_app_cache_save(ac, path);
e_app_cache_free(ac);
if (recurse)
{
Ecore_List *files;
files = ecore_file_ls(path);
if (files)
{
ecore_list_goto_first(files);
while ((file = ecore_list_next(files)))
{
if (file[0] != '.')
{
snprintf(buf, sizeof(buf), "%s/%s", path, file);
if (ecore_file_is_dir(buf)) _e_gen_cache(buf, recurse);
}
}
ecore_list_destroy(files);
}
}
return;
}
/* local subsystem functions */
static int
_e_cb_signal_exit(void *data, int ev_type, void *ev)
{
/* called on ctrl-c, kill (pid) (also SIGINT, SIGTERM and SIGQIT) */
exit(-1);
return 1;
}
static void
_e_help(void)
{
printf("enlightenment_eapp_cache_gen [directory] [OPTIONS]\n"
"\n"
"OPTIONS:\n"
" -h This help\n"
" -help This help\n"
" --help This help\n"
" --h This help\n"
" -r Recursively generate caches for all subdirectories too\n"
);
}

View File

@ -30,19 +30,6 @@ static int _e_main_cb_startup_fake_end(void *data);
static void _e_main_desk_save(void);
static void _e_main_desk_restore(E_Manager *man, E_Container *con);
E_Path *path_data = NULL;
E_Path *path_images = NULL;
E_Path *path_fonts = NULL;
E_Path *path_themes = NULL;
E_Path *path_init = NULL;
E_Path *path_icons = NULL;
E_Path *path_modules = NULL;
E_Path *path_backgrounds = NULL;
int restart = 0;
int good = 0;
int evil = 0;
int starting = 1;
/* local subsystem globals */
#define MAX_LEVEL 32
static int (*_e_main_shutdown_func[MAX_LEVEL]) (void);

View File

@ -3,6 +3,19 @@
*/
#include "e.h"
E_Path *path_data = NULL;
E_Path *path_images = NULL;
E_Path *path_fonts = NULL;
E_Path *path_themes = NULL;
E_Path *path_init = NULL;
E_Path *path_icons = NULL;
E_Path *path_modules = NULL;
E_Path *path_backgrounds = NULL;
int restart = 0;
int good = 0;
int evil = 0;
int starting = 1;
typedef struct _E_Util_Fake_Mouse_Up_Info E_Util_Fake_Mouse_Up_Info;
struct _E_Util_Fake_Mouse_Up_Info