fix awful event re-propagation between every part and parent and part

and.... u get the idea. this made an n^m list of messages... where n
was 3 of messages sent and m was # of child parts (42 of them)... this
caused a silly 3 of timers to be allocated... don't ask how many. in a
simple snapshot i saw 101mb of timers allocated... and i was just
starting... anyway - this makes the propagatiopn not propagate down
and then back up again... and it only needs 1 timer allocated to
handle a re-schedule of processing messages. not N. "leak" that was
just a massive memory spike) is now fixed.



SVN revision: 65571
This commit is contained in:
Carsten Haitzler 2011-11-24 11:51:11 +00:00
parent d5eca4d187
commit 2c283ada65
5 changed files with 96 additions and 32 deletions

View File

@ -731,8 +731,9 @@ _edje_object_file_set_internal(Evas_Object *obj, const char *file, const char *g
group_path = eina_list_remove(group_path, group_path_entry); group_path = eina_list_remove(group_path, group_path_entry);
eina_stringshare_del(group_path_entry); eina_stringshare_del(group_path_entry);
edje_object_signal_callback_add(child_obj, "*", "*", edje_object_propagate_callback_add(child_obj,
_cb_signal_repeat, obj); _cb_signal_repeat,
obj);
if (rp->part->type == EDJE_PART_TYPE_GROUP) if (rp->part->type == EDJE_PART_TYPE_GROUP)
{ {
_edje_real_part_swallow(rp, child_obj, EINA_TRUE); _edje_real_part_swallow(rp, child_obj, EINA_TRUE);
@ -1519,6 +1520,6 @@ _cb_signal_repeat(void *data, Evas_Object *obj, const char *sig, const char *sou
emsg.sig = sig; emsg.sig = sig;
emsg.src = alias ? alias : new_src; emsg.src = alias ? alias : new_src;
emsg.data = NULL; emsg.data = NULL;
_edje_message_send(ed_parent, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL, _edje_message_send(ed_parent, EDJE_QUEUE_SCRIPT,
0, &emsg); EDJE_MESSAGE_SIGNAL, 0, &emsg);
} }

View File

@ -414,7 +414,8 @@ edje_match_programs_exec_check_finals(const size_t *signal_finals,
const Edje_States *source_states, const Edje_States *source_states,
Edje_Program **programs, Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data), Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data) void *data,
Eina_Bool prop __UNUSED__)
{ {
size_t i; size_t i;
size_t j; size_t j;
@ -457,7 +458,9 @@ edje_match_callback_exec_check_finals(const Edje_Patterns *singal_ppat,
const char *sig, const char *sig,
const char *source, const char *source,
Eina_List *callbacks, Eina_List *callbacks,
Edje *ed) Edje *ed,
Eina_Bool prop
)
{ {
size_t i; size_t i;
size_t j; size_t j;
@ -477,6 +480,7 @@ edje_match_callback_exec_check_finals(const Edje_Patterns *singal_ppat,
escb = eina_list_nth(callbacks, signal_states->states[i].idx); escb = eina_list_nth(callbacks, signal_states->states[i].idx);
if (escb) if (escb)
{ {
if ((prop) && (escb->propagate)) continue;
if ((!escb->just_added) if ((!escb->just_added)
&& (!escb->delete_me)) && (!escb->delete_me))
{ {
@ -574,7 +578,8 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
const char *source, const char *source,
Edje_Program **programs, Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data), Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data) void *data,
Eina_Bool prop)
{ {
Edje_States *signal_result; Edje_States *signal_result;
Edje_States *source_result; Edje_States *source_result;
@ -600,7 +605,8 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
source_result, source_result,
programs, programs,
func, func,
data); data,
prop);
return r; return r;
} }
@ -610,7 +616,9 @@ edje_match_callback_exec(Edje_Patterns *ppat_signal,
const char *sig, const char *sig,
const char *source, const char *source,
Eina_List *callbacks, Eina_List *callbacks,
Edje *ed) Edje *ed,
Eina_Bool prop
)
{ {
Edje_States *signal_result; Edje_States *signal_result;
Edje_States *source_result; Edje_States *source_result;
@ -641,7 +649,8 @@ edje_match_callback_exec(Edje_Patterns *ppat_signal,
sig, sig,
source, source,
callbacks, callbacks,
ed); ed,
prop);
ppat_signal->ref--; ppat_signal->ref--;
ppat_source->ref--; ppat_source->ref--;
if (ppat_signal->ref <= 0) edje_match_patterns_free(ppat_signal); if (ppat_signal->ref <= 0) edje_match_patterns_free(ppat_signal);

View File

@ -1,5 +1,7 @@
#include "edje_private.h" #include "edje_private.h"
static void _edje_object_message_popornot_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg, Eina_Bool prop);
static int _injob = 0; static int _injob = 0;
static Ecore_Job *_job = NULL; static Ecore_Job *_job = NULL;
static Ecore_Timer *_job_loss_timer = NULL; static Ecore_Timer *_job_loss_timer = NULL;
@ -13,8 +15,8 @@ static int tmp_msgq_restart = 0;
* API * * API *
*============================================================================*/ *============================================================================*/
EAPI void static void
edje_object_message_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg) _edje_object_message_popornot_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg, Eina_Bool prop)
{ {
Edje *ed; Edje *ed;
Eina_List *l; Eina_List *l;
@ -22,13 +24,19 @@ edje_object_message_send(Evas_Object *obj, Edje_Message_Type type, int id, void
ed = _edje_fetch(obj); ed = _edje_fetch(obj);
if (!ed) return; if (!ed) return;
_edje_message_send(ed, EDJE_QUEUE_SCRIPT, type, id, msg); _edje_message_propornot_send(ed, EDJE_QUEUE_SCRIPT, type, id, msg, prop);
EINA_LIST_FOREACH(ed->subobjs, l, o) EINA_LIST_FOREACH(ed->subobjs, l, o)
{ {
edje_object_message_send(o, type, id, msg); _edje_object_message_popornot_send(o, type, id, msg, EINA_TRUE);
} }
} }
EAPI void
edje_object_message_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg)
{
_edje_object_message_popornot_send(obj, type, id, msg, EINA_FALSE);
}
EAPI void EAPI void
edje_object_message_handler_set(Evas_Object *obj, Edje_Message_Handler_Cb func, void *data) edje_object_message_handler_set(Evas_Object *obj, Edje_Message_Handler_Cb func, void *data)
@ -339,7 +347,7 @@ _edje_message_free(Edje_Message *em)
} }
void void
_edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg) _edje_message_propornot_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg, Eina_Bool prop)
{ {
/* FIXME: check all malloc & strdup fails and gracefully unroll and exit */ /* FIXME: check all malloc & strdup fails and gracefully unroll and exit */
Edje_Message *em; Edje_Message *em;
@ -348,6 +356,7 @@ _edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, v
em = _edje_message_new(ed, queue, type, id); em = _edje_message_new(ed, queue, type, id);
if (!em) return; if (!em) return;
em->propagated = prop;
if (_job) if (_job)
{ {
ecore_job_del(_job); ecore_job_del(_job);
@ -355,7 +364,8 @@ _edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, v
} }
if (_injob > 0) if (_injob > 0)
{ {
_job_loss_timer = ecore_timer_add(0.01, _edje_job_loss_timer, NULL); if (_job_loss_timer) ecore_timer_del(_job_loss_timer);
_job_loss_timer = ecore_timer_add(0.001, _edje_job_loss_timer, NULL);
} }
else else
{ {
@ -512,6 +522,12 @@ _edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, v
msgq = eina_list_append(msgq, em); msgq = eina_list_append(msgq, em);
} }
void
_edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg)
{
_edje_message_propornot_send(ed, queue, type, id, emsg, EINA_FALSE);
}
void void
_edje_message_parameters_push(Edje_Message *em) _edje_message_parameters_push(Edje_Message *em)
{ {
@ -640,7 +656,8 @@ _edje_message_process(Edje_Message *em)
_edje_emit_handle(em->edje, _edje_emit_handle(em->edje,
((Edje_Message_Signal *)em->msg)->sig, ((Edje_Message_Signal *)em->msg)->sig,
((Edje_Message_Signal *)em->msg)->src, ((Edje_Message_Signal *)em->msg)->src,
((Edje_Message_Signal *)em->msg)->data); ((Edje_Message_Signal *)em->msg)->data,
em->propagated);
return; return;
} }
/* if this has been queued up for the app then just call the callback */ /* if this has been queued up for the app then just call the callback */

View File

@ -1291,6 +1291,7 @@ struct _Edje_Signal_Callback
void *data; void *data;
unsigned char just_added : 1; unsigned char just_added : 1;
unsigned char delete_me : 1; unsigned char delete_me : 1;
unsigned char propagate : 1;
}; };
struct _Edje_Text_Insert_Filter_Callback struct _Edje_Text_Insert_Filter_Callback
@ -1435,6 +1436,7 @@ struct _Edje_Message
Edje_Message_Type type; Edje_Message_Type type;
int id; int id;
unsigned char *msg; unsigned char *msg;
Eina_Bool propagated : 1;
}; };
typedef enum _Edje_Fill typedef enum _Edje_Fill
@ -1482,13 +1484,15 @@ Eina_Bool edje_match_programs_exec(const Edje_Patterns *ppat_signal,
const char *source, const char *source,
Edje_Program **programs, Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data), Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data); void *data,
Eina_Bool prop);
int edje_match_callback_exec(Edje_Patterns *ppat_signal, int edje_match_callback_exec(Edje_Patterns *ppat_signal,
Edje_Patterns *ppat_source, Edje_Patterns *ppat_source,
const char *signal, const char *signal,
const char *source, const char *source,
Eina_List *callbacks, Eina_List *callbacks,
Edje *ed); Edje *ed,
Eina_Bool prop);
void edje_match_patterns_free(Edje_Patterns *ppat); void edje_match_patterns_free(Edje_Patterns *ppat);
@ -1593,7 +1597,7 @@ void _edje_programs_patterns_clean(Edje *ed);
void _edje_programs_patterns_init(Edje *ed); void _edje_programs_patterns_init(Edje *ed);
void _edje_emit(Edje *ed, const char *sig, const char *src); void _edje_emit(Edje *ed, const char *sig, const char *src);
void _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*free_func)(void *)); void _edje_emit_full(Edje *ed, const char *sig, const char *src, void *data, void (*free_func)(void *));
void _edje_emit_handle(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data); void _edje_emit_handle(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop);
void _edje_signals_sources_patterns_clean(Edje_Signals_Sources_Patterns *ssp); void _edje_signals_sources_patterns_clean(Edje_Signals_Sources_Patterns *ssp);
void _edje_callbacks_patterns_clean(Edje *ed); void _edje_callbacks_patterns_clean(Edje *ed);
@ -1723,6 +1727,7 @@ void _edje_message_shutdown (void);
void _edje_message_cb_set (Edje *ed, void (*func) (void *data, Evas_Object *obj, Edje_Message_Type type, int id, void *msg), void *data); void _edje_message_cb_set (Edje *ed, void (*func) (void *data, Evas_Object *obj, Edje_Message_Type type, int id, void *msg), void *data);
Edje_Message *_edje_message_new (Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id); Edje_Message *_edje_message_new (Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id);
void _edje_message_free (Edje_Message *em); void _edje_message_free (Edje_Message *em);
void _edje_message_propornot_send (Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg, Eina_Bool prop);
void _edje_message_send (Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg); void _edje_message_send (Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, void *emsg);
void _edje_message_parameters_push (Edje_Message *em); void _edje_message_parameters_push (Edje_Message *em);
void _edje_message_process (Edje_Message *em); void _edje_message_process (Edje_Message *em);
@ -1936,6 +1941,8 @@ edje_program_is_strrncmp(const char *str)
return EINA_FALSE; return EINA_FALSE;
return EINA_TRUE; return EINA_TRUE;
} }
void edje_object_propagate_callback_add(Evas_Object *obj, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data);
/* used by edje_cc - private still */ /* used by edje_cc - private still */
EAPI void _edje_program_insert(Edje_Part_Collection *ed, Edje_Program *p); EAPI void _edje_program_insert(Edje_Part_Collection *ed, Edje_Program *p);

View File

@ -1,6 +1,6 @@
#include "edje_private.h" #include "edje_private.h"
static void _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data); static void _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop);
static void _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param); static void _edje_param_copy(Edje_Real_Part *src_part, const char *src_param, Edje_Real_Part *dst_part, const char *dst_param);
static void _edje_param_set(Edje_Real_Part *part, const char *param, const char *value); static void _edje_param_set(Edje_Real_Part *part, const char *param, const char *value);
@ -25,6 +25,31 @@ edje_frametime_get(void)
return ecore_animator_frametime_get(); return ecore_animator_frametime_get();
} }
void
edje_object_propagate_callback_add(Evas_Object *obj, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
{
Edje *ed;
Edje_Signal_Callback *escb;
ed = _edje_fetch(obj);
if (!ed) return;
if (ed->delete_me) return;
escb = calloc(1, sizeof(Edje_Signal_Callback));
escb->propagate = EINA_TRUE;
escb->signal = eina_stringshare_add("*");
escb->source = eina_stringshare_add("*");
escb->func = func;
escb->data = data;
ed->callbacks = eina_list_append(ed->callbacks, escb);
if (ed->walking_callbacks)
{
escb->just_added = 1;
ed->just_added_callbacks = 1;
}
else
_edje_callbacks_patterns_clean(ed);
}
EAPI void EAPI void
edje_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data) edje_object_signal_callback_add(Evas_Object *obj, const char *emission, const char *source, void (*func) (void *data, Evas_Object *o, const char *emission, const char *source), void *data)
{ {
@ -1092,7 +1117,7 @@ _edje_callbacks_patterns_init(Edje *ed)
/* FIXME: what if we delete the evas object??? */ /* FIXME: what if we delete the evas object??? */
void void
_edje_emit_handle(Edje *ed, const char *sig, const char *src, _edje_emit_handle(Edje *ed, const char *sig, const char *src,
Edje_Message_Signal_Data *sdata) Edje_Message_Signal_Data *sdata, Eina_Bool prop)
{ {
if (ed->delete_me) return; if (ed->delete_me) return;
if (!sig) sig = ""; if (!sig) sig = "";
@ -1187,7 +1212,8 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src,
src, src,
ed->patterns.programs.u.programs.globing, ed->patterns.programs.u.programs.globing,
_edje_glob_callback, _edje_glob_callback,
&data) == 0) &data,
prop) == 0)
goto break_prog; goto break_prog;
match = edje_match_signal_source_hash_get(sig, src, match = edje_match_signal_source_hash_get(sig, src,
@ -1214,7 +1240,7 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src,
} }
#endif #endif
} }
_edje_emit_cb(ed, sig, src, sdata); _edje_emit_cb(ed, sig, src, sdata, prop);
if (_edje_block_break(ed)) if (_edje_block_break(ed))
{ {
goto break_prog; goto break_prog;
@ -1237,7 +1263,7 @@ edje_object_signal_callback_extra_data_get(void)
/* FIXME: what if we delete the evas object??? */ /* FIXME: what if we delete the evas object??? */
static void static void
_edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data) _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Data *data, Eina_Bool prop)
{ {
Eina_List *l; Eina_List *l;
@ -1266,7 +1292,8 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Da
sig, sig,
src, src,
ed->patterns.callbacks.u.callbacks.globing, ed->patterns.callbacks.u.callbacks.globing,
ed); ed,
prop);
if (!r) if (!r)
goto break_prog; goto break_prog;
@ -1274,12 +1301,15 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Da
match = edje_match_signal_source_hash_get(sig, src, match = edje_match_signal_source_hash_get(sig, src,
ed->patterns.callbacks.exact_match); ed->patterns.callbacks.exact_match);
EINA_LIST_FOREACH(match, l2, escb) EINA_LIST_FOREACH(match, l2, escb)
if ((!escb->just_added) && (!escb->delete_me)) {
{ if ((prop) && (escb->propagate)) continue;
escb->func(escb->data, ed->obj, sig, src); if ((!escb->just_added) && (!escb->delete_me))
if (_edje_block_break(ed)) {
goto break_prog; escb->func(escb->data, ed->obj, sig, src);
} if (_edje_block_break(ed))
goto break_prog;
}
}
} }
break_prog: break_prog: