ecore: use efl_future_then to simplify the code logic and reduce potential bugs.

Summary: Depends on D7380

Reviewers: segfaultxavi, felipealmeida, SanghyeonLee, vitor.sousa, bu5hm4n

Reviewed By: bu5hm4n

Subscribers: barbieri, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T7472

Differential Revision: https://phab.enlightenment.org/D7381
This commit is contained in:
Cedric BAIL 2018-12-07 12:29:22 +01:00 committed by Xavi Artigas
parent 4aeb3e20c9
commit 6b22e6e33d
4 changed files with 104 additions and 99 deletions

View File

@ -365,44 +365,39 @@ _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
}
static void
_efl_loop_arguments_cleanup(Eina_Array *arga)
{
Eina_Stringshare *s;
while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
eina_array_free(arga);
}
static Eina_Value
_efl_loop_arguments_send(void *data, const Eina_Value v,
const Eina_Future *dead EINA_UNUSED)
_efl_loop_arguments_send(Eo *o EINA_UNUSED, void *data, const Eina_Value v)
{
static Eina_Bool initialization = EINA_TRUE;
Efl_Loop_Arguments arge;
Eina_Array *arga = data;
if (v.type == EINA_VALUE_TYPE_ERROR) goto on_error;
arge.argv = arga;
arge.initialization = initialization;
initialization = EINA_FALSE;
efl_event_callback_call(efl_main_loop_get(),
EFL_LOOP_EVENT_ARGUMENTS, &arge);
on_error:
_efl_loop_arguments_cleanup(arga);
return v;
}
static void
_efl_loop_arguments_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
{
Eina_Array *arga = data;
Eina_Stringshare *s;
while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
eina_array_free(arga);
}
// It doesn't make sense to send those argument to any other mainloop
// As it also doesn't make sense to allow anyone to override this, so
// should be internal for sure, not even protected.
EAPI void
ecore_loop_arguments_send(int argc, const char **argv)
{
Eina_Future *job;
Eina_Array *arga;
int i = 0;
@ -414,18 +409,18 @@ ecore_loop_arguments_send(int argc, const char **argv)
efl_task_arg_append(efl_main_loop_get(), argv[i]);
}
job = eina_future_then(efl_loop_job(efl_main_loop_get()),
_efl_loop_arguments_send, arga, NULL);
efl_future_then(efl_main_loop_get(), job);
efl_future_then(efl_main_loop_get(), efl_loop_job(efl_main_loop_get()),
.success = _efl_loop_arguments_send,
.free = _efl_loop_arguments_cleanup,
.data = arga);
}
static Eina_Future *
_efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
{
Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
// NOTE: Eolian should do efl_future_then() to bind future to object.
return efl_future_then
(obj, eina_future_resolved(sched, EINA_VALUE_EMPTY));
return efl_future_then(obj,
eina_future_resolved(efl_loop_future_scheduler_get(obj), EINA_VALUE_EMPTY));
}
EOLIAN static void

View File

