damn async things, they're always more complex than what you want.

in few cases we could quickly change directories and views would still
be populating, then they could access dt->entry
(ephoto_directory_thumb.c), so we need notifiers to know it is gone
and not mess with it any further.

Then ephoto_entry_free_listener_add() is born, added it to
flow_browser and slideshow for the sake of it... it shouldn't be
needed.



SVN revision: 53341
This commit is contained in:
Gustavo Sverzut Barbieri 2010-10-13 06:11:06 +00:00
parent 8756234b66
commit dae342bc7d
5 changed files with 106 additions and 5 deletions

View File

@ -136,6 +136,7 @@ struct _Ephoto_Entry
const char *label; const char *label;
Ephoto *ephoto; Ephoto *ephoto;
Elm_Gengrid_Item *item; Elm_Gengrid_Item *item;
Eina_List *free_listeners;
Eina_List *dir_files; /* if dir, here contain files with preview */ Eina_List *dir_files; /* if dir, here contain files with preview */
Eina_Bool dir_files_checked : 1; Eina_Bool dir_files_checked : 1;
Eina_Bool is_dir : 1; Eina_Bool is_dir : 1;
@ -144,6 +145,8 @@ struct _Ephoto_Entry
Ephoto_Entry *ephoto_entry_new(Ephoto *ephoto, const char *path, const char *label); Ephoto_Entry *ephoto_entry_new(Ephoto *ephoto, const char *path, const char *label);
void ephoto_entry_free(Ephoto_Entry *entry); void ephoto_entry_free(Ephoto_Entry *entry);
void ephoto_entry_free_listener_add(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data);
void ephoto_entry_free_listener_del(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data);
void ephoto_entries_free(Ephoto *ephoto); void ephoto_entries_free(Ephoto *ephoto);
extern int __log_domain; extern int __log_domain;
@ -154,7 +157,7 @@ extern int __log_domain;
static inline Eina_Bool static inline Eina_Bool
_ephoto_eina_file_direct_info_image_useful(const Eina_File_Direct_Info *info) _ephoto_eina_file_direct_info_image_useful(const Eina_File_Direct_Info *info)
{ {
const char *type, *bname, *ext; const char /* *type, */ *bname, *ext;
bname = info->path + info->name_start; bname = info->path + info->name_start;
if (bname[0] == '.') return EINA_FALSE; if (bname[0] == '.') return EINA_FALSE;

View File

@ -11,9 +11,23 @@ struct _Ephoto_Directory_Thumb
static Eina_Hash *_pending_dirs = NULL; static Eina_Hash *_pending_dirs = NULL;
static void
_entry_free(void *data, const Ephoto_Entry *entry __UNUSED__)
{
Ephoto_Directory_Thumb *dt = data;
dt->entry = NULL;
}
static void static void
_ephoto_directory_thumb_free(Ephoto_Directory_Thumb *dt) _ephoto_directory_thumb_free(Ephoto_Directory_Thumb *dt)
{ {
if (dt->entry)
{
ephoto_entry_free_listener_del(dt->entry, _entry_free, dt);
eina_hash_del(_pending_dirs, dt->entry->path, dt);
dt->entry = NULL;
}
if (dt->ls) if (dt->ls)
{ {
dt->canceled = EINA_TRUE; dt->canceled = EINA_TRUE;
@ -21,7 +35,6 @@ _ephoto_directory_thumb_free(Ephoto_Directory_Thumb *dt)
return; return;
} }
eina_hash_del(_pending_dirs, dt->entry->path, dt);
free(dt); free(dt);
if (!eina_hash_population(_pending_dirs)) if (!eina_hash_population(_pending_dirs))
@ -59,9 +72,12 @@ _populate_end(void *data)
EINA_LIST_FREE(dt->objs, obj) EINA_LIST_FREE(dt->objs, obj)
evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL, _obj_del, dt); evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL, _obj_del, dt);
if (dt->entry)
{
dt->entry->dir_files_checked = EINA_TRUE; dt->entry->dir_files_checked = EINA_TRUE;
if ((dt->entry->item) && (!dt->canceled)) if ((dt->entry->item) && (!dt->canceled))
elm_gengrid_item_update(dt->entry->item); elm_gengrid_item_update(dt->entry->item);
}
_ephoto_directory_thumb_free(dt); _ephoto_directory_thumb_free(dt);
} }
@ -82,6 +98,7 @@ _populate_main(void *data, const Eina_File_Direct_Info *info)
const char *file; const char *file;
if (!dt->objs) return; if (!dt->objs) return;
if (!dt->entry) return;
obj = dt->objs->data; obj = dt->objs->data;
file = eina_stringshare_add(info->path); file = eina_stringshare_add(info->path);
@ -127,6 +144,7 @@ ephoto_directory_thumb_add(Evas_Object *parent, Ephoto_Entry *entry)
evas_object_del(obj); evas_object_del(obj);
return NULL; return NULL;
} }
ephoto_entry_free_listener_add(entry, _entry_free, dt);
dt->entry = entry; dt->entry = entry;
dt->ls = eio_file_direct_ls(entry->path, dt->ls = eio_file_direct_ls(entry->path,
_populate_filter, _populate_filter,

View File

@ -648,10 +648,19 @@ _key_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event
} }
} }
static void
_entry_free(void *data, const Ephoto_Entry *entry __UNUSED__)
{
Ephoto_Flow_Browser *fb = data;
fb->entry = NULL;
}
static void static void
_layout_del(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__) _layout_del(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
{ {
Ephoto_Flow_Browser *fb = data; Ephoto_Flow_Browser *fb = data;
if (fb->entry)
ephoto_entry_free_listener_del(fb->entry, _entry_free, fb);
eina_stringshare_del(fb->path); eina_stringshare_del(fb->path);
free(fb); free(fb);
} }
@ -823,7 +832,16 @@ ephoto_flow_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry)
EINA_SAFETY_ON_NULL_RETURN(fb); EINA_SAFETY_ON_NULL_RETURN(fb);
DBG("entry %p, was %p", entry, fb->entry); DBG("entry %p, was %p", entry, fb->entry);
if (fb->entry)
ephoto_entry_free_listener_del(fb->entry, _entry_free, fb);
fb->entry = entry; fb->entry = entry;
if (entry)
ephoto_entry_free_listener_add(entry, _entry_free, fb);
if (!entry) if (!entry)
{ {
eina_stringshare_replace(&fb->path, NULL); eina_stringshare_replace(&fb->path, NULL);

View File

@ -1,5 +1,12 @@
#include "ephoto.h" #include "ephoto.h"
typedef struct _Ephoto_Entry_Free_Listener Ephoto_Entry_Free_Listener;
struct _Ephoto_Entry_Free_Listener
{
void (*cb)(void *data, const Ephoto_Entry *dead);
const void *data;
};
static void static void
_ephoto_state_set(Ephoto *ephoto, Ephoto_State state) _ephoto_state_set(Ephoto *ephoto, Ephoto_State state)
{ {
@ -380,6 +387,13 @@ void
ephoto_entry_free(Ephoto_Entry *entry) ephoto_entry_free(Ephoto_Entry *entry)
{ {
const char *s; const char *s;
Ephoto_Entry_Free_Listener *fl;
EINA_LIST_FREE(entry->free_listeners, fl)
{
fl->cb((void *)fl->data, entry);
free(fl);
}
EINA_SAFETY_ON_NULL_RETURN(entry); EINA_SAFETY_ON_NULL_RETURN(entry);
eina_stringshare_del(entry->path); eina_stringshare_del(entry->path);
eina_stringshare_del(entry->label); eina_stringshare_del(entry->label);
@ -387,6 +401,37 @@ ephoto_entry_free(Ephoto_Entry *entry)
free(entry); free(entry);
} }
void
ephoto_entry_free_listener_add(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data)
{
Ephoto_Entry_Free_Listener *fl;
EINA_SAFETY_ON_NULL_RETURN(entry);
EINA_SAFETY_ON_NULL_RETURN(cb);
fl = malloc(sizeof(Ephoto_Entry_Free_Listener));
EINA_SAFETY_ON_NULL_RETURN(fl);
fl->cb = cb;
fl->data = data;
entry->free_listeners = eina_list_append(entry->free_listeners, fl);
}
void
ephoto_entry_free_listener_del(Ephoto_Entry *entry, void (*cb)(void *data, const Ephoto_Entry *entry), const void *data)
{
Eina_List *l;
Ephoto_Entry_Free_Listener *fl;
EINA_SAFETY_ON_NULL_RETURN(entry);
EINA_SAFETY_ON_NULL_RETURN(cb);
EINA_LIST_FOREACH(entry->free_listeners, l, fl)
{
if ((fl->cb == cb) && (fl->data == data))
{
entry->free_listeners = eina_list_remove_list
(entry->free_listeners, l);
break;
}
}
}
void void
ephoto_entries_free(Ephoto *ephoto) ephoto_entries_free(Ephoto *ephoto)
{ {

View File

@ -44,10 +44,19 @@ _mouse_down(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *eve
evas_object_smart_callback_call(ss->slideshow, "back", ss->entry); evas_object_smart_callback_call(ss->slideshow, "back", ss->entry);
} }
static void
_entry_free(void *data, const Ephoto_Entry *entry __UNUSED__)
{
Ephoto_Slideshow *ss = data;
ss->entry = NULL;
}
static void static void
_slideshow_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__) _slideshow_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{ {
Ephoto_Slideshow *ss = data; Ephoto_Slideshow *ss = data;
if (ss->entry)
ephoto_entry_free_listener_del(ss->entry, _entry_free, ss);
free(ss); free(ss);
} }
@ -158,7 +167,15 @@ ephoto_slideshow_entry_set(Evas_Object *obj, Ephoto_Entry *entry)
conf = ss->ephoto->config; conf = ss->ephoto->config;
DBG("entry %p, was %p", entry, ss->entry); DBG("entry %p, was %p", entry, ss->entry);
if (ss->entry)
ephoto_entry_free_listener_del(ss->entry, _entry_free, ss);
ss->entry = entry; ss->entry = entry;
if (entry)
ephoto_entry_free_listener_add(entry, _entry_free, ss);
elm_slideshow_loop_set(ss->slideshow, EINA_TRUE); /* move to config? */ elm_slideshow_loop_set(ss->slideshow, EINA_TRUE); /* move to config? */
elm_slideshow_transition_set(ss->slideshow, conf->slideshow_transition); elm_slideshow_transition_set(ss->slideshow, conf->slideshow_transition);
elm_slideshow_timeout_set(ss->slideshow, conf->slideshow_timeout); elm_slideshow_timeout_set(ss->slideshow, conf->slideshow_timeout);