extensive delete me handling for evas free's and list walks

SVN revision: 29776
This commit is contained in:
Carsten Haitzler 2007-04-30 04:22:42 +00:00
parent b0717e8539
commit 5e691081ca
4 changed files with 68 additions and 275 deletions

View File

@ -30,44 +30,6 @@ evas_object_event_callback_clear(Evas_Object *obj)
if (!obj->callbacks) return;
if (!obj->callbacks->deletions_waiting) return;
obj->callbacks->deletions_waiting = 0;
/*
evas_object_event_callback_list_post_free(&(obj->callbacks->in));
evas_object_event_callback_list_post_free(&(obj->callbacks->out));
evas_object_event_callback_list_post_free(&(obj->callbacks->down));
evas_object_event_callback_list_post_free(&(obj->callbacks->up));
evas_object_event_callback_list_post_free(&(obj->callbacks->move));
evas_object_event_callback_list_post_free(&(obj->callbacks->wheel));
evas_object_event_callback_list_post_free(&(obj->callbacks->free));
evas_object_event_callback_list_post_free(&(obj->callbacks->key_down));
evas_object_event_callback_list_post_free(&(obj->callbacks->key_up));
evas_object_event_callback_list_post_free(&(obj->callbacks->obj_focus_in));
evas_object_event_callback_list_post_free(&(obj->callbacks->obj_focus_out));
evas_object_event_callback_list_post_free(&(obj->callbacks->obj_show));
evas_object_event_callback_list_post_free(&(obj->callbacks->obj_hide));
evas_object_event_callback_list_post_free(&(obj->callbacks->obj_move));
evas_object_event_callback_list_post_free(&(obj->callbacks->obj_resize));
evas_object_event_callback_list_post_free(&(obj->callbacks->obj_restack));
if ((!obj->callbacks->in) &&
(!obj->callbacks->out) &&
(!obj->callbacks->down) &&
(!obj->callbacks->up) &&
(!obj->callbacks->move) &&
(!obj->callbacks->wheel) &&
(!obj->callbacks->free) &&
(!obj->callbacks->key_down) &&
(!obj->callbacks->key_up) &&
(!obj->callbacks->obj_focus_in) &&
(!obj->callbacks->obj_focus_out) &&
(!obj->callbacks->obj_show) &&
(!obj->callbacks->obj_hide) &&
(!obj->callbacks->obj_move) &&
(!obj->callbacks->obj_resize) &&
(!obj->callbacks->obj_restack))
{
free(obj->callbacks);
obj->callbacks = NULL;
}
*/
evas_object_event_callback_list_post_free(&obj->callbacks->callbacks);
if (!obj->callbacks->callbacks)
{
@ -96,26 +58,6 @@ evas_object_event_callback_cleanup(Evas_Object *obj)
{
/* MEM OK */
if (!obj->callbacks) return;
/*
evas_object_event_callback_list_free(&(obj->callbacks->in));
evas_object_event_callback_list_free(&(obj->callbacks->out));
evas_object_event_callback_list_free(&(obj->callbacks->down));
evas_object_event_callback_list_free(&(obj->callbacks->up));
evas_object_event_callback_list_free(&(obj->callbacks->move));
evas_object_event_callback_list_free(&(obj->callbacks->wheel));
evas_object_event_callback_list_free(&(obj->callbacks->free));
evas_object_event_callback_list_free(&(obj->callbacks->key_down));
evas_object_event_callback_list_free(&(obj->callbacks->key_up));
evas_object_event_callback_list_free(&(obj->callbacks->obj_focus_in));
evas_object_event_callback_list_free(&(obj->callbacks->obj_focus_out));
evas_object_event_callback_list_free(&(obj->callbacks->obj_show));
evas_object_event_callback_list_free(&(obj->callbacks->obj_hide));
evas_object_event_callback_list_free(&(obj->callbacks->obj_move));
evas_object_event_callback_list_free(&(obj->callbacks->obj_resize));
evas_object_event_callback_list_free(&(obj->callbacks->obj_restack));
free(obj->callbacks);
obj->callbacks = NULL;
*/
evas_object_event_callback_list_post_free(&obj->callbacks->callbacks);
free(obj->callbacks);
obj->callbacks = NULL;
@ -132,85 +74,9 @@ evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void
if (obj->delete_me) return;
e = evas_object_evas_get(obj);
_evas_walk(e);
if (obj->callbacks)
{
/*
switch (type)
{
case EVAS_CALLBACK_MOUSE_IN:
l_mod = &(obj->callbacks->in);
break;
case EVAS_CALLBACK_MOUSE_OUT:
l_mod = &(obj->callbacks->out);
break;
case EVAS_CALLBACK_MOUSE_DOWN:
{
Evas_Event_Mouse_Down *ev = event_info;
flags = ev->flags;
if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
{
if (obj->last_mouse_down_counter < (e->last_mouse_down_counter - 1))
ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
}
l_mod = &(obj->callbacks->down);
obj->last_mouse_down_counter = e->last_mouse_down_counter;
break;
}
case EVAS_CALLBACK_MOUSE_UP:
{
Evas_Event_Mouse_Up *ev = event_info;
flags = ev->flags;
if (ev->flags & (EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK))
{
if (obj->last_mouse_up_counter < (e->last_mouse_up_counter - 1))
ev->flags &= ~(EVAS_BUTTON_DOUBLE_CLICK | EVAS_BUTTON_TRIPLE_CLICK);
}
l_mod = &(obj->callbacks->up);
obj->last_mouse_up_counter = e->last_mouse_up_counter;
break;
}
case EVAS_CALLBACK_MOUSE_MOVE:
l_mod = &(obj->callbacks->move);
break;
case EVAS_CALLBACK_MOUSE_WHEEL:
l_mod = &(obj->callbacks->wheel);
break;
case EVAS_CALLBACK_FREE:
l_mod = &(obj->callbacks->free);
break;
case EVAS_CALLBACK_KEY_DOWN:
l_mod = &(obj->callbacks->key_down);
break;
case EVAS_CALLBACK_KEY_UP:
l_mod = &(obj->callbacks->key_up);
break;
case EVAS_CALLBACK_FOCUS_IN:
l_mod = &(obj->callbacks->obj_focus_in);
case EVAS_CALLBACK_FOCUS_OUT:
l_mod = &(obj->callbacks->obj_focus_out);
break;
case EVAS_CALLBACK_SHOW:
l_mod = &(obj->callbacks->obj_show);
break;
case EVAS_CALLBACK_HIDE:
l_mod = &(obj->callbacks->obj_hide);
break;
case EVAS_CALLBACK_MOVE:
l_mod = &(obj->callbacks->obj_move);
break;
case EVAS_CALLBACK_RESIZE:
l_mod = &(obj->callbacks->obj_resize);
break;
case EVAS_CALLBACK_RESTACK:
l_mod = &(obj->callbacks->obj_restack);
break;
default:
return;
break;
}
*/
l_mod = &obj->callbacks->callbacks;
switch (type)
{
@ -272,10 +138,13 @@ evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void
}
}
if ((obj->no_propagate) && (l_mod) && (*l_mod)) return;
if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) &&
(type <= EVAS_CALLBACK_KEY_UP))
evas_object_event_callback_call(obj->smart.parent, type, event_info);
if (!((obj->no_propagate) && (l_mod) && (*l_mod)))
{
if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) &&
(type <= EVAS_CALLBACK_KEY_UP))
evas_object_event_callback_call(obj->smart.parent, type, event_info);
}
_evas_unwalk(e);
}
/**
@ -471,64 +340,6 @@ evas_object_event_callback_add(Evas_Object *obj, Evas_Callback_Type type, void (
free(fn);
return;
}
/*
switch (type)
{
case EVAS_CALLBACK_MOUSE_IN:
l_mod = &(obj->callbacks->in);
break;
case EVAS_CALLBACK_MOUSE_OUT:
l_mod = &(obj->callbacks->out);
break;
case EVAS_CALLBACK_MOUSE_DOWN:
l_mod = &(obj->callbacks->down);
break;
case EVAS_CALLBACK_MOUSE_UP:
l_mod = &(obj->callbacks->up);
break;
case EVAS_CALLBACK_MOUSE_MOVE:
l_mod = &(obj->callbacks->move);
break;
case EVAS_CALLBACK_MOUSE_WHEEL:
l_mod = &(obj->callbacks->wheel);
break;
case EVAS_CALLBACK_FREE:
l_mod = &(obj->callbacks->free);
break;
case EVAS_CALLBACK_KEY_DOWN:
l_mod = &(obj->callbacks->key_down);
break;
case EVAS_CALLBACK_KEY_UP:
l_mod = &(obj->callbacks->key_up);
break;
case EVAS_CALLBACK_FOCUS_IN:
l_mod = &(obj->callbacks->obj_focus_in);
break;
case EVAS_CALLBACK_FOCUS_OUT:
l_mod = &(obj->callbacks->obj_focus_out);
break;
case EVAS_CALLBACK_SHOW:
l_mod = &(obj->callbacks->obj_show);
break;
case EVAS_CALLBACK_HIDE:
l_mod = &(obj->callbacks->obj_hide);
break;
case EVAS_CALLBACK_MOVE:
l_mod = &(obj->callbacks->obj_move);
break;
case EVAS_CALLBACK_RESIZE:
l_mod = &(obj->callbacks->obj_resize);
break;
case EVAS_CALLBACK_RESTACK:
l_mod = &(obj->callbacks->obj_restack);
break;
default:
free(fn);
return;
break;
}
*l_mod = evas_object_list_append(*l_mod, fn);
*/
obj->callbacks->callbacks =
evas_object_list_append(obj->callbacks->callbacks, fn);
}
@ -571,79 +382,6 @@ evas_object_event_callback_del(Evas_Object *obj, Evas_Callback_Type type, void (
if (!obj->callbacks) return NULL;
/*
switch (type)
{
case EVAS_CALLBACK_MOUSE_IN:
l_mod = &(obj->callbacks->in);
break;
case EVAS_CALLBACK_MOUSE_OUT:
l_mod = &(obj->callbacks->out);
break;
case EVAS_CALLBACK_MOUSE_DOWN:
l_mod = &(obj->callbacks->down);
break;
case EVAS_CALLBACK_MOUSE_UP:
l_mod = &(obj->callbacks->up);
break;
case EVAS_CALLBACK_MOUSE_MOVE:
l_mod = &(obj->callbacks->move);
break;
case EVAS_CALLBACK_MOUSE_WHEEL:
l_mod = &(obj->callbacks->wheel);
break;
case EVAS_CALLBACK_FREE:
l_mod = &(obj->callbacks->free);
break;
case EVAS_CALLBACK_KEY_DOWN:
l_mod = &(obj->callbacks->key_down);
break;
case EVAS_CALLBACK_KEY_UP:
l_mod = &(obj->callbacks->key_up);
break;
case EVAS_CALLBACK_FOCUS_IN:
l_mod = &(obj->callbacks->obj_focus_in);
break;
case EVAS_CALLBACK_FOCUS_OUT:
l_mod = &(obj->callbacks->obj_focus_out);
break;
case EVAS_CALLBACK_SHOW:
l_mod = &(obj->callbacks->obj_show);
break;
case EVAS_CALLBACK_HIDE:
l_mod = &(obj->callbacks->obj_hide);
break;
case EVAS_CALLBACK_MOVE:
l_mod = &(obj->callbacks->obj_move);
break;
case EVAS_CALLBACK_RESIZE:
l_mod = &(obj->callbacks->obj_resize);
break;
case EVAS_CALLBACK_RESTACK:
l_mod = &(obj->callbacks->obj_restack);
break;
default:
return NULL;
break;
}
for (l = *l_mod; l; l = l->next)
{
Evas_Func_Node *fn;
fn = (Evas_Func_Node *)l;
if ((fn->func == func) && (!fn->delete_me))
{
void *data;
data = fn->data;
fn->delete_me = 1;
obj->callbacks->deletions_waiting = 1;
if (!obj->callbacks->walking_list)
evas_object_event_callback_clear(obj);
return data;
}
}
*/
for (l = obj->callbacks->callbacks; l; l = l->next)
{
Evas_Func_Node *fn;

View File

@ -235,6 +235,7 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int
if (e->events_frozen > 0) return;
e->last_timestamp = timestamp;
_evas_walk(e);
copy = evas_event_list_copy(e->pointer.object.in);
for (l = copy; l; l = l->next)
{
@ -259,9 +260,11 @@ evas_event_feed_mouse_down(Evas *e, int b, Evas_Button_Flags flags, unsigned int
ev.timestamp = timestamp;
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_DOWN, &ev);
if (e->delete_me) break;
}
if (copy) copy = evas_list_free(copy);
e->last_mouse_down_counter++;
_evas_unwalk(e);
}
/**
@ -286,6 +289,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
if (e->events_frozen > 0) return;
e->last_timestamp = timestamp;
_evas_walk(e);
copy = evas_event_list_copy(e->pointer.object.in);
for (l = copy; l; l = l->next)
{
@ -311,6 +315,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
ev.timestamp = timestamp;
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_UP, &ev);
if (e->delete_me) break;
}
if (copy) copy = evas_list_free(copy);
e->last_mouse_up_counter++;
@ -348,6 +353,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
}
if (e->delete_me) break;
}
if (copy) copy = evas_list_free(copy);
if (e->pointer.inside)
@ -377,6 +383,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev);
}
if (e->delete_me) break;
}
}
else
@ -394,6 +401,7 @@ evas_event_feed_mouse_up(Evas *e, int b, Evas_Button_Flags flags, unsigned int t
{
e->pointer.mouse_grabbed = 0;
}
_evas_unwalk(e);
}
/**
@ -414,6 +422,7 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam
if (e->events_frozen > 0) return;
e->last_timestamp = timestamp;
_evas_walk(e);
copy = evas_event_list_copy(e->pointer.object.in);
for (l = copy; l; l = l->next)
@ -435,10 +444,11 @@ evas_event_feed_mouse_wheel(Evas *e, int direction, int z, unsigned int timestam
ev.timestamp = timestamp;
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_WHEEL, &ev);
if (e->delete_me) break;
}
if (copy) copy = evas_list_free(copy);
return;
_evas_unwalk(e);
}
/**
@ -472,6 +482,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
//// e->pointer.canvas_x = evas_coord_screen_x_to_world(e, x);
//// e->pointer.canvas_y = evas_coord_screen_y_to_world(e, y);
if ((!e->pointer.inside) && (e->pointer.mouse_grabbed == 0)) return;
_evas_walk(e);
/* if our mouse button is grabbed to any objects */
if (e->pointer.mouse_grabbed > 0)
{
@ -517,6 +528,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
}
else
outs = evas_list_append(outs, obj);
if (e->delete_me) break;
}
if (copy) copy = evas_list_free(copy);
while (outs)
@ -525,7 +537,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
obj = outs->data;
outs = evas_list_remove(outs, obj);
if (!obj->mouse_grabbed)
if ((!obj->mouse_grabbed) && (!e->delete_me))
{
e->pointer.object.in = evas_list_remove(e->pointer.object.in, obj);
{
@ -619,6 +631,7 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
}
if (e->delete_me) break;
}
if (copy) copy = evas_list_free(copy);
/* go thru our current list of ins */
@ -647,12 +660,14 @@ evas_event_feed_mouse_move(Evas *e, int x, int y, unsigned int timestamp, const
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev);
}
if (e->delete_me) break;
}
/* free our old list of ins */
evas_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
}
_evas_unwalk(e);
}
/**
@ -677,6 +692,7 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
if (e->pointer.mouse_grabbed != 0) return;
_evas_walk(e);
/* get new list of ins */
ins = evas_event_objects_event_list(e, NULL, e->pointer.x, e->pointer.y);
for (l = ins; l; l = l->next)
@ -704,12 +720,14 @@ evas_event_feed_mouse_in(Evas *e, unsigned int timestamp, const void *data)
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_IN, &ev);
}
if (e->delete_me) break;
}
/* free our old list of ins */
e->pointer.object.in = evas_list_free(e->pointer.object.in);
/* and set up the new one */
e->pointer.object.in = ins;
evas_event_feed_mouse_move(e, e->pointer.x, e->pointer.y, timestamp, data);
_evas_unwalk(e);
}
/**
@ -729,6 +747,7 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
if (e->events_frozen > 0) return;
e->last_timestamp = timestamp;
_evas_walk(e);
/* if our mouse button is grabbed to any objects */
if (e->pointer.mouse_grabbed == 0)
{
@ -759,11 +778,13 @@ evas_event_feed_mouse_out(Evas *e, unsigned int timestamp, const void *data)
if (e->events_frozen <= 0)
evas_object_event_callback_call(obj, EVAS_CALLBACK_MOUSE_OUT, &ev);
}
if (e->delete_me) break;
}
if (copy) copy = evas_list_free(copy);
/* free our old list of ins */
e->pointer.object.in = evas_list_free(e->pointer.object.in);
}
_evas_unwalk(e);
}
/**
@ -781,6 +802,7 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch
if (!keyname) return;
if (e->events_frozen > 0) return;
e->last_timestamp = timestamp;
_evas_walk(e);
{
Evas_Event_Key_Down ev;
int exclusive;
@ -821,6 +843,7 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch
if (g->exclusive) exclusive = 1;
}
}
if (e->delete_me) break;
}
e->walking_grabs--;
if (e->walking_grabs <= 0)
@ -848,6 +871,7 @@ evas_event_feed_key_down(Evas *e, const char *keyname, const char *key, const ch
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_DOWN, &ev);
}
}
_evas_unwalk(e);
}
/**
@ -865,6 +889,7 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char
if (!keyname) return;
if (e->events_frozen > 0) return;
e->last_timestamp = timestamp;
_evas_walk(e);
{
Evas_Event_Key_Up ev;
int exclusive;
@ -904,6 +929,7 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char
evas_object_event_callback_call(g->object, EVAS_CALLBACK_KEY_UP, &ev);
if (g->exclusive) exclusive = 1;
}
if (e->delete_me) break;
}
e->walking_grabs--;
if (e->walking_grabs <= 0)
@ -931,6 +957,7 @@ evas_event_feed_key_up(Evas *e, const char *keyname, const char *key, const char
evas_object_event_callback_call(e->focused, EVAS_CALLBACK_KEY_UP, &ev);
}
}
_evas_unwalk(e);
}
/**

View File

@ -85,7 +85,9 @@ evas_free(Evas *e)
return;
MAGIC_CHECK_END();
if (e->walking_list > 0) return;
del = 1;
e->walking_list++;
while (del)
{
del = 0;
@ -101,6 +103,13 @@ evas_free(Evas *e)
Evas_Object *o;
o = (Evas_Object *)ll;
if ((o->callbacks) && (o->callbacks->walking_list))
{
/* Defer free */
e->delete_me = 1;
e->walking_list--;
return;
}
if (!o->delete_me)
del = 1;
}
@ -114,7 +123,8 @@ evas_free(Evas *e)
evas_layer_del(lay);
evas_layer_free(lay);
}
e->walking_list--;
evas_font_path_clear(e);
e->pointer.object.in = evas_list_free(e->pointer.object.in);
@ -958,3 +968,17 @@ evas_data_attach_get(Evas *e)
MAGIC_CHECK_END();
return e->attach_data;
}
void
_evas_walk(Evas *e)
{
e->walking_list++;
}
void
_evas_unwalk(Evas *e)
{
e->walking_list--;
if ((e->walking_list == 0) && (e->delete_me)) evas_free(e);
}

View File

@ -309,8 +309,8 @@ struct _Evas
Evas_Hash *name_hash;
unsigned char changed : 1;
unsigned char walking_layers : 1;
int walking_list;
int events_frozen;
struct {
@ -340,6 +340,7 @@ struct _Evas
int last_mouse_down_counter;
int last_mouse_up_counter;
Evas_Font_Hinting_Flags hinting;
unsigned char delete_me : 1;
};
struct _Evas_Layer
@ -455,7 +456,7 @@ struct _Evas_Func_Node
void (*func) (void *data, Evas *e, Evas_Object *obj, void *event_info);
void *data;
Evas_Callback_Type type;
char delete_me : 1;
unsigned char delete_me : 1;
};
struct _Evas_Data_Node
@ -770,6 +771,9 @@ void evas_module_use(Evas_Module *em);
void evas_module_clean(void);
void evas_module_shutdown(void);
void _evas_walk(Evas *e);
void _evas_unwalk(Evas *e);
EAPI int _evas_module_engine_inherit(Evas_Func *funcs, char *name);
#define EVAS_API_OVERRIDE(func, api, prefix) \