@ -181,16 +181,13 @@ struct _Efl_Model_Slice_Request
};
static Eina_Value
_efl_model_composite_boolean_then(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
_efl_model_composite_boolean_then(Eo *o EINA_UNUSED, void *data, const Eina_Value v)
{
Efl_Model_Slice_Request *req = data;
unsigned int i, len;
Eina_Value r = EINA_VALUE_EMPTY;
Eo *target = NULL;
if (eina_value_type_get(&v) != EINA_VALUE_TYPE_ARRAY)
goto on_error;
eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);
EINA_VALUE_ARRAY_FOREACH(&v, len, i, target)
@ -206,11 +203,16 @@ _efl_model_composite_boolean_then(void *data, const Eina_Value v, const Eina_Fut
eina_value_array_append(&r, composite);
}
on_error:
return r;
}
static void
_efl_model_composite_boolean_clean(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
{
Efl_Model_Slice_Request *req = data;
efl_unref(req->parent);
free(req);
return r;
}
static void
@ -295,8 +297,10 @@ _efl_model_composite_boolean_efl_model_children_slice_get(Eo *obj,
req->parent = efl_ref(obj);
req->start = start;
return efl_future_then
(obj, eina_future_then(f, _efl_model_composite_boolean_then, req, NULL));
return efl_future_then(obj, f, .success_type = EINA_VALUE_TYPE_ARRAY,
.success = _efl_model_composite_boolean_then,
.free = _efl_model_composite_boolean_clean,
.data = req);
}
#include "efl_model_composite_boolean.eo.c"

View File

@ -40,10 +40,9 @@ _efl_model_composite_selection_efl_object_constructor(Eo *obj,
}
static Eina_Value
_commit_change(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
_commit_change(Eo *child, void *data EINA_UNUSED, const Eina_Value v)
{
Efl_Model_Composite_Selection_Data *pd;
Efl_Model *child = data;
Eina_Value *vc = NULL;
Eina_Value *selected = NULL;
Eina_Bool selflag = EINA_FALSE;
@ -85,16 +84,12 @@ _commit_change(void *data, const Eina_Value v, const Eina_Future *dead_future EI
return v;
}
static Eina_Value
_clear_child(void *data,
const Eina_Value v,
static void
_clear_child(Eo *child,
void *data EINA_UNUSED,
const Eina_Future *dead_future EINA_UNUSED)
{
Efl_Model *child = data;
efl_del(child);
return v;
}
static Efl_Model *
@ -131,8 +126,7 @@ _check_child_change(Efl_Model *child, Eina_Bool value)
else
{
r = efl_model_property_set(child, "selected", eina_value_bool_new(!!value));
r = eina_future_then(r, _commit_change, child, NULL);
r = eina_future_then(r, _clear_child, child, NULL);
r = efl_future_then(child, r, .success = _commit_change, .free = _clear_child);
}
return r;
@ -151,9 +145,9 @@ _unselect_child(Efl_Model *child)
}
static Eina_Value
_select_slice_then(void *data EINA_UNUSED,
const Eina_Value v,
const Eina_Future *dead_future EINA_UNUSED)
_select_slice_then(Eo *obj EINA_UNUSED,
void *data EINA_UNUSED,
const Eina_Value v)
{
Efl_Model *child = NULL;
Eina_Future *r;
@ -169,9 +163,9 @@ _select_slice_then(void *data EINA_UNUSED,
}
static Eina_Value
_unselect_slice_then(void *data EINA_UNUSED,
const Eina_Value v,
const Eina_Future *dead_future EINA_UNUSED)
_unselect_slice_then(Eo *obj EINA_UNUSED,
void *data EINA_UNUSED,
const Eina_Value v)
{
Efl_Model *child = NULL;
Eina_Future *r;
@ -233,12 +227,13 @@ _efl_model_composite_selection_efl_model_property_set(Eo *obj,
if (!success)
return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
return efl_future_then
(obj, eina_future_then(efl_model_children_slice_get(obj, l, 1),
_select_slice_then, obj, NULL));
return efl_future_then(obj, efl_model_children_slice_get(obj, l, 1),
.success = _select_slice_then,
.success_type = EINA_VALUE_TYPE_ARRAY);
}
return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS), property, value);
return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS),
property, value);
}
static Eina_Value *
@ -277,29 +272,10 @@ _regenerate_error(void *data,
}
static Eina_Value
_untangle_array(void *data,
const Eina_Value v,
const Eina_Future *dead_future EINA_UNUSED)
_untangle_array(void *data EINA_UNUSED,
const Eina_Value v)
{
Efl_Model *child = data;
Eina_Value va = EINA_VALUE_EMPTY;
Eina_Future *f;
if (v.type == EINA_VALUE_TYPE_ERROR)
{
// We need to roll back the change, which means in this
// case to unselect this child as this is the only case
// where we could end up here.
Eina_Error *error = calloc(1, sizeof (Eina_Error));
f = efl_model_property_set(efl_super(child, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
"selected", eina_value_bool_new(EINA_FALSE));
// Once this is done, we need to repropagate the error
eina_value_error_get(&v, error);
f = eina_future_then(f, _regenerate_error, error, NULL);
return eina_future_as_value(f);
}
// Only return the commit change, not the result of the unselect
eina_value_array_get(&v, 0, &va);
@ -317,6 +293,26 @@ _efl_model_composite_selection_children_efl_model_properties_get(const Eo *obj,
return props;
}
static Eina_Value
_untangle_error(void *data, Eina_Error err)
{
Efl_Model *child = data;
Eina_Future *f;
// We need to roll back the change, which means in this
// case to unselect this child as this is the only case
// where we could end up here.
Eina_Error *error = calloc(1, sizeof (Eina_Error));
f = efl_model_property_set(efl_super(child, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
"selected", eina_value_bool_new(EINA_FALSE));
// Once this is done, we need to repropagate the error
*error = err;
f = eina_future_then(f, _regenerate_error, error, NULL);
return eina_future_as_value(f);
}
static Eina_Future *
_efl_model_composite_selection_children_efl_model_property_set(Eo *obj,
Efl_Model_Composite_Selection_Children_Data *pd EINA_UNUSED,
@ -381,6 +377,7 @@ _efl_model_composite_selection_children_efl_model_property_set(Eo *obj,
}
else
{
Eo *parent;
Eina_Value *vs;
unsigned long selected = 0;
Eina_Bool success;
@ -403,18 +400,23 @@ _efl_model_composite_selection_children_efl_model_property_set(Eo *obj,
return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);
// There was, need to unselect the previous one along setting the new value
parent = efl_parent_get(obj);
chain = eina_future_all(chain,
eina_future_then(efl_model_children_slice_get(efl_parent_get(obj), selected, 1),
_unselect_slice_then, NULL, NULL));
efl_future_then(parent, efl_model_children_slice_get(parent, selected, 1),
.success = _unselect_slice_then,
.success_type = EINA_VALUE_TYPE_ARRAY));
chain = eina_future_then(chain, _untangle_array, obj, NULL);
chain = eina_future_then_easy(chain,
.success_type = EINA_VALUE_TYPE_ARRAY,
.success = _untangle_array,
.data = obj,
.error = _untangle_error);
}
}
commit_change:
chain = eina_future_then(chain, _commit_change, obj, NULL);
return efl_future_then(obj, chain);
return efl_future_then(obj, chain,
.success = _commit_change);
}
typedef struct _Selection_Children_Request Selection_Children_Request;
@ -426,18 +428,15 @@ struct _Selection_Children_Request
};
static Eina_Value
_slice_get(void *data,
const Eina_Value v,
const Eina_Future *dead_future EINA_UNUSED)
_slice_get(Eo *o EINA_UNUSED,
void *data,
const Eina_Value v)
{
Selection_Children_Request *req = data;
unsigned int length, it;
Eo *composited = NULL;
Eina_Value r = EINA_VALUE_EMPTY;
if (v.type == EINA_VALUE_TYPE_ERROR)
goto error;
eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);
EINA_VALUE_ARRAY_FOREACH(&v, length, it, composited)
@ -450,11 +449,18 @@ _slice_get(void *data,
eina_value_array_append(&r, compositing);
}
error:
return r;
}
static void
_slice_clean(Eo *o EINA_UNUSED,
void *data,
const Eina_Future *dead_future EINA_UNUSED)
{
Selection_Children_Request *req = data;
efl_unref(req->parent);
free(req);
return r;
}
static Eina_Future *
@ -473,9 +479,12 @@ _efl_model_composite_selection_efl_model_children_slice_get(Eo *obj,
// NOTE: We do jump on purpose EFL_MODEL_COMPOSITE_BOOLEAN_CLASS here
f = efl_model_children_slice_get(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS),
start, count);
f = eina_future_then(f, _slice_get, req, NULL);
return efl_future_then(obj, f);
return efl_future_then(obj, f,
.success_type = EINA_VALUE_TYPE_ARRAY,
.success = _slice_get,
.free = _slice_clean,
.data = req);
}
#include "efl_model_composite_selection.eo.c"

