forked from enlightenment/efl
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:
parent
4aeb3e20c9
commit
6b22e6e33d
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue