forked from enlightenment/efl
ecore: add a timeout promise.
This commit is contained in:
parent
3ba901f15e
commit
8d50990a27
|
@ -2800,54 +2800,121 @@ _efl_loop_eo_base_constructor(Eo *obj, Efl_Loop_Data *pd)
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _Efl_Internal_Job Efl_Internal_Job;
|
typedef struct _Efl_Internal_Promise Efl_Internal_Promise;
|
||||||
struct _Efl_Internal_Job
|
struct _Efl_Internal_Promise
|
||||||
{
|
{
|
||||||
Ecore_Job *job;
|
union {
|
||||||
|
Ecore_Job *job;
|
||||||
|
Efl_Timer *timer;
|
||||||
|
} u;
|
||||||
Eina_Promise_Owner *promise;
|
Eina_Promise_Owner *promise;
|
||||||
|
|
||||||
const void *data;
|
const void *data;
|
||||||
|
|
||||||
|
Eina_Bool job_is : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_loop_job_cb(void *data)
|
_efl_loop_job_cb(void *data)
|
||||||
{
|
{
|
||||||
Efl_Internal_Job *j = data;
|
Efl_Internal_Promise *j = data;
|
||||||
|
|
||||||
eina_promise_owner_value_set(j->promise, &j->data, NULL);
|
eina_promise_owner_value_set(j->promise, &j->data, NULL);
|
||||||
|
|
||||||
free(j);
|
free(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Eina_Bool
|
||||||
|
_efl_loop_timeout_cb(void *data, const Eo_Event *event EINA_UNUSED)
|
||||||
|
{
|
||||||
|
Efl_Internal_Promise *t = data;
|
||||||
|
|
||||||
|
eina_promise_owner_value_set(t->promise, &t->data, NULL);
|
||||||
|
|
||||||
|
eo_del(t->u.timer);
|
||||||
|
|
||||||
|
return EO_CALLBACK_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_loop_internal_cancel(Efl_Internal_Promise *p)
|
||||||
|
{
|
||||||
|
eina_promise_owner_error_set(p->promise, _promise_canceled);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_loop_job_cancel(void* data, Eina_Promise_Owner* promise EINA_UNUSED)
|
_efl_loop_job_cancel(void* data, Eina_Promise_Owner* promise EINA_UNUSED)
|
||||||
{
|
{
|
||||||
Efl_Internal_Job *j = data;
|
Efl_Internal_Promise *j = data;
|
||||||
|
|
||||||
eina_promise_owner_error_set(j->promise, _promise_canceled);
|
if (j->job_is)
|
||||||
ecore_job_del(j->job);
|
ecore_job_del(j->u.job);
|
||||||
free(j);
|
else
|
||||||
|
eo_del(j->u.timer);
|
||||||
|
_efl_loop_internal_cancel(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Efl_Internal_Promise *
|
||||||
|
_efl_internal_promise_new(Eina_Promise_Owner* promise, const void *data)
|
||||||
|
{
|
||||||
|
Efl_Internal_Promise *p;
|
||||||
|
|
||||||
|
p = calloc(1, sizeof (Efl_Internal_Promise));
|
||||||
|
if (!p) return NULL;
|
||||||
|
|
||||||
|
eina_promise_owner_default_cancel_cb_add(promise, &_efl_loop_job_cancel, p, NULL);
|
||||||
|
p->promise = promise;
|
||||||
|
p->data = data;
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_efl_loop_job(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED, Eina_Promise_Owner *promise, const void *data)
|
_efl_loop_job(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd EINA_UNUSED, Eina_Promise_Owner *promise, const void *data)
|
||||||
{
|
{
|
||||||
Efl_Internal_Job *j;
|
Efl_Internal_Promise *j;
|
||||||
|
|
||||||
j = calloc(1, sizeof (Efl_Internal_Job));
|
j = _efl_internal_promise_new(promise, data);
|
||||||
if (!j) goto on_error;
|
if (!j) return ;
|
||||||
|
|
||||||
eina_promise_owner_default_cancel_cb_add(promise, &_efl_loop_job_cancel, j, NULL);
|
j->job_is = EINA_TRUE;
|
||||||
j->promise = promise;
|
j->u.job = ecore_job_add(_efl_loop_job_cb, j);
|
||||||
j->data = data;
|
|
||||||
j->job = ecore_job_add(_efl_loop_job_cb, j);
|
|
||||||
if (!j->job) goto on_error;
|
|
||||||
|
|
||||||
return ;
|
if (j->u.job) return ;
|
||||||
|
|
||||||
on_error:
|
_efl_loop_internal_cancel(j);
|
||||||
eina_promise_owner_error_set(promise, _promise_canceled);
|
}
|
||||||
free(j);
|
|
||||||
|
/* This event will be triggered when the main loop is destroyed and destroy its timers along */
|
||||||
|
static Eina_Bool
|
||||||
|
_efl_loop_timeout_force_cancel_cb(void *data, const Eo_Event *event EINA_UNUSED)
|
||||||
|
{
|
||||||
|
_efl_loop_internal_cancel(data);
|
||||||
|
|
||||||
|
return EO_CALLBACK_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EO_CALLBACKS_ARRAY_DEFINE(timeout,
|
||||||
|
{ EFL_TIMER_EVENT_TICK, _efl_loop_timeout_cb },
|
||||||
|
{ EO_BASE_EVENT_DEL, _efl_loop_timeout_force_cancel_cb });
|
||||||
|
|
||||||
|
static void
|
||||||
|
_efl_loop_timeout(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED, Eina_Promise_Owner *promise, double time, const void *data)
|
||||||
|
{
|
||||||
|
Efl_Internal_Promise *t;
|
||||||
|
|
||||||
|
t = _efl_internal_promise_new(promise, data);
|
||||||
|
if (!t) return ;
|
||||||
|
|
||||||
|
t->job_is = EINA_FALSE;
|
||||||
|
t->u.timer = eo_add(EFL_TIMER_CLASS, obj,
|
||||||
|
efl_timer_interval_set(eo_self, time),
|
||||||
|
eo_event_callback_array_add(eo_self, timeout(), t));
|
||||||
|
|
||||||
|
if (t->u.timer) return ;
|
||||||
|
|
||||||
|
_efl_loop_internal_cancel(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "efl_loop.eo.c"
|
#include "efl_loop.eo.c"
|
||||||
|
|
|
@ -34,8 +34,16 @@ class Efl.Loop (Eo.Base)
|
||||||
job {
|
job {
|
||||||
[[Will execute that promise in the near future.]]
|
[[Will execute that promise in the near future.]]
|
||||||
params {
|
params {
|
||||||
@inout promise: promise<void*>*;
|
@inout promise: promise<void*>*; [[The promise that will be triggered.]]
|
||||||
@in data: const(void)* @optional;
|
@in data: const(void)* @optional; [[The data to be given when the promise is done.]]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timeout {
|
||||||
|
[[Will trigger this promise when the specified timeout occur.]]
|
||||||
|
params {
|
||||||
|
@inout promise: promise<void*>*; [[The promise that will be triggered.]]
|
||||||
|
@in time: double; [[The time from now in second that the main loop will wait before triggering it.]]
|
||||||
|
@in data: const(void)* @optional; [[The data to be given when the promise is done.]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue