cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=d052f001bee68517af7e6d5fec47c2345fff33f2
commit d052f001bee68517af7e6d5fec47c2345fff33f2 Author: Cedric Bail <ced...@osg.samsung.com> Date: Wed May 9 20:07:01 2018 -0700 eo: move destruction of the link with children to be always after invalidate. --- src/lib/eo/eo_base_class.c | 51 +++++++++++++++++++++++++++++++++++++--------- src/lib/eo/eo_private.h | 20 +----------------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c index 3baff35724..d3c7619c26 100644 --- a/src/lib/eo/eo_base_class.c +++ b/src/lib/eo/eo_base_class.c @@ -132,21 +132,11 @@ _efl_pending_futures_clear(Efl_Object_Data *pd) static void _efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd) { - Eina_Inlist *l; - _Eo_Object *child; - _efl_pending_futures_clear(pd); EO_OBJ_POINTER(obj_id, obj); if (obj->invalidate) goto end; - // Invalidate all children too - EINA_INLIST_FOREACH_SAFE(pd->children, l, child) - { - Eo *child_id = _eo_obj_id_get(child); - efl_parent_set(child_id, NULL); - } - // Finally invalidate itself if it wasn't done already // I am not sure this is a good idea, but it force the // behavior of calling directly efl_invalidate to be the @@ -160,6 +150,47 @@ _efl_object_invalidate(Eo *obj_id, Efl_Object_Data *pd) EO_OBJ_DONE(obj_id); } +// Generate the invalidate event in all case and make sure it happens +// before any user code can change the children invalidate state. This +// make sure that the entire tree of object is valid at the time of +// the invalidate event. +void +_efl_invalidate(_Eo_Object *obj) +{ + Eina_Array stash = { 0 }; + Efl_Object_Data *pd; + _Eo_Object *child; + Eo *id; + + if (obj->is_invalidating) return ; + obj->is_invalidating = EINA_TRUE; + if (obj->invalidate) return; + + id = _eo_obj_id_get(obj); + + efl_event_callback_call(id, EFL_EVENT_INVALIDATE, NULL); + + pd = efl_data_scope_get(id, EFL_OBJECT_CLASS); + + efl_invalidate(id); + + eina_array_step_set(&stash, sizeof (stash), 4); + + // Invalidate all children too + EINA_INLIST_FOREACH(pd->children, child) + eina_array_push(&stash, _efl_ref(child)); + + while ((child = eina_array_pop(&stash))) + { + Eo *child_id = _eo_obj_id_get(child); + + efl_parent_set(child_id, NULL); + _efl_unref(child); + } + + eina_array_flush(&stash); +} + static void _efl_object_noref(Eo *obj EINA_UNUSED, Efl_Object_Data *pd EINA_UNUSED) { diff --git a/src/lib/eo/eo_private.h b/src/lib/eo/eo_private.h index 96e7b7fee0..6302eeeafe 100644 --- a/src/lib/eo/eo_private.h +++ b/src/lib/eo/eo_private.h @@ -251,25 +251,7 @@ _eo_condtor_reset(_Eo_Object *obj) obj->condtor_done = EINA_FALSE; } -// Generate the invalidate event in all case and make sure it happens -// before any user code can change the children invalidate state. This -// make sure that the entire tree of object is valid at the time of -// the invalidate event. -static void -_efl_invalidate(_Eo_Object *obj) -{ - Eo *id; - - if (obj->is_invalidating) return ; - obj->is_invalidating = EINA_TRUE; - if (obj->invalidate) return; - - id = _eo_obj_id_get(obj); - - efl_event_callback_call(id, EFL_EVENT_INVALIDATE, NULL); - - efl_invalidate(id); -} +void _efl_invalidate(_Eo_Object *obj); static inline void _efl_del_internal(_Eo_Object *obj, const char *func_name, const char *file, int line) --