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);
eina_stringshare_del(group_path_entry);
edje_object_signal_callback_add(child_obj, "*", "*",
_cb_signal_repeat, obj);
edje_object_propagate_callback_add(child_obj,
_cb_signal_repeat,
obj);
if (rp->part->type == EDJE_PART_TYPE_GROUP)
{
_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.src = alias ? alias : new_src;
emsg.data = NULL;
_edje_message_send(ed_parent, EDJE_QUEUE_SCRIPT, EDJE_MESSAGE_SIGNAL,
0, &emsg);
_edje_message_send(ed_parent, EDJE_QUEUE_SCRIPT,
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,
Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data)
void *data,
Eina_Bool prop __UNUSED__)
{
size_t i;
size_t j;
@ -457,7 +458,9 @@ edje_match_callback_exec_check_finals(const Edje_Patterns *singal_ppat,
const char *sig,
const char *source,
Eina_List *callbacks,
Edje *ed)
Edje *ed,
Eina_Bool prop
)
{
size_t i;
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);
if (escb)
{
if ((prop) && (escb->propagate)) continue;
if ((!escb->just_added)
&& (!escb->delete_me))
{
@ -574,7 +578,8 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
const char *source,
Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data)
void *data,
Eina_Bool prop)
{
Edje_States *signal_result;
Edje_States *source_result;
@ -600,7 +605,8 @@ edje_match_programs_exec(const Edje_Patterns *ppat_signal,
source_result,
programs,
func,
data);
data,
prop);
return r;
}
@ -610,7 +616,9 @@ edje_match_callback_exec(Edje_Patterns *ppat_signal,
const char *sig,
const char *source,
Eina_List *callbacks,
Edje *ed)
Edje *ed,
Eina_Bool prop
)
{
Edje_States *signal_result;
Edje_States *source_result;
@ -641,7 +649,8 @@ edje_match_callback_exec(Edje_Patterns *ppat_signal,
sig,
source,
callbacks,
ed);
ed,
prop);
ppat_signal->ref--;
ppat_source->ref--;
if (ppat_signal->ref <= 0) edje_match_patterns_free(ppat_signal);

View File

@ -1,5 +1,7 @@
#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 Ecore_Job *_job = NULL;
static Ecore_Timer *_job_loss_timer = NULL;
@ -13,8 +15,8 @@ static int tmp_msgq_restart = 0;
* API *
*============================================================================*/
EAPI void
edje_object_message_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg)
static void
_edje_object_message_popornot_send(Evas_Object *obj, Edje_Message_Type type, int id, void *msg, Eina_Bool prop)
{
Edje *ed;
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);
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)
{
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
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
_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 */
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);
if (!em) return;
em->propagated = prop;
if (_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)
{
_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
{
@ -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);
}
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
_edje_message_parameters_push(Edje_Message *em)
{
@ -640,7 +656,8 @@ _edje_message_process(Edje_Message *em)
_edje_emit_handle(em->edje,
((Edje_Message_Signal *)em->msg)->sig,
((Edje_Message_Signal *)em->msg)->src,
((Edje_Message_Signal *)em->msg)->data);
((Edje_Message_Signal *)em->msg)->data,
em->propagated);
return;
}
/* 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;
unsigned char just_added : 1;
unsigned char delete_me : 1;
unsigned char propagate : 1;
};
struct _Edje_Text_Insert_Filter_Callback
@ -1435,6 +1436,7 @@ struct _Edje_Message
Edje_Message_Type type;
int id;
unsigned char *msg;
Eina_Bool propagated : 1;
};
typedef enum _Edje_Fill
@ -1482,13 +1484,15 @@ Eina_Bool edje_match_programs_exec(const Edje_Patterns *ppat_signal,
const char *source,
Edje_Program **programs,
Eina_Bool (*func)(Edje_Program *pr, void *data),
void *data);
void *data,
Eina_Bool prop);
int edje_match_callback_exec(Edje_Patterns *ppat_signal,
Edje_Patterns *ppat_source,
const char *signal,
const char *source,
Eina_List *callbacks,
Edje *ed);
Edje *ed,
Eina_Bool prop);
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_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_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_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);
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_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_parameters_push (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_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 */
EAPI void _edje_program_insert(Edje_Part_Collection *ed, Edje_Program *p);

View File

@ -1,6 +1,6 @@
#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_set(Edje_Real_Part *part, const char *param, const char *value);
@ -25,6 +25,31 @@ edje_frametime_get(void)
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
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??? */
void
_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 (!sig) sig = "";
@ -1187,7 +1212,8 @@ _edje_emit_handle(Edje *ed, const char *sig, const char *src,
src,
ed->patterns.programs.u.programs.globing,
_edje_glob_callback,
&data) == 0)
&data,
prop) == 0)
goto break_prog;
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
}
_edje_emit_cb(ed, sig, src, sdata);
_edje_emit_cb(ed, sig, src, sdata, prop);
if (_edje_block_break(ed))
{
goto break_prog;
@ -1237,7 +1263,7 @@ edje_object_signal_callback_extra_data_get(void)
/* FIXME: what if we delete the evas object??? */
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;
@ -1266,7 +1292,8 @@ _edje_emit_cb(Edje *ed, const char *sig, const char *src, Edje_Message_Signal_Da
sig,
src,
ed->patterns.callbacks.u.callbacks.globing,
ed);
ed,
prop);
if (!r)
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,
ed->patterns.callbacks.exact_match);
EINA_LIST_FOREACH(match, l2, escb)
if ((!escb->just_added) && (!escb->delete_me))
{
escb->func(escb->data, ed->obj, sig, src);
if (_edje_block_break(ed))
goto break_prog;
}
{
if ((prop) && (escb->propagate)) continue;
if ((!escb->just_added) && (!escb->delete_me))
{
escb->func(escb->data, ed->obj, sig, src);
if (_edje_block_break(ed))
goto break_prog;
}
}
}
break_prog: