forked from enlightenment/efl
events (also filters and handlers) now have reference counting.
Add reference counting to events, event filters and event handlers so they can recurse main loops. Note that the required "continuation" when entering main loops is not there, thus recursion will restart and this will fail badly in lots of cases. This should be fixed in future commits. SVN revision: 46417
This commit is contained in:
parent
0bdbf9d147
commit
b9c3b58561
|
@ -19,6 +19,7 @@ struct _Ecore_Event_Handler
|
||||||
int type;
|
int type;
|
||||||
int (*func) (void *data, int type, void *event);
|
int (*func) (void *data, int type, void *event);
|
||||||
void *data;
|
void *data;
|
||||||
|
int references;
|
||||||
Eina_Bool delete_me : 1;
|
Eina_Bool delete_me : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,6 +32,7 @@ struct _Ecore_Event_Filter
|
||||||
void (*func_end) (void *data, void *loop_data);
|
void (*func_end) (void *data, void *loop_data);
|
||||||
void *loop_data;
|
void *loop_data;
|
||||||
void *data;
|
void *data;
|
||||||
|
int references;
|
||||||
Eina_Bool delete_me : 1;
|
Eina_Bool delete_me : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,6 +44,7 @@ struct _Ecore_Event
|
||||||
void *event;
|
void *event;
|
||||||
void (*func_free) (void *data, void *ev);
|
void (*func_free) (void *data, void *ev);
|
||||||
void *data;
|
void *data;
|
||||||
|
int references;
|
||||||
Eina_Bool delete_me : 1;
|
Eina_Bool delete_me : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +64,9 @@ static int ecore_raw_event_type = ECORE_EVENT_NONE;
|
||||||
static void *ecore_raw_event_event = NULL;
|
static void *ecore_raw_event_event = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
static void _ecore_event_purge_deleted(void);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an event handler.
|
* Add an event handler.
|
||||||
* @param type The type of the event this handler will get called for
|
* @param type The type of the event this handler will get called for
|
||||||
|
@ -328,7 +334,7 @@ _ecore_event_shutdown(void)
|
||||||
Ecore_Event_Handler *eh;
|
Ecore_Event_Handler *eh;
|
||||||
Ecore_Event_Filter *ef;
|
Ecore_Event_Filter *ef;
|
||||||
|
|
||||||
while (events) _ecore_event_del(events);
|
_ecore_event_purge_deleted();
|
||||||
for (i = 0; i < event_handlers_num; i++)
|
for (i = 0; i < event_handlers_num; i++)
|
||||||
{
|
{
|
||||||
while ((eh = event_handlers[i]))
|
while ((eh = event_handlers[i]))
|
||||||
|
@ -391,18 +397,34 @@ _ecore_event_del(Ecore_Event *event)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_ecore_event_purge_deleted(void)
|
||||||
|
{
|
||||||
|
Ecore_Event *itr = events;
|
||||||
|
|
||||||
|
while (itr)
|
||||||
|
{
|
||||||
|
Ecore_Event *next = (Ecore_Event *)EINA_INLIST_GET(itr)->next;
|
||||||
|
if (!itr->references)
|
||||||
|
_ecore_event_del(itr);
|
||||||
|
itr = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_ecore_event_call(void)
|
_ecore_event_call(void)
|
||||||
{
|
{
|
||||||
Ecore_Event *e;
|
Ecore_Event *e;
|
||||||
Ecore_Event_Filter *ef;
|
Ecore_Event_Filter *ef;
|
||||||
Ecore_Event_Handler *eh;
|
Ecore_Event_Handler *eh;
|
||||||
int handle_count;
|
Eina_List *l, *l_next;
|
||||||
|
|
||||||
EINA_INLIST_FOREACH(event_filters, ef)
|
EINA_INLIST_FOREACH(event_filters, ef)
|
||||||
{
|
{
|
||||||
if (!ef->delete_me)
|
if (!ef->delete_me)
|
||||||
{
|
{
|
||||||
|
ef->references++;
|
||||||
|
|
||||||
if (ef->func_start)
|
if (ef->func_start)
|
||||||
ef->loop_data = ef->func_start(ef->data);
|
ef->loop_data = ef->func_start(ef->data);
|
||||||
EINA_INLIST_FOREACH(events, e)
|
EINA_INLIST_FOREACH(events, e)
|
||||||
|
@ -416,10 +438,13 @@ _ecore_event_call(void)
|
||||||
}
|
}
|
||||||
if (ef->func_end)
|
if (ef->func_end)
|
||||||
ef->func_end(ef->data, ef->loop_data);
|
ef->func_end(ef->data, ef->loop_data);
|
||||||
|
|
||||||
|
ef->references--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (event_filters_delete_me)
|
if (event_filters_delete_me)
|
||||||
{
|
{
|
||||||
|
int deleted_in_use = 0;
|
||||||
Ecore_Event_Filter *l;
|
Ecore_Event_Filter *l;
|
||||||
EINA_INLIST_FOREACH(event_filters, l)
|
EINA_INLIST_FOREACH(event_filters, l)
|
||||||
{
|
{
|
||||||
|
@ -427,19 +452,26 @@ _ecore_event_call(void)
|
||||||
l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)->next;
|
l = (Ecore_Event_Filter *) EINA_INLIST_GET(l)->next;
|
||||||
if (ef->delete_me)
|
if (ef->delete_me)
|
||||||
{
|
{
|
||||||
|
if (ef->references)
|
||||||
|
{
|
||||||
|
deleted_in_use++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
|
event_filters = (Ecore_Event_Filter *) eina_inlist_remove(EINA_INLIST_GET(event_filters), EINA_INLIST_GET(ef));
|
||||||
ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
|
ECORE_MAGIC_SET(ef, ECORE_MAGIC_NONE);
|
||||||
free(ef);
|
free(ef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
event_filters_delete_me = 0;
|
if (!deleted_in_use)
|
||||||
|
event_filters_delete_me = 0;
|
||||||
}
|
}
|
||||||
// printf("EVENT BATCH...\n");
|
// printf("EVENT BATCH...\n");
|
||||||
EINA_INLIST_FOREACH(events, e)
|
EINA_INLIST_FOREACH(events, e)
|
||||||
{
|
{
|
||||||
if (!e->delete_me)
|
if (!e->delete_me)
|
||||||
{
|
{
|
||||||
handle_count = 0;
|
int handle_count = 0;
|
||||||
ecore_raw_event_type = e->type;
|
ecore_raw_event_type = e->type;
|
||||||
ecore_raw_event_event = e->event;
|
ecore_raw_event_event = e->event;
|
||||||
// printf("HANDLE ev type %i, %p\n", e->type, e->event);
|
// printf("HANDLE ev type %i, %p\n", e->type, e->event);
|
||||||
|
@ -449,8 +481,15 @@ _ecore_event_call(void)
|
||||||
{
|
{
|
||||||
if (!eh->delete_me)
|
if (!eh->delete_me)
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
handle_count++;
|
handle_count++;
|
||||||
if (!eh->func(eh->data, e->type, e->event))
|
|
||||||
|
eh->references++;
|
||||||
|
ret = eh->func(eh->data, e->type, e->event);
|
||||||
|
eh->references--;
|
||||||
|
|
||||||
|
if (!ret)
|
||||||
break; /* 0 == "call no further handlers" */
|
break; /* 0 == "call no further handlers" */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,11 +504,14 @@ _ecore_event_call(void)
|
||||||
ecore_raw_event_type = ECORE_EVENT_NONE;
|
ecore_raw_event_type = ECORE_EVENT_NONE;
|
||||||
ecore_raw_event_event = NULL;
|
ecore_raw_event_event = NULL;
|
||||||
|
|
||||||
while (events) _ecore_event_del((Ecore_Event *) events);
|
_ecore_event_purge_deleted();
|
||||||
EINA_LIST_FREE(event_handlers_delete_list, eh)
|
EINA_LIST_FOREACH_SAFE(event_handlers_delete_list, l, l_next, eh)
|
||||||
{
|
{
|
||||||
|
if (eh->references) continue;
|
||||||
|
|
||||||
|
event_handlers_delete_list = eina_list_remove_list(event_handlers_delete_list, l);
|
||||||
|
|
||||||
event_handlers[eh->type] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
|
event_handlers[eh->type] = (Ecore_Event_Handler *) eina_inlist_remove(EINA_INLIST_GET(event_handlers[eh->type]), EINA_INLIST_GET(eh));
|
||||||
event_handlers_delete_list = eina_list_remove(event_handlers_delete_list, eh);
|
|
||||||
ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
|
ECORE_MAGIC_SET(eh, ECORE_MAGIC_NONE);
|
||||||
free(eh);
|
free(eh);
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,7 +137,6 @@ int _ecore_idle_exiter_exist(void);
|
||||||
void _ecore_event_shutdown(void);
|
void _ecore_event_shutdown(void);
|
||||||
int _ecore_event_exist(void);
|
int _ecore_event_exist(void);
|
||||||
Ecore_Event *_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data);
|
Ecore_Event *_ecore_event_add(int type, void *ev, void (*func_free) (void *data, void *ev), void *data);
|
||||||
void *_ecore_event_del(Ecore_Event *event);
|
|
||||||
void _ecore_event_call(void);
|
void _ecore_event_call(void);
|
||||||
|
|
||||||
Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe);
|
Ecore_Timer *_ecore_exe_doomsday_clock_get(Ecore_Exe *exe);
|
||||||
|
|
Loading…
Reference in New Issue