elementary: fix initialization order and memory leak when setting model on Efl.Ui.CollectionView.

This patch use volatile model to make sure that a model is properly cleaned once it is not
used anymore.

Reviewed-by: Marcel Hollerbach <mail@marcel-hollerbach.de>
Differential Revision: https://phab.enlightenment.org/D10625
This commit is contained in:
Cedric BAIL 2019-11-07 16:17:06 -08:00 committed by Marcel Hollerbach
parent f71a109e70
commit 6cec0df499
1 changed files with 26 additions and 27 deletions

View File

@ -1874,7 +1874,9 @@ static void
_efl_ui_collection_view_model_changed(void *data, const Efl_Event *event) _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
{ {
Efl_Model_Changed_Event *ev = event->info; Efl_Model_Changed_Event *ev = event->info;
#ifdef VIEWPORT_ENABLE
Eina_List *requests = NULL; Eina_List *requests = NULL;
#endif
MY_DATA_GET(data, pd); MY_DATA_GET(data, pd);
Eina_Iterator *it; Eina_Iterator *it;
const char *property; const char *property;
@ -1883,22 +1885,21 @@ _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
Efl_Model *mselect = NULL; Efl_Model *mselect = NULL;
Eina_Bool selection = EINA_FALSE, sizing = EINA_FALSE; Eina_Bool selection = EINA_FALSE, sizing = EINA_FALSE;
// Cleanup all object, pending request and refetch everything // Cleanup all object, pending request to prepare refetching everything
_all_cleanup(data, pd); _all_cleanup(data, pd);
if (pd->model) efl_event_callback_array_del(pd->model, model_cbs(), data); if (pd->model) efl_event_callback_array_del(pd->model, model_cbs(), data);
efl_replace(&pd->model, NULL); if (pd->multi_selectable_async_model)
{
efl_event_callback_forwarder_del(pd->multi_selectable_async_model,
EFL_UI_SELECTABLE_EVENT_SELECTION_CHANGED,
data);
efl_composite_detach(data, pd->multi_selectable_async_model);
}
if (!ev->current) if (!ev->current)
{ {
if (pd->multi_selectable_async_model) efl_replace(&pd->model, NULL);
{ efl_replace(&pd->multi_selectable_async_model, NULL);
efl_event_callback_forwarder_del(pd->multi_selectable_async_model,
EFL_UI_SELECTABLE_EVENT_SELECTION_CHANGED,
data);
efl_composite_detach(data, pd->multi_selectable_async_model);
efl_replace(&pd->multi_selectable_async_model, NULL);
}
return ; return ;
} }
@ -1937,15 +1938,9 @@ _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
// Build and connect the selection model properly // Build and connect the selection model properly
if (!mselect) if (!mselect)
{ {
mselect = model = efl_add(EFL_UI_SELECT_MODEL_CLASS, data, mselect = model = efl_add_ref(EFL_UI_SELECT_MODEL_CLASS, data,
efl_ui_view_model_set(efl_added, model)); efl_ui_view_model_set(efl_added, model),
} efl_loop_model_volatile_make(efl_added));
if (pd->multi_selectable_async_model)
{
efl_event_callback_forwarder_del(pd->multi_selectable_async_model,
EFL_UI_SELECTABLE_EVENT_SELECTION_CHANGED,
data);
efl_composite_detach(data, pd->multi_selectable_async_model);
} }
efl_replace(&pd->multi_selectable_async_model, mselect); efl_replace(&pd->multi_selectable_async_model, mselect);
efl_composite_attach(data, pd->multi_selectable_async_model); efl_composite_attach(data, pd->multi_selectable_async_model);
@ -1953,8 +1948,15 @@ _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
EFL_UI_SELECTABLE_EVENT_SELECTION_CHANGED, EFL_UI_SELECTABLE_EVENT_SELECTION_CHANGED,
data); data);
if (!sizing) model = efl_add(EFL_UI_HOMOGENEOUS_MODEL_CLASS, data, if (!sizing) model = efl_add_ref(EFL_UI_HOMOGENEOUS_MODEL_CLASS, data,
efl_ui_view_model_set(efl_added, model)); efl_ui_view_model_set(efl_added, model),
efl_loop_model_volatile_make(efl_added));
efl_replace(&pd->model, model);
efl_event_callback_array_add(pd->model, model_cbs(), data);
if (mselect) efl_unref(mselect);
if (!sizing) efl_unref(model);
count = efl_model_children_count_get(model); count = efl_model_children_count_get(model);
@ -1976,13 +1978,9 @@ _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
requests = eina_list_append(requests, request); requests = eina_list_append(requests, request);
} }
#endif
requests = _batch_request_flush(requests, data, pd); requests = _batch_request_flush(requests, data, pd);
#endif
pd->model = model;
efl_event_callback_array_add(pd->model, model_cbs(), data);
efl_ui_position_manager_entity_item_size_changed(pd->manager, 0, count - 1);
switch(efl_ui_position_manager_entity_version(pd->manager, 1)) switch(efl_ui_position_manager_entity_version(pd->manager, 1))
{ {
case 1: case 1:
@ -1992,6 +1990,7 @@ _efl_ui_collection_view_model_changed(void *data, const Efl_Event *event)
count); count);
break; break;
} }
efl_ui_position_manager_entity_item_size_changed(pd->manager, 0, count - 1);
} }
static void static void