ecore: use efl_future_then to simplify the code logic and reduce potential bugs.
authorCedric BAIL <cedric@osg.samsung.com>
Fri, 7 Dec 2018 11:29:22 +0000 (12:29 +0100)
committerWonki Kim <wonki_.kim@samsung.com>
Tue, 18 Dec 2018 04:20:08 +0000 (13:20 +0900)
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

src/lib/ecore/efl_loop.c
src/lib/ecore/efl_model_composite_boolean.c
src/lib/ecore/efl_model_composite_selection.c
src/lib/ecore/efl_thread.c

index 5d24608..33b6398 100644 (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
index 222329e..2db0bc7 100644 (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"
index 25f68c2..ad14b74 100644 (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));
-
-             chain = eina_future_then(chain, _untangle_array, obj, 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_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"
index 3a650a7..f72aa07 100644 (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