fix awful event re-propagation between every part and parent and part
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 24 Nov 2011 11:51:11 +0000 (11:51 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 24 Nov 2011 11:51:11 +0000 (11:51 +0000)
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.

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/edje@65571 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/edje_load.c
src/lib/edje_match.c
src/lib/edje_message_queue.c
src/lib/edje_private.h
src/lib/edje_program.c

index c9b77da..644bb7c 100644 (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);
 }
index 5a98cd6..f113f7b 100644 (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);
index 3ba4fd5..1a313a5 100644 (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
      {
@@ -513,6 +523,12 @@ _edje_message_send(Edje *ed, Edje_Queue queue, Edje_Message_Type type, int id, v
 }
 
 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)
 {
    int i;
@@ -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 */
index e42aa6c..8f55912 100644 (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);
index bd18234..2c139e9 100644 (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: