From 151df126ebfac835c20f4c0239221a36f7f884ff Mon Sep 17 00:00:00 2001 From: raster Date: Mon, 29 Aug 2011 12:14:55 +0000 Subject: [PATCH] i've found a subtle issue with how we queue recalcs of smart objs. if an obj is already queued we dont push it FURTHEr down the queue if smart recalc is enabled. now at least we keep order of operation/calc correctly! git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@62944 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/canvas/evas_main.c | 2 ++ src/lib/canvas/evas_object_smart.c | 72 ++++++++++++++++++++++++++++++-------- src/lib/include/evas_private.h | 3 ++ 3 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/lib/canvas/evas_main.c b/src/lib/canvas/evas_main.c index a1eb035..05fce4f 100644 --- a/src/lib/canvas/evas_main.c +++ b/src/lib/canvas/evas_main.c @@ -249,6 +249,8 @@ evas_free(Evas *e) eina_array_flush(&e->calculate_objects); eina_array_flush(&e->clip_changes); + eina_list_free(e->calc_list); + e->magic = 0; free(e); } diff --git a/src/lib/canvas/evas_object_smart.c b/src/lib/canvas/evas_object_smart.c index 979a97c..f45bc66 100644 --- a/src/lib/canvas/evas_object_smart.c +++ b/src/lib/canvas/evas_object_smart.c @@ -10,7 +10,8 @@ struct _Evas_Object_Smart void *engine_data; void *data; Eina_List *callbacks; - Eina_Inlist *contained; + Eina_Inlist *contained; + Eina_List *calc_node; Evas_Smart_Cb_Description_Array callbacks_descriptions; int walking_list; Eina_Bool deletions_waiting : 1; @@ -548,7 +549,38 @@ evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value) return; MAGIC_CHECK_END(); + // XXX: do i need this? + if (obj->delete_me) return; + value = !!value; + if (value) + { + Evas *e = obj->layer->evas; + + if (o->need_recalculate) + { + if ((o->calc_node) && (e->calc_list_current != o->calc_node)) + e->calc_list = eina_list_demote_list(e->calc_list, + o->calc_node); + else + e->calc_list = eina_list_append(e->calc_list, obj); + } + else + e->calc_list = eina_list_append(e->calc_list, obj); + o->calc_node = eina_list_last(e->calc_list); + } + else + { + Evas *e = obj->layer->evas; + + if (o->need_recalculate) + { + if ((o->calc_node) && (e->calc_list_current != o->calc_node)) + e->calc_list = eina_list_remove_list(e->calc_list, + o->calc_node); + o->calc_node = NULL; + } + } if (o->need_recalculate == value) return; @@ -568,11 +600,14 @@ evas_object_smart_need_recalculate_set(Evas_Object *obj, Eina_Bool value) * XXX: on _evas_render_call_smart_calculate() will check for the flag * XXX: and it will be unset after the first. */ + +/* if (o->need_recalculate) { Evas *e = obj->layer->evas; eina_array_push(&e->calculate_objects, obj); } + */ /* TODO: else, remove from array */ } @@ -638,31 +673,31 @@ evas_call_smarts_calculate(Evas *e) { Eina_Array *calculate; Evas_Object *obj; - Eina_Array_Iterator it; - unsigned int i; + Eina_List *l; +// printf("+CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALC-----------v\n"); evas_event_freeze(e); e->in_smart_calc++; - calculate = &e->calculate_objects; - for (i = 0; i < eina_array_count_get(calculate); ++i) + + EINA_LIST_FOREACH(e->calc_list, l, obj) { - Evas_Object_Smart *o; - - obj = eina_array_data_get(calculate, i); - if (obj->delete_me) - continue; - - o = obj->object_data; + Evas_Object_Smart *o = obj->object_data; + + if (obj->delete_me) continue; + e->calc_list_current = l; if (o->need_recalculate) { o->need_recalculate = 0; obj->smart.smart->smart_class->calculate(obj); } + if (o->calc_node == l) o->calc_node = NULL; + e->calc_list_current = NULL; } - EINA_ARRAY_ITER_NEXT(calculate, i, obj, it) + EINA_LIST_FREE(e->calc_list, obj) { obj->recalculate_cycle = 0; } + e->calc_list_current = NULL; e->in_smart_calc--; if (e->in_smart_calc == 0) { @@ -671,6 +706,7 @@ evas_call_smarts_calculate(Evas *e) } evas_event_thaw(e); evas_event_thaw_eval(e); +// printf("-CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALC-----------^\n"); } EAPI void @@ -731,13 +767,19 @@ evas_object_smart_cleanup(Evas_Object *obj) o = (Evas_Object_Smart *)(obj->object_data); if (o->magic == MAGIC_OBJ_SMART) { + Evas *e = obj->layer->evas; + + if ((o->calc_node) && (e->calc_list_current != o->calc_node)) + e->calc_list = eina_list_remove_list(e->calc_list, + o->calc_node); + o->calc_node = NULL; while (o->contained) - evas_object_smart_member_del((Evas_Object *)o->contained); + evas_object_smart_member_del((Evas_Object *)o->contained); while (o->callbacks) { Evas_Smart_Callback *cb; - + cb = o->callbacks->data; o->callbacks = eina_list_remove(o->callbacks, cb); if (cb->event) eina_stringshare_del(cb->event); diff --git a/src/lib/include/evas_private.h b/src/lib/include/evas_private.h index b183c87..7eeee99 100644 --- a/src/lib/include/evas_private.h +++ b/src/lib/include/evas_private.h @@ -305,6 +305,9 @@ struct _Evas Eina_Array calculate_objects; Eina_Array clip_changes; + Eina_List *calc_list; + Eina_List *calc_list_current; + Eina_List *post_events; // free me on evas_free Evas_Callbacks *callbacks; -- 2.7.4