forked from enlightenment/efl
ecore: enforce proper lifecycle for all Efl.Composite_Model children.
Summary: This make sure that the object returned by children_slice_get are properly destroyed when the refcount drop to only the parent holding a reference on it. This make it clear that the user of the api can rely on efl_ref/efl_unref to actually manage its use of the returned object. Reviewers: felipealmeida, segfaultxavi, SanghyeonLee, zmike, bu5hm4n Reviewed By: segfaultxavi, zmike Subscribers: #reviewers, #committers Tags: #efl Maniphest Tasks: T7528 Differential Revision: https://phab.enlightenment.org/D7864
This commit is contained in:
parent
7943a69b0d
commit
790fc1b8c5
|
@ -193,11 +193,14 @@ _efl_composite_model_then(Eo *o EINA_UNUSED, void *data, const Eina_Value v)
|
|||
|
||||
// First set the Model to be used as a source so that we the newly object
|
||||
// can know if it needs to retain the information regarding its index.
|
||||
composite = efl_add(req->self, req->parent,
|
||||
efl_ui_view_model_set(efl_added, target),
|
||||
efl_composite_model_index_set(efl_added, req->start + i));
|
||||
composite = efl_add_ref(req->self, req->parent,
|
||||
efl_ui_view_model_set(efl_added, target),
|
||||
efl_composite_model_index_set(efl_added, req->start + i),
|
||||
efl_loop_model_volatile_make(efl_added));
|
||||
|
||||
eina_value_array_append(&r, composite);
|
||||
// Dropping this scope reference
|
||||
efl_unref(composite);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
|
|
@ -88,7 +88,7 @@ _clear_child(Eo *child,
|
|||
void *data EINA_UNUSED,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
efl_del(child);
|
||||
efl_unref(child);
|
||||
}
|
||||
|
||||
static Efl_Model *
|
||||
|
@ -125,7 +125,9 @@ _check_child_change(Efl_Model *child, Eina_Bool value)
|
|||
else
|
||||
{
|
||||
r = efl_model_property_set(child, "selected", eina_value_bool_new(!!value));
|
||||
r = efl_future_then(child, r, .success = _commit_change, .free = _clear_child);
|
||||
r = efl_future_then(efl_ref(child), r,
|
||||
.success = _commit_change,
|
||||
.free = _clear_child);
|
||||
}
|
||||
|
||||
return r;
|
||||
|
@ -229,6 +231,15 @@ _untangle_error(void *data, Eina_Error err)
|
|||
return eina_future_as_value(f);
|
||||
}
|
||||
|
||||
static void
|
||||
_untangle_free(void *data,
|
||||
const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Eo *obj = data;
|
||||
|
||||
efl_unref(obj);
|
||||
}
|
||||
|
||||
static Eina_Iterator *
|
||||
_efl_select_model_efl_model_properties_get(const Eo *obj,
|
||||
Efl_Select_Model_Data *pd EINA_UNUSED)
|
||||
|
@ -271,9 +282,10 @@ _efl_select_model_efl_model_property_set(Eo *obj,
|
|||
if (!eina_value_ulong_convert(value, &l))
|
||||
return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
|
||||
|
||||
return efl_future_then(obj, efl_model_children_slice_get(obj, l, 1),
|
||||
return efl_future_then(efl_ref(obj), efl_model_children_slice_get(obj, l, 1),
|
||||
.success = _select_slice_then,
|
||||
.success_type = EINA_VALUE_TYPE_ARRAY);
|
||||
.success_type = EINA_VALUE_TYPE_ARRAY,
|
||||
.free = _clear_child);
|
||||
}
|
||||
|
||||
if (pd->parent && !strcmp("self.selected", property))
|
||||
|
@ -326,18 +338,23 @@ _efl_select_model_efl_model_property_set(Eo *obj,
|
|||
// There was, need to unselect the previous one along setting the new value
|
||||
parent = efl_parent_get(obj);
|
||||
chain = eina_future_all(chain,
|
||||
efl_future_then(parent, efl_model_children_slice_get(parent, selected, 1),
|
||||
efl_future_then(efl_ref(parent),
|
||||
efl_model_children_slice_get(parent, selected, 1),
|
||||
.success = _unselect_slice_then,
|
||||
.success_type = EINA_VALUE_TYPE_ARRAY));
|
||||
.success_type = EINA_VALUE_TYPE_ARRAY,
|
||||
.free = _clear_child));
|
||||
chain = eina_future_then_easy(chain,
|
||||
.success_type = EINA_VALUE_TYPE_ARRAY,
|
||||
.success = _untangle_array,
|
||||
.data = obj,
|
||||
.error = _untangle_error);
|
||||
.data = efl_ref(obj),
|
||||
.error = _untangle_error,
|
||||
.free = _untangle_free);
|
||||
}
|
||||
}
|
||||
|
||||
return efl_future_then(obj, chain, .success = _commit_change);
|
||||
return efl_future_then(efl_ref(obj), chain,
|
||||
.success = _commit_change,
|
||||
.free = _clear_child);
|
||||
}
|
||||
|
||||
return efl_model_property_set(efl_super(obj, EFL_SELECT_MODEL_CLASS),
|
||||
|
|
Loading…
Reference in New Issue