genilst: get rid of lazy deletion.

delete genlist item directly.
instead, remove the bunch of code that was related to lazy deletion.

we can success, if we clean up the resources and callback calls properly.
here i only found item focus callback that (may) required the lazy deletion.
This commit is contained in:
ChunEon Park 2015-01-08 23:03:52 +09:00
parent 9494c4cbad
commit a045ca8289
3 changed files with 54 additions and 175 deletions

View File

@ -154,7 +154,7 @@ static void _access_activate_cb(void *data EINA_UNUSED,
Evas_Object *part_obj EINA_UNUSED,
Elm_Object_Item *item);
static void _decorate_item_set(Elm_Gen_Item *);
static void _internal_elm_genlist_clear(Evas_Object *obj, Eina_Bool standby);
static void _internal_elm_genlist_clear(Evas_Object *obj);
static const Elm_Action key_actions[] = {
{"move", _key_action_move},
@ -1286,9 +1286,7 @@ _decorate_all_item_realize(Elm_Gen_Item *it,
if (!it) return;
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if ((it->item->decorate_all_item_realized) ||
(it->generation < sd->generation))
return;
if (it->item->decorate_all_item_realized) return;
it->deco_all_view = edje_object_add(evas_object_evas_get(WIDGET(it)));
edje_object_scale_set(it->deco_all_view, elm_widget_scale_get(WIDGET(it)) *
@ -1623,7 +1621,6 @@ _item_realize(Elm_Gen_Item *it,
int tsize = 20;
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if (it->generation < sd->generation) return;
if (it->realized)
{
if (it->item->order_num_in != in)
@ -2157,9 +2154,7 @@ _item_block_position(Item_Block *itb,
EINA_LIST_FOREACH(itb->items, l, it)
{
sd = GL_IT(it)->wsd;
if (it->generation < sd->generation) continue;
else if (sd->reorder_it == it)
continue;
if (sd->reorder_it == it) continue;
it->x = 0;
it->y = y;
@ -2386,9 +2381,7 @@ _item_multi_select_up(Elm_Genlist_Data *sd)
while (eo_prev)
{
ELM_GENLIST_ITEM_DATA_GET(eo_prev, prev);
if ((prev->generation == sd->generation) &&
(!_is_no_select(prev)) &&
(!elm_object_item_disabled_get(eo_prev)))
if ((!_is_no_select(prev)) && (!elm_object_item_disabled_get(eo_prev)))
break;
eo_prev = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev));
}
@ -2418,9 +2411,7 @@ _item_multi_select_down(Elm_Genlist_Data *sd)
while ((eo_next))
{
ELM_GENLIST_ITEM_DATA_GET(eo_next, next);
if ((next->generation == sd->generation) &&
(!_is_no_select(next)) &&
(!elm_object_item_disabled_get(eo_next)))
if ((_is_no_select(next)) && (!elm_object_item_disabled_get(eo_next)))
break;
eo_next = EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next));
}
@ -2472,8 +2463,7 @@ _item_single_select_up(Elm_Genlist_Data *sd)
while (prev)
{
if ((prev->generation == sd->generation) &&
(!_is_no_select(prev)) &&
if ((!_is_no_select(prev)) &&
(!elm_object_item_disabled_get(EO_OBJ(prev))))
break;
prev = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(prev)->prev);
@ -2503,8 +2493,7 @@ _item_single_select_down(Elm_Genlist_Data *sd)
while ((next))
{
if ((next->generation == sd->generation) &&
(!_is_no_select(next)) &&
if ((!_is_no_select(next)) &&
(!elm_object_item_disabled_get(EO_OBJ(next))))
break;
next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
@ -2527,9 +2516,6 @@ _elm_genlist_item_focused(Elm_Object_Item *eo_it)
ELM_GENLIST_DATA_GET(obj, sd);
const char *focus_raise;
if (it->generation < sd->generation)
return;
if (_is_no_select(it) ||
(eo_it == sd->focused_item) ||
(eo_do(eo_it, elm_wdg_item_disabled_get())))
@ -2569,9 +2555,6 @@ _elm_genlist_item_unfocused(Elm_Object_Item *eo_it)
Evas_Object *obj = WIDGET(it);
ELM_GENLIST_DATA_GET(obj, sd);
if (it->generation < sd->generation)
return;
if (_is_no_select(it))
return;
@ -2608,7 +2591,6 @@ _item_focused_next(Evas_Object *obj, Elm_Focus_Direction dir)
return EINA_FALSE;
while ((next) &&
(next->generation < sd->generation) &&
(!eo_do(EO_OBJ(next), elm_wdg_item_disabled_get())))
next = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(next)->next);
}
@ -3341,7 +3323,6 @@ _item_highlight(Elm_Gen_Item *it)
if (_is_no_select(it) ||
(!sd->highlight) ||
(it->generation < sd->generation) ||
(it->highlighted) || eo_do(EO_OBJ(it), elm_wdg_item_disabled_get()) ||
(it->item->deco_it_view))
return;
@ -3367,8 +3348,7 @@ _item_unhighlight(Elm_Gen_Item *it)
{
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if ((it->generation < GL_IT(it)->wsd->generation) || (!it->highlighted))
return;
if (!it->highlighted) return;
edje_object_signal_emit(VIEW(it), SIGNAL_UNSELECTED, "elm");
evas_object_smart_callback_call(WIDGET(it), SIG_UNHIGHLIGHTED, EO_OBJ(it));
@ -3554,11 +3534,6 @@ _elm_genlist_item_del_not_serious(Elm_Gen_Item *it)
Elm_Object_Item *eo_it = EO_OBJ(it);
eo_do(eo_it, elm_wdg_item_pre_notify_del());
it->generation = sd->generation - 1; /* This means that
* the item is
* deleted */
if (it->walking > 0) return;
if (it->selected)
{
@ -3587,7 +3562,6 @@ _elm_genlist_item_del_serious(Elm_Gen_Item *it)
sd->items = eina_inlist_remove(sd->items, EINA_INLIST_GET(it));
if (it->tooltip.del_cb)
it->tooltip.del_cb((void *)it->tooltip.data, WIDGET(it), it);
sd->walking -= it->walking;
ELM_SAFE_FREE(it->long_timer, ecore_timer_del);
if (GL_IT(it)->type == ELM_GENLIST_ITEM_GROUP)
sd->group_items = eina_list_remove(sd->group_items, it);
@ -3659,7 +3633,6 @@ _item_unselect(Elm_Gen_Item *it)
{
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if ((it->generation < sd->generation)) return;
it->unhighlight_cb(it); /* unhighlight the item first */
if (!it->selected) return; /* then check whether the item is selected */
@ -4800,19 +4773,6 @@ _item_mouse_up_cb(void *data,
if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
it->walking++;
sd->walking++;
if (sd->focused_item != EO_OBJ(it))
elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
it->walking--;
sd->walking--;
if ((sd->clear_me) && (!sd->walking))
{
_internal_elm_genlist_clear(WIDGET(it), EINA_TRUE);
return;
}
if (sd->multi &&
((sd->multi_select_mode != ELM_OBJECT_MULTI_SELECT_MODE_WITH_CONTROL) ||
(evas_key_modifier_is_set(ev->modifiers, "Control"))))
@ -4851,6 +4811,9 @@ _item_mouse_up_cb(void *data,
it->highlight_cb(it);
it->sel_cb(it);
}
if (sd->focused_item != EO_OBJ(it))
elm_object_item_focus_set(EO_OBJ(it), EINA_TRUE);
}
static void
@ -4943,8 +4906,7 @@ _decorate_item_finished_signal_cb(void *data,
te = evas_object_evas_get(obj);
if ((it->generation < sd->generation) || (!it->realized)
|| (!it->item->deco_it_view)) return;
if ((!it->realized) || (!it->item->deco_it_view)) return;
evas_event_freeze(te);
it->item->nocache_once = EINA_FALSE;
@ -5011,7 +4973,6 @@ _item_block_recalc(Item_Block *itb,
EINA_LIST_FOREACH(itb->items, l, it)
{
sd = GL_IT(it)->wsd;
if (it->generation < sd->generation) continue;
show_me |= it->item->show_me;
if (!itb->realized)
{
@ -5290,8 +5251,7 @@ _decorate_item_realize(Elm_Gen_Item *it)
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
Evas_Object *obj = sd->obj;
if ((it->item->deco_it_view) || (it->generation <
sd->generation)) return;
if (it->item->deco_it_view) return;
evas_event_freeze(evas_object_evas_get(obj));
it->item->deco_it_view = _view_create(it, it->itc->decorate_item_style);
@ -5464,8 +5424,6 @@ _elm_genlist_evas_object_smart_add(Eo *obj, Elm_Genlist_Data *priv)
elm_widget_can_focus_set(obj, EINA_TRUE);
elm_widget_on_show_region_hook_set(obj, _show_region_hook, NULL);
priv->generation = 1;
if (!elm_layout_theme_set
(obj, "genlist", "base", elm_widget_style_get(obj)))
CRI("Failed to set layout!");
@ -5631,45 +5589,25 @@ _elm_genlist_eo_base_constructor(Eo *obj, Elm_Genlist_Data *sd)
}
static void
_internal_elm_genlist_clear(Evas_Object *obj,
Eina_Bool standby)
_internal_elm_genlist_clear(Evas_Object *obj)
{
Eina_Inlist *next, *l;
ELM_GENLIST_DATA_GET(obj, sd);
if (!standby) sd->generation++;
_elm_genlist_item_unfocused(sd->focused_item);
if (sd->mode_item) sd->mode_item = NULL;
ELM_SAFE_FREE(sd->state, eina_inlist_sorted_state_free);
if (sd->walking > 0)
{
sd->clear_me = EINA_TRUE;
return;
}
evas_event_freeze(evas_object_evas_get(sd->obj));
for (l = sd->items, next = l ? l->next : NULL;
l;
l = next, next = next ? next->next : NULL)
{
Elm_Gen_Item *it = ELM_GEN_ITEM_FROM_INLIST(l);
if (it->generation < sd->generation)
{
Elm_Gen_Item *itn = NULL;
if (next) itn = ELM_GEN_ITEM_FROM_INLIST(next);
if (itn) itn->walking++; /* prevent early death of subitem */
it->del_cb(it);
eo_del(EO_OBJ(it));
if (itn) itn->walking--;
}
eo_do(EO_OBJ(it), elm_wdg_item_del());
}
sd->clear_me = EINA_FALSE;
sd->pan_changed = EINA_TRUE;
if (!sd->queue)
{
@ -5714,11 +5652,7 @@ _item_select(Elm_Gen_Item *it)
Elm_Object_Item *eo_it = EO_OBJ(it);
if (eo_do(eo_it, elm_wdg_item_disabled_get())) return;
if (_is_no_select(it) ||
(it->generation < sd->generation) ||
(it->decorate_it_set))
return;
if (_is_no_select(it) || (it->decorate_it_set)) return;
if (!sd->multi)
{
@ -5739,15 +5673,12 @@ _item_select(Elm_Gen_Item *it)
}
evas_object_ref(obj);
it->walking++;
sd->walking++;
if (it->func.func) it->func.func((void *)it->func.data, WIDGET(it), eo_it);
if (it->generation == sd->generation)
{
evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it);
elm_object_item_focus_set(eo_it, EINA_TRUE);
_elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
}
evas_object_smart_callback_call(WIDGET(it), SIG_SELECTED, eo_it);
elm_object_item_focus_set(eo_it, EINA_TRUE);
_elm_genlist_item_content_focus_set(it, ELM_FOCUS_PREVIOUS);
sd->last_selected_item = eo_it;
if (!(sd->focus_on_selection_enabled || _elm_config->item_select_on_focus_disable))
{
@ -5764,21 +5695,6 @@ _item_select(Elm_Gen_Item *it)
}
}
it->walking--;
sd->walking--;
if ((sd->clear_me) && (!sd->walking))
_internal_elm_genlist_clear(WIDGET(it), EINA_TRUE);
else
{
if ((!it->walking) && (it->generation < sd->generation))
{
it->del_cb(it);
eo_del(eo_it);
}
else
sd->last_selected_item = eo_it;
}
evas_object_unref(obj);
}
@ -5825,8 +5741,6 @@ _elm_genlist_item_elm_widget_item_disable(Eo *eo_it, Elm_Gen_Item *it)
Eina_List *l;
Evas_Object *obj;
if (it->generation < GL_IT(it)->wsd->generation) return;
_item_unselect(it);
if (eo_it == GL_IT(it)->wsd->focused_item)
_elm_genlist_item_unfocused(eo_it);
@ -5858,39 +5772,35 @@ _elm_genlist_item_elm_widget_item_del_pre(Eo *eo_it, Elm_Gen_Item *it)
{
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if (it->walking > 0)
// FIXME: relative will be better to be fixed. it is too harsh.
if (it->item->rel)
{
// FIXME: relative will be better to be fixed. it is too harsh.
if (it->item->rel)
{
it->item->rel->item->rel_revs =
eina_list_remove(it->item->rel->item->rel_revs, it);
it->item->rel = NULL;
}
if (it->item->rel_revs)
{
Elm_Gen_Item *tmp;
EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
}
elm_genlist_item_subitems_clear(eo_it);
if (sd->show_item == it)
sd->show_item = NULL;
it->item->rel->item->rel_revs =
eina_list_remove(it->item->rel->item->rel_revs, it);
it->item->rel = NULL;
}
if (it->item->rel_revs)
{
Elm_Gen_Item *tmp;
EINA_LIST_FREE(it->item->rel_revs, tmp) tmp->item->rel = NULL;
}
elm_genlist_item_subitems_clear(eo_it);
if (sd->show_item == it)
sd->show_item = NULL;
_elm_genlist_item_del_not_serious(it);
if (it->item->block)
{
if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
it->item->block->changed = EINA_TRUE;
ecore_job_del(sd->calc_job);
sd->calc_job = ecore_job_add(_calc_job, sd->obj);
}
if (it->parent)
{
it->parent->item->items =
eina_list_remove(it->parent->item->items, eo_it);
it->parent = NULL;
}
return EINA_FALSE;
_elm_genlist_item_del_not_serious(it);
if (it->item->block)
{
if (it->realized) _elm_genlist_item_unrealize(it, EINA_FALSE);
it->item->block->changed = EINA_TRUE;
ecore_job_del(sd->calc_job);
sd->calc_job = ecore_job_add(_calc_job, sd->obj);
}
if (it->parent)
{
it->parent->item->items =
eina_list_remove(it->parent->item->items, eo_it);
it->parent = NULL;
}
_item_del(it);
@ -5974,7 +5884,6 @@ _elm_genlist_item_new(Elm_Genlist_Data *sd,
if (!eo_it) return NULL;
ELM_GENLIST_ITEM_DATA_GET(eo_it, it);
it->generation = sd->generation;
it->itc = itc;
elm_genlist_item_class_ref((Elm_Genlist_Item_Class *)itc);
@ -6359,7 +6268,7 @@ _elm_genlist_item_sorted_insert(Eo *obj, Elm_Genlist_Data *sd, const Elm_Genlist
EOLIAN static void
_elm_genlist_clear(Eo *obj, Elm_Genlist_Data *sd EINA_UNUSED)
{
_internal_elm_genlist_clear(obj, EINA_FALSE);
_internal_elm_genlist_clear(obj);
}
EOLIAN static void
@ -6502,15 +6411,7 @@ _elm_genlist_at_xy_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd, Evas_Coor
EOLIAN static Elm_Object_Item*
_elm_genlist_first_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
{
Elm_Gen_Item *it;
if (!sd->items) return NULL;
it = ELM_GEN_ITEM_FROM_INLIST(sd->items);
while ((it) && (it->generation < sd->generation))
it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
return EO_OBJ(it);
return EO_OBJ(ELM_GEN_ITEM_FROM_INLIST(sd->items));
}
EOLIAN static Elm_Object_Item*
@ -6521,8 +6422,6 @@ _elm_genlist_last_item_get(Eo *obj EINA_UNUSED, Elm_Genlist_Data *sd)
if (!sd->items) return NULL;
it = ELM_GEN_ITEM_FROM_INLIST(sd->items->last);
while ((it) && (it->generation < sd->generation))
it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
return EO_OBJ(it);
}
@ -6533,7 +6432,7 @@ _elm_genlist_item_next_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
while (it)
{
it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->next);
if ((it) && (it->generation == GL_IT(it)->wsd->generation)) break;
if (it) break;
}
if (it) return EO_OBJ(it);
@ -6546,7 +6445,7 @@ _elm_genlist_item_prev_get(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
while (it)
{
it = ELM_GEN_ITEM_FROM_INLIST(EINA_INLIST_GET(it)->prev);
if ((it) && (it->generation == GL_IT(it)->wsd->generation)) break;
if (it) break;
}
if (it) return EO_OBJ(it);
@ -6607,10 +6506,8 @@ _elm_genlist_item_selected_set(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
Eina_Bool selected)
{
ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if ((it->generation < sd->generation) ||
eo_do(EO_OBJ(it), elm_wdg_item_disabled_get())) return;
if (eo_do(EO_OBJ(it), elm_wdg_item_disabled_get())) return;
selected = !!selected;
if (it->selected == selected) return;
@ -6778,7 +6675,6 @@ _elm_genlist_item_coordinates_calc(Elm_Gen_Item *it,
Evas_Coord gith = 0;
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if (it->generation < sd->generation) return EINA_FALSE;
if ((sd->queue) ||
(!((sd->homogeneous) &&
(sd->mode == ELM_LIST_COMPRESS))))
@ -6833,7 +6729,6 @@ _elm_genlist_item_promote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
{
ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
if (it->generation < GL_IT(it)->wsd->generation) return;
Elm_Object_Item *eo_first_item = elm_genlist_first_item_get(WIDGET(it));
ELM_GENLIST_ITEM_DATA_GET(eo_first_item, first_item);
_item_move_before(it, first_item);
@ -6843,7 +6738,6 @@ EOLIAN static void
_elm_genlist_item_demote(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it)
{
ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
if (it->generation < GL_IT(it)->wsd->generation) return;
Elm_Object_Item *eo_last_item = elm_genlist_last_item_get(WIDGET(it));
ELM_GENLIST_ITEM_DATA_GET(eo_last_item, last_item);
_item_move_after(it, last_item);
@ -6897,7 +6791,6 @@ _elm_genlist_item_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if (!it->item->block) return;
if (it->generation < sd->generation) return;
it->item->mincalcd = EINA_FALSE;
it->item->updateme = EINA_TRUE;
it->item->block->updateme = EINA_TRUE;
@ -6913,7 +6806,6 @@ _elm_genlist_item_fields_update(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it,
ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
if (!it->item->block) return;
if (it->generation < GL_IT(it)->wsd->generation) return;
if ((!itf) || (itf & ELM_GENLIST_ITEM_FIELD_TEXT))
{
@ -6968,7 +6860,6 @@ _elm_genlist_item_item_class_update(Eo *eo_it, Elm_Gen_Item *it,
EINA_SAFETY_ON_NULL_RETURN(itc);
it->itc = itc;
if (!it->item->block) return;
if (it->generation < GL_IT(it)->wsd->generation) return;
it->item->nocache_once = EINA_TRUE;
ELM_SAFE_FREE(it->texts, elm_widget_stringlist_free);
@ -6980,7 +6871,6 @@ EOLIAN static const Elm_Genlist_Item_Class *
_elm_genlist_item_item_class_get(Eo *eo_item EINA_UNUSED, Elm_Gen_Item *it)
{
ELM_GENLIST_ITEM_CHECK_OR_RETURN(it, NULL);
if (it->generation < GL_IT(it)->wsd->generation) return NULL;
return it->itc;
}
@ -7383,8 +7273,7 @@ _elm_genlist_item_decorate_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
sd = GL_IT(it)->wsd;
if (!decorate_it_type) return;
if ((it->generation < sd->generation) ||
eo_do(eo_it, elm_wdg_item_disabled_get())) return;
if (eo_do(eo_it, elm_wdg_item_disabled_get())) return;
if (sd->decorate_all_mode) return;
if ((sd->mode_item == it) &&
@ -7702,8 +7591,6 @@ _elm_genlist_item_select_mode_set(Eo *eo_it EINA_UNUSED, Elm_Gen_Item *it,
ELM_GENLIST_ITEM_CHECK_OR_RETURN(it);
ELM_GENLIST_DATA_GET_FROM_ITEM(it, sd);
if (it->generation < sd->generation) return;
if ((mode >= ELM_OBJECT_SELECT_MODE_MAX) || (it->select_mode == mode))
return;

View File

@ -812,8 +812,6 @@ EAPI void elm_widget_tree_dot_dump(const Evas_Object *top, FILE *out
* @see elm_widget_item_internal_del()
* @param item a valid item.
*/
#define elm_widget_item_del(item) \
_elm_widget_item_internal_del(item)
#define elm_widget_item_pre_notify_del(item) \
elm_widget_item_internal_pre_notify_del(item)
#define elm_widget_item_del_cb_set(item, del_cb) \

View File

@ -123,9 +123,6 @@ struct _Elm_Genlist_Data
* default. this can be changed by
* elm_genlist_longpress_timeout_set() */
double longpress_timeout;
/* a generation of genlist. when genlist is cleared, this value
* will be increased and a new generation will start */
int generation;
Eina_Compare_Cb item_compare_cb;
Eina_Compare_Cb item_compare_data_cb;
@ -177,9 +174,6 @@ struct _Elm_Genlist_Data
Eina_Bool on_sub_del : 1;
Eina_Bool highlight : 1;
/* a flag whether genlist is marked as to be cleared or not. if
* this flag is true, genlist clear was already deferred. */
Eina_Bool clear_me : 1;
Eina_Bool h_bounce : 1;
Eina_Bool v_bounce : 1;
Eina_Bool bring_in : 1; /* a flag to