View File

@ -145,19 +145,16 @@ _cb_thread_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED)
}
static Eina_Value
_efl_loop_arguments_send(void *data, const Eina_Value v,
const Eina_Future *dead EINA_UNUSED)
_efl_loop_arguments_send(Eo *obj, void *data EINA_UNUSED, const Eina_Value v)
{
Efl_Loop_Arguments arge;
Eo *obj = data;
Eina_Array *arga;
Eina_Stringshare *s;
unsigned int argc = efl_task_arg_count_get(obj);
unsigned int i;
arga = eina_array_new(argc);
if (v.type == EINA_VALUE_TYPE_ERROR) goto on_error;
for (i = 0; i < argc; i++)
{
@ -169,9 +166,10 @@ _efl_loop_arguments_send(void *data, const Eina_Value v,
arge.initialization = EINA_TRUE;
efl_event_callback_call(obj,
EFL_LOOP_EVENT_ARGUMENTS, &arge);
on_error:
while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
eina_array_free(arga);
return v;
}
@ -285,8 +283,8 @@ _efl_thread_main(void *data, Eina_Thread t)
}
for (i = 0; i < thdat->args.argc; i++)
efl_task_arg_append(obj, thdat->args.argv[i]);
job = eina_future_then(efl_loop_job(obj), _efl_loop_arguments_send, obj);
efl_future_then(obj, job);
efl_future_then(obj, efl_loop_job(obj),
.success = _efl_loop_arguments_send);
for (i = 0; i < thdat->args.argc; i++)
eina_stringshare_del(thdat->args.argv[i]);
@ -780,8 +778,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
pd->thdat = thdat;
pd->run = EINA_TRUE;
pd->promise = efl_loop_promise_new(obj, _run_cancel_cb, obj);
Eina_Future *f = eina_future_new(pd->promise);
return efl_future_then(obj, f);
return efl_future_then(obj, eina_future_new(pd->promise));
}
EOLIAN static void