diff options
author | Cedric BAIL <cedric@osg.samsung.com> | 2018-11-21 16:44:17 -0800 |
---|---|---|
committer | Cedric BAIL <cedric@osg.samsung.com> | 2018-11-23 11:39:35 -0800 |
commit | 38865a688a89f69630f4cf3f49fa23a9f82260e4 (patch) | |
tree | 7837767f3d2c53ba5e600ab7c7e3067ab2bf5370 | |
parent | 88553eb9e8185c5505db21ec00b6f7083b5a9859 (diff) | |
download | efl-38865a688a89f69630f4cf3f49fa23a9f82260e4.tar.gz |
ecore,efl: add Efl.Model.property_get helper which will suceed once when a property finally has a value.
Reviewed-by: Vitor Sousa da Silva <vitorsousa@expertisesolutions.com.br>
Differential Revision: https://phab.enlightenment.org/D7323
-rw-r--r-- | src/Makefile_Ecore.am | 2 | ||||
-rw-r--r-- | src/lib/ecore/Ecore_Eo.h | 1 | ||||
-rw-r--r-- | src/lib/ecore/efl_model_loop.c | 109 | ||||
-rw-r--r-- | src/lib/ecore/efl_model_loop.eo | 7 | ||||
-rw-r--r-- | src/lib/ecore/meson.build | 2 | ||||
-rw-r--r-- | src/lib/efl/interfaces/efl_model.eo | 17 |
6 files changed, 138 insertions, 0 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am index 661ccbf721..5b7c664687 100644 --- a/src/Makefile_Ecore.am +++ b/src/Makefile_Ecore.am @@ -41,6 +41,7 @@ ecore_eolian_files_public = \ lib/ecore/efl_bounce_interpolator.eo \ lib/ecore/efl_spring_interpolator.eo \ lib/ecore/efl_cubic_bezier_interpolator.eo \ + lib/ecore/efl_model_loop.eo \ lib/ecore/efl_model_item.eo \ lib/ecore/efl_model_container.eo \ lib/ecore/efl_model_container_item.eo \ @@ -117,6 +118,7 @@ lib/ecore/efl_io_stderr.c \ lib/ecore/efl_io_file.c \ lib/ecore/efl_io_copier.c \ lib/ecore/efl_io_buffered_stream.c \ +lib/ecore/efl_model_loop.c \ lib/ecore/efl_model_item.c \ lib/ecore/efl_model_container.c \ lib/ecore/efl_model_container_item.c \ diff --git a/src/lib/ecore/Ecore_Eo.h b/src/lib/ecore/Ecore_Eo.h index cbdf6ce26b..f73080ae4c 100644 --- a/src/lib/ecore/Ecore_Eo.h +++ b/src/lib/ecore/Ecore_Eo.h @@ -123,6 +123,7 @@ EAPI Eo *efl_app_get(void); * @{ */ +#include "efl_model_loop.eo.h" #include "efl_model_item.eo.h" #include "efl_model_container.eo.h" #include "efl_model_container_item.eo.h" diff --git a/src/lib/ecore/efl_model_loop.c b/src/lib/ecore/efl_model_loop.c new file mode 100644 index 0000000000..a64b3f851b --- /dev/null +++ b/src/lib/ecore/efl_model_loop.c @@ -0,0 +1,109 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "Eina.h" +#include "Efl.h" +#include <Ecore.h> +#include "Eo.h" + +#include "efl_model_loop.eo.h" + +typedef struct _Efl_Model_Loop_Watcher_Data Efl_Model_Loop_Watcher_Data; + +struct _Efl_Model_Loop_Watcher_Data +{ + const char *property; + Eina_Promise *p; + Eo *obj; +}; + +static void _propagate_future(void *data, const Efl_Event *event); + +static void +_efl_model_loop_wathcer_free(Efl_Model_Loop_Watcher_Data *wd) +{ + efl_event_callback_del(wd->obj, EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _propagate_future, wd); + eina_stringshare_del(wd->property); + free(wd); +} + +static void +_propagate_future(void *data, const Efl_Event *event) +{ + Efl_Model_Property_Event *ev = event->info; + const char *property; + unsigned int i; + Eina_Array_Iterator it; + Efl_Model_Loop_Watcher_Data *wd = data; + + EINA_ARRAY_ITER_NEXT(ev->changed_properties, i, property, it) + if (property == wd->property || !strcmp(property, wd->property)) + { + Eina_Value *v = efl_model_property_get(wd->obj, wd->property); + + if (eina_value_type_get(v) == EINA_VALUE_TYPE_ERROR) + { + Eina_Error err = 0; + + eina_value_get(v, &err); + + if (err == EAGAIN) + return ; // Not ready yet + + eina_promise_reject(wd->p, err); + } + else + { + eina_promise_resolve(wd->p, eina_value_reference_copy(v)); + } + + eina_value_free(v); + _efl_model_loop_wathcer_free(wd); + break ; + } +} + +static void +_event_cancel(void *data, const Eina_Promise *dead_ptr) +{ + _efl_model_loop_wathcer_free(data); +} + +static Eina_Future * +_efl_model_loop_efl_model_property_ready_get(Eo *obj, void *pd EINA_UNUSED, const char *property) +{ + Eina_Value *value = efl_model_property_get(obj, property); + Eina_Future *f; + + if (eina_value_type_get(value) == EINA_VALUE_TYPE_ERROR) + { + Eina_Error err = 0; + + eina_value_get(value, &err); + eina_value_free(value); + + if (err == EAGAIN) + { + Efl_Model_Loop_Watcher_Data *wd = calloc(1, sizeof (Efl_Model_Loop_Watcher_Data)); + + wd->obj = obj; + wd->property = eina_stringshare_add(property); + wd->p = eina_promise_new(efl_loop_future_scheduler_get(obj), + _event_cancel, wd); + + efl_event_callback_add(obj, + EFL_MODEL_EVENT_PROPERTIES_CHANGED, + _propagate_future, wd); + } + + return eina_future_rejected(efl_loop_future_scheduler_get(obj), err); + } + f = eina_future_resolved(efl_loop_future_scheduler_get(obj), + eina_value_reference_copy(value)); + eina_value_free(value); + return efl_future_Eina_FutureXXX_then(obj, f); +} + +#include "efl_model_loop.eo.c" diff --git a/src/lib/ecore/efl_model_loop.eo b/src/lib/ecore/efl_model_loop.eo new file mode 100644 index 0000000000..be4fe6a452 --- /dev/null +++ b/src/lib/ecore/efl_model_loop.eo @@ -0,0 +1,7 @@ +class Efl.Model_Loop (Efl.Loop_Consumer, Efl.Model) +{ + data: null; + implements { + Efl.Model.property_ready_get; + } +}
\ No newline at end of file diff --git a/src/lib/ecore/meson.build b/src/lib/ecore/meson.build index 60525ee659..96ad59b98c 100644 --- a/src/lib/ecore/meson.build +++ b/src/lib/ecore/meson.build @@ -67,6 +67,7 @@ pub_eo_files = [ 'efl_cubic_bezier_interpolator.eo', 'efl_loop_message_future_handler.eo', 'efl_loop_message_future.eo', + 'efl_model_loop.eo', 'efl_model_item.eo', 'efl_model_container.eo', 'efl_model_container_item.eo', @@ -144,6 +145,7 @@ ecore_src = [ 'efl_io_file.c', 'efl_io_copier.c', 'efl_io_buffered_stream.c', + 'efl_model_loop.c', 'efl_model_item.c', 'efl_model_container.c', 'efl_model_container_item.c', diff --git a/src/lib/efl/interfaces/efl_model.eo b/src/lib/efl/interfaces/efl_model.eo index ffe8bf4430..ff06a321a8 100644 --- a/src/lib/efl/interfaces/efl_model.eo +++ b/src/lib/efl/interfaces/efl_model.eo @@ -76,6 +76,23 @@ interface Efl.Model () value: any_value_ptr; [[Property value]] } } + property_ready_get { + [[Get a future value when it change to something that is not error:EAGAIN + + property_get can return an error with code EAGAIN when it doesn't have any + meaningful value. To make life easier, this future will resolve when + the error:EAGAIN disapear. Either into a failed future in case the error + code change to something else or a success with the value of property whenever + the property finally change. + + + The future can also be canceled if the model itself get destroyed. + ]] + params { + @in property: string; + } + return: future<any_value_ptr>; + } children_slice_get { [[Get children slice OR full range. |