lets do that again. recalc list instead of recalc array. why? fixes

nasty ordering issues where recalc items dont get pushed later into
the recalc queue after the things they depend on.



SVN revision: 62977
This commit is contained in:
Carsten Haitzler 2011-08-29 23:45:24 +00:00
parent 5a4163f5f2
commit 8833075666
3 changed files with 65 additions and 38 deletions

View File

@ -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);
}

View File

@ -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,32 +549,51 @@ 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 (o->need_recalculate == value)
return;
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;
if (obj->recalculate_cycle > 64)
{
ERR("Object %p is not stable during recalc loop", obj);
return ;
return;
}
if (obj->layer->evas->in_smart_calc)
obj->recalculate_cycle++;
if (obj->layer->evas->in_smart_calc) obj->recalculate_cycle++;
o->need_recalculate = value;
if (!obj->smart.smart->smart_class->calculate) return;
/* XXX: objects can be present multiple times in calculate_objects()
* XXX: after a set-unset-set cycle, but it's not a problem since
* 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 */
}
EAPI Eina_Bool
@ -636,41 +656,37 @@ evas_smart_objects_calculate_count_get(const Evas *e)
void
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)
{
eina_array_clean(calculate);
e->smart_calc_count++;
}
if (e->in_smart_calc == 0) e->smart_calc_count++;
evas_event_thaw(e);
evas_event_thaw_eval(e);
// printf("-CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALC-----------^\n");
}
EAPI void
@ -731,13 +747,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);

View File

@ -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;