forked from enlightenment/efl
Efl_Loop: add job, timeout and idle based on Eina_Future.
Since some clash with old version, then add Eina_FutureXXX to their name, later we'll sed.
This commit is contained in:
parent
8e80d3d2dc
commit
22cee38239
|
@ -44,6 +44,7 @@ GENERIC_ALLOC_FREE(Ecore_Event, ecore_event);
|
|||
//GENERIC_ALLOC_FREE(Ecore_Poller, ecore_poller);
|
||||
GENERIC_ALLOC_FREE(Ecore_Pipe, ecore_pipe);
|
||||
GENERIC_ALLOC_FREE(Ecore_Fd_Handler, ecore_fd_handler);
|
||||
GENERIC_ALLOC_FREE(Efl_Loop_Promise_Simple_Data, efl_loop_promise_simple_data);
|
||||
#ifdef _WIN32
|
||||
GENERIC_ALLOC_FREE(Ecore_Win32_Handler, ecore_win32_handler);
|
||||
#endif
|
||||
|
@ -61,6 +62,7 @@ static Ecore_Mempool *mempool_array[] = {
|
|||
// &ecore_poller_mp,
|
||||
&ecore_pipe_mp,
|
||||
&ecore_fd_handler_mp,
|
||||
&efl_loop_promise_simple_data_mp,
|
||||
#ifdef _WIN32
|
||||
&ecore_win32_handler_mp
|
||||
#endif
|
||||
|
@ -87,6 +89,7 @@ ecore_mempool_init(void)
|
|||
// MP_SIZE_INIT(Ecore_Poller, ecore_poller);
|
||||
MP_SIZE_INIT(Ecore_Pipe, ecore_pipe);
|
||||
MP_SIZE_INIT(Ecore_Fd_Handler, ecore_fd_handler);
|
||||
MP_SIZE_INIT(Efl_Loop_Promise_Simple_Data, efl_loop_promise_simple_data);
|
||||
#ifdef _WIN32
|
||||
MP_SIZE_INIT(Ecore_Win32_Handler, ecore_win32_handler);
|
||||
#endif
|
||||
|
|
|
@ -233,6 +233,15 @@ struct _Ecore_Fd_Handler
|
|||
};
|
||||
GENERIC_ALLOC_SIZE_DECLARE(Ecore_Fd_Handler);
|
||||
|
||||
typedef struct _Efl_Loop_Promise_Simple_Data {
|
||||
union {
|
||||
Ecore_Timer *timer;
|
||||
Ecore_Idler *idler;
|
||||
};
|
||||
Eina_Promise *promise;
|
||||
} Efl_Loop_Promise_Simple_Data;
|
||||
GENERIC_ALLOC_SIZE_DECLARE(Efl_Loop_Promise_Simple_Data);
|
||||
|
||||
#ifdef _WIN32
|
||||
struct _Ecore_Win32_Handler
|
||||
{
|
||||
|
@ -3112,6 +3121,101 @@ EFL_CALLBACKS_ARRAY_DEFINE(timeout,
|
|||
{ EFL_LOOP_TIMER_EVENT_TICK, _efl_loop_timeout_cb },
|
||||
{ EFL_EVENT_DEL, _efl_loop_timeout_force_cancel_cb });
|
||||
|
||||
static Eina_Future *
|
||||
_efl_loop_Eina_FutureXXX_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
|
||||
{
|
||||
// NOTE: Eolian should do efl_future_then() to bind future to object.
|
||||
return efl_future_Eina_FutureXXX_then(obj,
|
||||
eina_future_resolved(efl_loop_future_scheduler_get(obj),
|
||||
EINA_VALUE_EMPTY));
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_loop_Eina_FutureXXX_idle_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
|
||||
{
|
||||
Efl_Loop_Promise_Simple_Data *d = data;
|
||||
ecore_idler_del(d->idler);
|
||||
efl_loop_promise_simple_data_mp_free(d);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_efl_loop_Eina_FutureXXX_idle_done(void *data)
|
||||
{
|
||||
Efl_Loop_Promise_Simple_Data *d = data;
|
||||
eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
|
||||
efl_loop_promise_simple_data_mp_free(d);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Future *
|
||||
_efl_loop_Eina_FutureXXX_idle(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
|
||||
{
|
||||
Efl_Loop_Promise_Simple_Data *d;
|
||||
Eina_Promise *p;
|
||||
|
||||
d = efl_loop_promise_simple_data_calloc(1);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
|
||||
|
||||
d->idler = ecore_idler_add(_efl_loop_Eina_FutureXXX_idle_done, d);
|
||||
EINA_SAFETY_ON_NULL_GOTO(d->idler, idler_error);
|
||||
|
||||
p = eina_promise_new(efl_loop_future_scheduler_get(obj),
|
||||
_efl_loop_Eina_FutureXXX_idle_cancel, d);
|
||||
// d is dead if p is NULL
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
|
||||
d->promise = p;
|
||||
|
||||
// NOTE: Eolian should do efl_future_then() to bind future to object.
|
||||
return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
|
||||
|
||||
idler_error:
|
||||
efl_loop_promise_simple_data_mp_free(d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_loop_Eina_FutureXXX_timeout_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
|
||||
{
|
||||
Efl_Loop_Promise_Simple_Data *d = data;
|
||||
ecore_timer_del(d->timer);
|
||||
efl_loop_promise_simple_data_mp_free(d);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_efl_loop_Eina_FutureXXX_timeout_done(void *data)
|
||||
{
|
||||
Efl_Loop_Promise_Simple_Data *d = data;
|
||||
eina_promise_resolve(d->promise, EINA_VALUE_EMPTY);
|
||||
efl_loop_promise_simple_data_mp_free(d);
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static Eina_Future *
|
||||
_efl_loop_Eina_FutureXXX_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, double time)
|
||||
{
|
||||
Efl_Loop_Promise_Simple_Data *d;
|
||||
Eina_Promise *p;
|
||||
|
||||
d = efl_loop_promise_simple_data_calloc(1);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(d, NULL);
|
||||
|
||||
d->timer = ecore_timer_add(time, _efl_loop_Eina_FutureXXX_timeout_done, d);
|
||||
EINA_SAFETY_ON_NULL_GOTO(d->timer, timer_error);
|
||||
|
||||
p = eina_promise_new(efl_loop_future_scheduler_get(obj),
|
||||
_efl_loop_Eina_FutureXXX_timeout_cancel, d);
|
||||
// d is dead if p is NULL
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(p, NULL);
|
||||
d->promise = p;
|
||||
|
||||
// NOTE: Eolian should do efl_future_then() to bind future to object.
|
||||
return efl_future_Eina_FutureXXX_then(obj, eina_future_new(p));
|
||||
|
||||
timer_error:
|
||||
efl_loop_promise_simple_data_mp_free(d);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* This event will be triggered when the main loop is destroyed and destroy its timers along */
|
||||
static void _efl_loop_internal_cancel(Efl_Internal_Promise *p);
|
||||
|
||||
|
|
|
@ -81,6 +81,8 @@ extern int _ecore_log_dom;
|
|||
|
||||
typedef struct _Ecore_Factorized_Idle Ecore_Factorized_Idle;
|
||||
|
||||
typedef struct _Efl_Loop_Promise_Simple_Data Efl_Loop_Promise_Simple_Data;
|
||||
|
||||
typedef struct _Efl_Loop_Data Efl_Loop_Data;
|
||||
struct _Efl_Loop_Data
|
||||
{
|
||||
|
@ -371,6 +373,7 @@ GENERIC_ALLOC_FREE_HEADER(Ecore_Event, ecore_event);
|
|||
//GENERIC_ALLOC_FREE_HEADER(Ecore_Poller, ecore_poller);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Pipe, ecore_pipe);
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Fd_Handler, ecore_fd_handler);
|
||||
GENERIC_ALLOC_FREE_HEADER(Efl_Loop_Promise_Simple_Data, efl_loop_promise_simple_data);
|
||||
#ifdef _WIN32
|
||||
GENERIC_ALLOC_FREE_HEADER(Ecore_Win32_Handler, ecore_win32_handler);
|
||||
#endif
|
||||
|
|
|
@ -82,6 +82,31 @@ class Efl.Loop (Efl.Object)
|
|||
scheduler: ptr(Eina.Future.Scheduler); [[The scheduler.]]
|
||||
}
|
||||
}
|
||||
Eina_FutureXXX_job {
|
||||
[[A future promise that will be resolved from a clean main
|
||||
loop context as soon as possible.
|
||||
|
||||
This has higher priority, for low priority use
|
||||
@.Eina_FutureXXX_idle
|
||||
]]
|
||||
return: own(ptr(Eina.Future)) /* TODO: future<void> */; [[The future handle.]]
|
||||
}
|
||||
Eina_FutureXXX_idle {
|
||||
[[A future promise that will be resolved from a clean main
|
||||
loop context as soon as the main loop is idle.
|
||||
|
||||
This is a low priority version of @.Eina_FutureXXX_job
|
||||
]]
|
||||
return: own(ptr(Eina.Future)) /* TODO: future<void> */; [[The future handle.]]
|
||||
}
|
||||
Eina_FutureXXX_timeout {
|
||||
[[A future promise that will be resolved from a clean main
|
||||
loop context after $time seconds.]]
|
||||
params {
|
||||
@in time: double; [[The time from now in second that the main loop will wait before triggering it.]]
|
||||
}
|
||||
return: own(ptr(Eina.Future)) /* future<void> */; [[The future handle.]]
|
||||
}
|
||||
job {
|
||||
[[Will execute that promise in the near future.]]
|
||||
params {
|
||||
|
|
|
@ -472,6 +472,67 @@ _race_end_cb(void *data, const Eina_Value v, const Eina_Future *dead EINA_UNUSED
|
|||
return v;
|
||||
}
|
||||
|
||||
static Eina_Value
|
||||
_promise_empty_done(void *data, const Eina_Value value, const Eina_Future *dead_future EINA_UNUSED)
|
||||
{
|
||||
Eina_Bool *pdone = data;
|
||||
|
||||
if (!value.type) *pdone = EINA_TRUE;
|
||||
|
||||
ecore_main_loop_quit();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
START_TEST(efl_test_timeout)
|
||||
{
|
||||
Eina_Future *f;
|
||||
Eina_Bool done = EINA_FALSE;
|
||||
|
||||
fail_if(!ecore_init());
|
||||
f = eina_future_then(efl_loop_Eina_FutureXXX_timeout(ecore_main_loop_get(), 0.0001),
|
||||
_promise_empty_done, &done);
|
||||
fail_if(!f);
|
||||
ecore_main_loop_begin();
|
||||
ecore_shutdown();
|
||||
|
||||
fail_unless(done);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(efl_test_job)
|
||||
{
|
||||
Eina_Future *f;
|
||||
Eina_Bool done = EINA_FALSE;
|
||||
|
||||
fail_if(!ecore_init());
|
||||
f = eina_future_then(efl_loop_Eina_FutureXXX_job(ecore_main_loop_get()),
|
||||
_promise_empty_done, &done);
|
||||
fail_if(!f);
|
||||
ecore_main_loop_begin();
|
||||
ecore_shutdown();
|
||||
|
||||
fail_unless(done);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(efl_test_idle)
|
||||
{
|
||||
Eina_Future *f;
|
||||
Eina_Bool done = EINA_FALSE;
|
||||
|
||||
fail_if(!ecore_init());
|
||||
f = eina_future_then(efl_loop_Eina_FutureXXX_idle(ecore_main_loop_get()),
|
||||
_promise_empty_done, &done);
|
||||
fail_if(!f);
|
||||
ecore_main_loop_begin();
|
||||
ecore_shutdown();
|
||||
|
||||
fail_unless(done);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
||||
START_TEST(efl_test_promise_future_success)
|
||||
{
|
||||
Eina_Future *f;
|
||||
|
@ -1258,6 +1319,9 @@ END_TEST
|
|||
|
||||
void ecore_test_ecore_promise2(TCase *tc)
|
||||
{
|
||||
tcase_add_test(tc, efl_test_timeout);
|
||||
tcase_add_test(tc, efl_test_job);
|
||||
tcase_add_test(tc, efl_test_idle);
|
||||
tcase_add_test(tc, efl_test_promise_future_success);
|
||||
tcase_add_test(tc, efl_test_promise_future_failure);
|
||||
tcase_add_test(tc, efl_test_promise_future_chain_no_error);
|
||||
|
|
Loading…
Reference in New Issue