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;
Ephoto *ephoto;
Elm_Gengrid_Item *item;
Eina_List *free_listeners;
Eina_List *dir_files; /* if dir, here contain files with preview */
Eina_Bool dir_files_checked : 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);
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);
extern int __log_domain;
@ -154,7 +157,7 @@ extern int __log_domain;
static inline Eina_Bool
_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;
if (bname[0] == '.') return EINA_FALSE;

View File

@ -11,9 +11,23 @@ struct _Ephoto_Directory_Thumb
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
_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)
{
dt->canceled = EINA_TRUE;
@ -21,7 +35,6 @@ _ephoto_directory_thumb_free(Ephoto_Directory_Thumb *dt)
return;
}
eina_hash_del(_pending_dirs, dt->entry->path, dt);
free(dt);
if (!eina_hash_population(_pending_dirs))
@ -59,9 +72,12 @@ _populate_end(void *data)
EINA_LIST_FREE(dt->objs, obj)
evas_object_event_callback_del_full(obj, EVAS_CALLBACK_DEL, _obj_del, dt);
if (dt->entry)
{
dt->entry->dir_files_checked = EINA_TRUE;
if ((dt->entry->item) && (!dt->canceled))
elm_gengrid_item_update(dt->entry->item);
}
_ephoto_directory_thumb_free(dt);
}
@ -82,6 +98,7 @@ _populate_main(void *data, const Eina_File_Direct_Info *info)
const char *file;
if (!dt->objs) return;
if (!dt->entry) return;
obj = dt->objs->data;
file = eina_stringshare_add(info->path);
@ -127,6 +144,7 @@ ephoto_directory_thumb_add(Evas_Object *parent, Ephoto_Entry *entry)
evas_object_del(obj);
return NULL;
}
ephoto_entry_free_listener_add(entry, _entry_free, dt);
dt->entry = entry;
dt->ls = eio_file_direct_ls(entry->path,
_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
_layout_del(void *data, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event_info __UNUSED__)
{
Ephoto_Flow_Browser *fb = data;
if (fb->entry)
ephoto_entry_free_listener_del(fb->entry, _entry_free, fb);
eina_stringshare_del(fb->path);
free(fb);
}
@ -823,7 +832,16 @@ ephoto_flow_browser_entry_set(Evas_Object *obj, Ephoto_Entry *entry)
EINA_SAFETY_ON_NULL_RETURN(fb);
DBG("entry %p, was %p", entry, fb->entry);
if (fb->entry)
ephoto_entry_free_listener_del(fb->entry, _entry_free, fb);
fb->entry = entry;
if (entry)
ephoto_entry_free_listener_add(entry, _entry_free, fb);
if (!entry)
{
eina_stringshare_replace(&fb->path, NULL);

View File

@ -1,5 +1,12 @@
#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
_ephoto_state_set(Ephoto *ephoto, Ephoto_State state)
{
@ -380,6 +387,13 @@ void
ephoto_entry_free(Ephoto_Entry *entry)
{
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_stringshare_del(entry->path);
eina_stringshare_del(entry->label);
@ -387,6 +401,37 @@ ephoto_entry_free(Ephoto_Entry *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
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);
}
static void
_entry_free(void *data, const Ephoto_Entry *entry __UNUSED__)
{
Ephoto_Slideshow *ss = data;
ss->entry = NULL;
}
static void
_slideshow_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
{
Ephoto_Slideshow *ss = data;
if (ss->entry)
ephoto_entry_free_listener_del(ss->entry, _entry_free, ss);
free(ss);
}
@ -158,7 +167,15 @@ ephoto_slideshow_entry_set(Evas_Object *obj, Ephoto_Entry *entry)
conf = ss->ephoto->config;
DBG("entry %p, was %p", entry, ss->entry);
if (ss->entry)
ephoto_entry_free_listener_del(ss->entry, _entry_free, ss);
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_transition_set(ss->slideshow, conf->slideshow_transition);
elm_slideshow_timeout_set(ss->slideshow, conf->slideshow_timeout);