forked from enlightenment/efl
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
This commit is contained in:
parent
88553eb9e8
commit
38865a688a
|
@ -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 \
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
|
@ -0,0 +1,7 @@
|
|||
class Efl.Model_Loop (Efl.Loop_Consumer, Efl.Model)
|
||||
{
|
||||
data: null;
|
||||
implements {
|
||||
Efl.Model.property_ready_get;
|
||||
}
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
Loading…
Reference in New Issue