ecore: rework efl_timer to be a proper eo object emiting signal.

This commit is contained in:
Cedric BAIL 2016-05-04 13:37:39 -07:00
parent 639378bfc7
commit 3ba901f15e
4 changed files with 293 additions and 352 deletions

View File

@ -461,7 +461,6 @@ _ecore_main_uv_poll_cb(uv_poll_t* handle, int status, int events)
_ecore_event_call();
_ecore_main_fd_handlers_cleanup();
_efl_timer_expired_timers_call(_ecore_time_loop_time);
_efl_timer_cleanup();
}
static int
@ -706,7 +705,6 @@ _ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
{
_ecore_time_loop_time = ecore_time_get();
_efl_timer_expired_timers_call(_ecore_time_loop_time);
_efl_timer_cleanup();
_ecore_idle_enterer_call(_mainloop_singleton);
_ecore_throttle();
@ -889,7 +887,6 @@ _ecore_main_gsource_dispatch(GSource *source EINA_UNUSED,
_ecore_main_fd_handlers_cleanup();
_efl_timer_expired_timers_call(_ecore_time_loop_time);
_efl_timer_cleanup();
_ecore_idle_enterer_call(_mainloop_singleton);
_ecore_throttle();
@ -1023,7 +1020,6 @@ _ecore_main_loop_uv_check(uv_check_t* handle EINA_UNUSED)
_ecore_event_call();
_ecore_main_fd_handlers_cleanup();
_efl_timer_expired_timers_call(_ecore_time_loop_time);
_efl_timer_cleanup();
}
while(fd_handlers_to_call);
quit:
@ -2230,7 +2226,6 @@ _ecore_main_loop_iterate_internal(int once_only)
in_main_loop++;
/* expire any timers */
_efl_timer_expired_timers_call(_ecore_time_loop_time);
_efl_timer_cleanup();
/* process signals into events .... */
_ecore_signal_received_process();

View File

@ -158,14 +158,8 @@ EAPI void _ecore_magic_fail(const void *d,
void _ecore_time_init(void);
Ecore_Timer *_efl_timer_loop_add(double in,
Ecore_Task_Cb func,
const void *data);
void *_efl_timer_del(Ecore_Timer *timer);
void _efl_timer_util_delay(Ecore_Timer *timer,
double add);
void _efl_timer_shutdown(void);
void _efl_timer_cleanup(void);
void _efl_timer_enable_new(void);
double _efl_timer_next_get(void);
void _efl_timer_expired_timers_call(double when);

View File

@ -20,33 +20,36 @@
struct _Efl_Timer_Data
{
EINA_INLIST;
Ecore_Timer *obj;
double in;
double at;
double pending;
Ecore_Task_Cb func;
void *data;
Eo *object;
int references;
unsigned char delete_me : 1;
unsigned char just_added : 1;
unsigned char frozen : 1;
double in;
double at;
double pending;
int listening;
unsigned char just_added : 1;
unsigned char frozen : 1;
unsigned char initialized : 1;
};
typedef struct _Efl_Timer_Data Efl_Timer_Data;
static void _efl_timer_set(Ecore_Timer *timer,
double at,
double in,
Ecore_Task_Cb func,
void *data);
static void _efl_timer_util_delay(Efl_Timer_Data *timer,
double add);
static void _efl_timer_util_instanciate(Efl_Timer_Data *timer);
static void _efl_timer_set(Efl_Timer_Data *timer,
double at,
double in);
static Eina_Inlist *timers = NULL;
static Eina_Inlist *suspended = NULL;
static Efl_Timer_Data *timer_current = NULL;
static int timers_added = 0;
static int timers_delete_me = 0;
static Efl_Timer_Data *timers = NULL;
static Efl_Timer_Data *timer_current = NULL;
static Efl_Timer_Data *suspended = NULL;
static double last_check = 0.0;
static double precision = 10.0 / 1000000.0;
@ -70,82 +73,157 @@ ecore_timer_precision_set(double value)
precision = value;
}
static Eina_Bool
_check_timer_event_catcher_add(void *data, const Eo_Event *event)
{
const Eo_Callback_Array_Item *array = event->info;
Efl_Timer_Data *timer = data;
int i;
for (i = 0; array[i].desc != NULL; i++)
{
if (array[i].desc == EFL_TIMER_EVENT_TICK)
{
if (timer->listening++ > 0) return EO_CALLBACK_CONTINUE;
_efl_timer_util_instanciate(timer);
// No need to walk more than once per array as you can not del
// a partial array
return EO_CALLBACK_CONTINUE;
}
}
return EO_CALLBACK_CONTINUE;
}
static Eina_Bool
_check_timer_event_catcher_del(void *data, const Eo_Event *event)
{
const Eo_Callback_Array_Item *array = event->info;
Efl_Timer_Data *timer = data;
int i;
for (i = 0; array[i].desc != NULL; i++)
{
if (array[i].desc == EFL_TIMER_EVENT_TICK)
{
if ((--timer->listening) > 0) return EO_CALLBACK_CONTINUE;
_efl_timer_util_instanciate(timer);
return EO_CALLBACK_CONTINUE;
}
}
return EO_CALLBACK_CONTINUE;
}
EO_CALLBACKS_ARRAY_DEFINE(timer_watch,
{ EO_BASE_EVENT_CALLBACK_ADD, _check_timer_event_catcher_add },
{ EO_BASE_EVENT_CALLBACK_DEL, _check_timer_event_catcher_del });
EOLIAN static Eo *
_efl_timer_eo_base_constructor(Eo *obj, Efl_Timer_Data *timer)
{
eo_constructor(eo_super(obj, MY_CLASS));
eo_event_callback_array_add(obj, timer_watch(), timer);
eo_wref_add(obj, &timer->object);
timer->at = ecore_time_get();
timer->initialized = 0;
return obj;
}
EOLIAN static Eo *
_efl_timer_eo_base_finalize(Eo *obj, Efl_Timer_Data *pd)
{
_efl_timer_util_instanciate(pd);
return eo_finalize(eo_super(obj, MY_CLASS));
}
typedef struct _Ecore_Timer_Legacy Ecore_Timer_Legacy;
struct _Ecore_Timer_Legacy
{
Ecore_Task_Cb func;
const void *data;
};
static Eina_Bool
_ecore_timer_legacy_tick(void *data, const Eo_Event *event)
{
Ecore_Timer_Legacy *legacy = data;
if (!_ecore_call_task_cb(legacy->func, (void*)legacy->data))
{
eo_del(event->obj);
free(legacy);
}
return EO_CALLBACK_CONTINUE;
}
EAPI Ecore_Timer *
ecore_timer_add(double in,
Ecore_Task_Cb func,
const void *data)
{
Ecore_Timer *timer = NULL;
Ecore_Timer_Legacy *legacy;
Eo *timer;
legacy = calloc(1, sizeof (Ecore_Timer_Legacy));
if (!legacy) return NULL;
legacy->func = func;
legacy->data = data;
timer = eo_add(MY_CLASS, ecore_main_loop_get(),
eo_event_callback_add(eo_self, EFL_TIMER_EVENT_TICK, _ecore_timer_legacy_tick, legacy),
eo_key_data_set(eo_self, "_legacy", legacy),
efl_timer_interval_set(eo_self, in));
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
timer = eo_add(MY_CLASS, _ecore_parent, efl_timer_constructor(eo_self, in, func, data));
return timer;
}
static Eina_Bool
_efl_timer_add(Ecore_Timer *obj,
Efl_Timer_Data *timer,
double now,
double in,
Ecore_Task_Cb func,
const void *data)
{
if (EINA_UNLIKELY(!eina_main_loop_is()))
{
EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
}
timer->obj = obj;
eo_manual_free_set(obj, EINA_TRUE);
if (!func)
{
ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME);
return EINA_FALSE;
}
if (in < 0.0) in = 0.0;
_efl_timer_set(obj, now + in, in, func, (void *)data);
return EINA_TRUE;
}
EOLIAN static void
_efl_timer_constructor(Eo *obj, Efl_Timer_Data *timer, double in, Ecore_Task_Cb func, const void *data)
{
double now;
now = ecore_time_get();
_efl_timer_add(obj, timer, now, in, func, data);
}
EOLIAN static void
_efl_timer_loop_constructor(Eo *obj, Efl_Timer_Data *timer, double in, Ecore_Task_Cb func, const void *data)
{
double now;
now = ecore_loop_time_get();
_efl_timer_add(obj, timer, now, in, func, data);
}
EAPI Ecore_Timer *
ecore_timer_loop_add(double in,
Ecore_Task_Cb func,
const void *data)
{
return _efl_timer_loop_add(in, func, data);
Ecore_Timer_Legacy *legacy;
Eo *timer;
legacy = calloc(1, sizeof (Ecore_Timer_Legacy));
if (!legacy) return NULL;
legacy->func = func;
legacy->data = data;
timer = eo_add(MY_CLASS, ecore_main_loop_get(),
eo_event_callback_add(eo_self, EFL_TIMER_EVENT_TICK, _ecore_timer_legacy_tick, legacy),
eo_key_data_set(eo_self, "_legacy", legacy),
efl_timer_loop_reset(eo_self),
efl_timer_interval_set(eo_self, in));
return timer;
}
EAPI void *
ecore_timer_del(Ecore_Timer *timer)
{
Ecore_Timer_Legacy *legacy;
void *data;
if (!timer) return NULL;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
return _efl_timer_del(timer);
legacy = eo_key_data_get(timer, "_legacy");
data = (void*) legacy->data;
free(legacy);
eo_key_del(timer, "_legacy");
eo_del(timer);
return data;
}
EOLIAN static void
@ -155,6 +233,9 @@ _efl_timer_interval_set(Eo *obj EINA_UNUSED, Efl_Timer_Data *timer, double in)
if (in < 0.0) in = 0.0;
timer->in = in;
if (!timer->initialized)
_efl_timer_set(timer, timer->at + in, in);
}
EOLIAN static double
@ -169,26 +250,53 @@ _efl_timer_interval_get(Eo *obj EINA_UNUSED, Efl_Timer_Data *timer)
}
EOLIAN static void
_efl_timer_delay(Eo *obj, Efl_Timer_Data *_pd EINA_UNUSED, double add)
_efl_timer_delay(Eo *obj EINA_UNUSED, Efl_Timer_Data *pd, double add)
{
EINA_MAIN_LOOP_CHECK_RETURN;
_efl_timer_util_delay(obj, add);
_efl_timer_util_delay(pd, add);
}
EOLIAN static void
_efl_timer_reset(Eo *obj, Efl_Timer_Data *timer)
_efl_timer_reset(Eo *obj EINA_UNUSED, Efl_Timer_Data *timer)
{
double now, add;
EINA_MAIN_LOOP_CHECK_RETURN;
now = ecore_time_get();
if (!timer->initialized)
{
timer->at = now;
return;
}
if (timer->frozen)
add = timer->pending;
else
add = timer->at - now;
_efl_timer_util_delay(obj, timer->in - add);
_efl_timer_util_delay(timer, timer->in - add);
}
EOLIAN static void
_efl_timer_loop_reset(Eo *obj EINA_UNUSED, Efl_Timer_Data *timer)
{
double now, add;
EINA_MAIN_LOOP_CHECK_RETURN;
now = ecore_loop_time_get();
if (!timer->initialized)
{
timer->at = now;
return ;
}
if (timer->frozen)
add = timer->pending;
else
add = timer->at - now;
_efl_timer_util_delay(timer, timer->in - add);
}
EOLIAN static double
@ -223,18 +331,19 @@ _efl_timer_eo_base_event_freeze(Eo *obj EINA_UNUSED, Efl_Timer_Data *timer)
EINA_MAIN_LOOP_CHECK_RETURN;
eo_event_freeze(eo_super(obj, MY_CLASS));
/* Timer already frozen */
if (timer->frozen)
return;
timers = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
suspended = (Efl_Timer_Data *)eina_inlist_prepend(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
now = ecore_time_get();
timer->pending = timer->at - now;
timer->at = 0.0;
timer->frozen = 1;
_efl_timer_util_instanciate(timer);
}
EAPI Eina_Bool
@ -268,14 +377,16 @@ _efl_timer_eo_base_event_thaw(Eo *obj, Efl_Timer_Data *timer)
EINA_MAIN_LOOP_CHECK_RETURN;
eo_event_thaw(eo_super(obj, MY_CLASS));
/* Timer not frozen */
if (!timer->frozen)
return ;
suspended = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
suspended = eina_inlist_remove(suspended, EINA_INLIST_GET(timer));
now = ecore_time_get();
_efl_timer_set(obj, timer->pending + now, timer->in, timer->func, timer->data);
_efl_timer_set(timer, timer->pending + now, timer->in);
}
EAPI char *
@ -284,190 +395,85 @@ ecore_timer_dump(void)
return NULL;
}
Ecore_Timer *
_efl_timer_loop_add(double in,
Ecore_Task_Cb func,
const void *data)
static void
_efl_timer_util_instanciate(Efl_Timer_Data *timer)
{
Ecore_Timer *timer = NULL;
timer = eo_add(MY_CLASS, _ecore_parent, efl_timer_loop_constructor(eo_self, in, func, data));
Efl_Timer_Data *t2;
Eina_Inlist *first;
return timer;
// Remove the timer from all possible pending list
first = eina_inlist_first(EINA_INLIST_GET(timer));
if (first == timers)
timers = eina_inlist_remove(timers, EINA_INLIST_GET(timer));
else if (first == suspended)
suspended = eina_inlist_remove(suspended, EINA_INLIST_GET(timer));
// And start putting it back where it belong
if (!timer->listening || timer->frozen || timer->at <= 0.0 || timer->in < 0.0)
{
suspended = eina_inlist_prepend(suspended, EINA_INLIST_GET(timer));
return ;
}
EINA_INLIST_REVERSE_FOREACH(timers, t2)
{
if (timer->at > t2->at)
{
timers = eina_inlist_append_relative(timers,
EINA_INLIST_GET(timer),
EINA_INLIST_GET(t2));
return;
}
}
timers = eina_inlist_prepend(timers, EINA_INLIST_GET(timer));
}
EAPI void
_efl_timer_util_delay(Ecore_Timer *obj,
double add)
static void
_efl_timer_util_delay(Efl_Timer_Data *timer,
double add)
{
Efl_Timer_Data *timer = eo_data_scope_get(obj, MY_CLASS);
if (timer->frozen)
{
timer->pending += add;
}
else
{
timers = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
eo_data_unref(obj, timer);
_efl_timer_set(obj, timer->at + add, timer->in, timer->func, timer->data);
}
}
void *
_efl_timer_del(Ecore_Timer *obj)
{
Efl_Timer_Data *timer = eo_data_scope_get(obj, MY_CLASS);
EINA_SAFETY_ON_NULL_RETURN_VAL(timer, NULL);
if (timer->frozen && !timer->references)
{
void *data = timer->data;
eo_data_unref(obj, timer);
suspended = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
if (timer->delete_me)
timers_delete_me--;
eo_parent_set(obj, NULL);
if (eo_destructed_is(obj))
eo_manual_free(obj);
else
eo_manual_free_set(obj, EINA_FALSE);
return data;
return ;
}
EINA_SAFETY_ON_TRUE_RETURN_VAL(timer->delete_me, NULL);
timer->delete_me = 1;
timers_delete_me++;
return timer->data;
_efl_timer_set(timer, timer->at + add, timer->in);
}
EOLIAN static void
_efl_timer_eo_base_destructor(Eo *obj, Efl_Timer_Data *pd)
{
if (!pd->delete_me)
{
pd->delete_me = 1;
timers_delete_me++;
}
Eina_Inlist *first;
// Check if we are the current timer, if so move along
if (timer_current == pd)
timer_current = (Efl_Timer_Data *)EINA_INLIST_GET(pd)->next;
// Remove the timer from all possible pending list
first = eina_inlist_first(EINA_INLIST_GET(pd));
if (first == timers)
timers = eina_inlist_remove(timers, EINA_INLIST_GET(pd));
else if (first == suspended)
suspended = eina_inlist_remove(suspended, EINA_INLIST_GET(pd));
eo_destructor(eo_super(obj, MY_CLASS));
}
EOLIAN static Eo *
_efl_timer_eo_base_finalize(Eo *obj, Efl_Timer_Data *pd)
{
if (!pd->func)
{
return NULL;
}
return eo_finalize(eo_super(obj, MY_CLASS));
}
void
_efl_timer_shutdown(void)
{
Efl_Timer_Data *timer;
while ((timer = timers))
{
timers = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timers));
EINA_INLIST_FREE(timers, timer)
eo_del(timer->object);
eo_data_unref(timer->obj, timer);
eo_parent_set(timer->obj, NULL);
if (eo_destructed_is(timer->obj))
eo_manual_free(timer->obj);
else
eo_manual_free_set(timer->obj, EINA_FALSE);
}
while ((timer = suspended))
{
suspended = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(suspended));
eo_data_unref(timer->obj, timer);
eo_parent_set(timer->obj, NULL);
if (eo_destructed_is(timer->obj))
eo_manual_free(timer->obj);
else
eo_manual_free_set(timer->obj, EINA_FALSE);
}
EINA_INLIST_FREE(suspended, timer)
eo_del(timer->object);
timer_current = NULL;
}
void
_efl_timer_cleanup(void)
{
Efl_Timer_Data *l;
int in_use = 0, todo = timers_delete_me, done = 0;
if (!timers_delete_me) return;
for (l = timers; l; )
{
Efl_Timer_Data *timer = l;
l = (Efl_Timer_Data *)EINA_INLIST_GET(l)->next;
if (timer->delete_me)
{
if (timer->references)
{
in_use++;
continue;
}
timers = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
eo_data_unref(timer->obj, timer);
eo_parent_set(timer->obj, NULL);
if (eo_destructed_is(timer->obj))
eo_manual_free(timer->obj);
else
eo_manual_free_set(timer->obj, EINA_FALSE);
timers_delete_me--;
done++;
if (timers_delete_me == 0) return;
}
}
for (l = suspended; l; )
{
Efl_Timer_Data *timer = l;
l = (Efl_Timer_Data *)EINA_INLIST_GET(l)->next;
if (timer->delete_me)
{
if (timer->references)
{
in_use++;
continue;
}
suspended = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(suspended), EINA_INLIST_GET(timer));
eo_data_unref(timer->obj, timer);
eo_parent_set(timer->obj, NULL);
if (eo_destructed_is(timer->obj))
eo_manual_free(timer->obj);
else
eo_manual_free_set(timer->obj, EINA_FALSE);
timers_delete_me--;
done++;
if (timers_delete_me == 0) return;
}
}
if ((!in_use) && (timers_delete_me))
{
ERR("%d timers to delete, but they were not found!"
"Stats: todo=%d, done=%d, pending=%d, in_use=%d. "
"reset counter.",
timers_delete_me, todo, done, todo - done, in_use);
timers_delete_me = 0;
}
}
void
_efl_timer_enable_new(void)
{
@ -481,65 +487,49 @@ _efl_timer_enable_new(void)
int
_efl_timers_exists(void)
{
Efl_Timer_Data *timer = timers;
while ((timer) && (timer->delete_me))
timer = (Efl_Timer_Data *)EINA_INLIST_GET(timer)->next;
return !!timer;
return !!timers;
}
static inline Ecore_Timer *
_efl_timer_first_get(void)
{
Ecore_Timer *ret = NULL;
Efl_Timer_Data *timer = timers;
Efl_Timer_Data *timer;
while ((timer) && ((timer->delete_me) || (timer->just_added)))
timer = (Efl_Timer_Data *)EINA_INLIST_GET(timer)->next;
EINA_INLIST_FOREACH(timers, timer)
if (!timer->just_added) return timer->object;
if (timer)
ret = timer->obj;
return ret;
return NULL;
}
static inline Ecore_Timer *
_efl_timer_after_get(Ecore_Timer *obj)
static inline Efl_Timer_Data *
_efl_timer_after_get(Efl_Timer_Data *base)
{
Ecore_Timer *ret = NULL;
Efl_Timer_Data *base = eo_data_scope_get(obj, MY_CLASS);
Efl_Timer_Data *timer = (Efl_Timer_Data *)EINA_INLIST_GET(base)->next;
Efl_Timer_Data *valid_timer = NULL;
Efl_Timer_Data *timer;
Efl_Timer_Data *valid_timer = base;
double maxtime = base->at + precision;
while ((timer) && (timer->at < maxtime))
EINA_INLIST_FOREACH(EINA_INLIST_GET(base)->next, timer)
{
if (!((timer->delete_me) || (timer->just_added)))
if (timer->at >= maxtime) break;
if (!timer->just_added)
valid_timer = timer;
timer = (Efl_Timer_Data *)EINA_INLIST_GET(timer)->next;
}
if (valid_timer)
ret = valid_timer->obj;
return ret;
return valid_timer;
}
double
_efl_timer_next_get(void)
{
Ecore_Timer *object;
Efl_Timer_Data *first;
double now;
double in;
Ecore_Timer *first_obj, *second_obj;
Efl_Timer_Data *first;
first_obj = _efl_timer_first_get();
if (!first_obj) return -1;
object = _efl_timer_first_get();
if (!object) return -1;
second_obj = _efl_timer_after_get(first_obj);
if (second_obj) first_obj = second_obj;
first = eo_data_scope_get(first_obj, MY_CLASS);
first = _efl_timer_after_get(eo_data_scope_get(object, MY_CLASS));
now = ecore_loop_time_get();
in = first->at - now;
@ -548,14 +538,12 @@ _efl_timer_next_get(void)
}
static inline void
_efl_timer_reschedule(Ecore_Timer *obj,
double when)
_efl_timer_reschedule(Efl_Timer_Data *timer,
double when)
{
Efl_Timer_Data *timer = eo_data_scope_get(obj, MY_CLASS);
if ((timer->delete_me) || (timer->frozen)) return;
if (timer->frozen) return;
timers = (Efl_Timer_Data *)eina_inlist_remove(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
eo_data_unref(obj, timer);
timers = eina_inlist_remove(timers, EINA_INLIST_GET(timer));
/* if the timer would have gone off more than 15 seconds ago,
* assume that the system hung and set the timer to go off
@ -567,9 +555,9 @@ _efl_timer_reschedule(Ecore_Timer *obj,
* really slow within the main loop.
*/
if ((timer->at + timer->in) < (when - 15.0))
_efl_timer_set(obj, when + timer->in, timer->in, timer->func, timer->data);
_efl_timer_set(timer, when + timer->in, timer->in);
else
_efl_timer_set(obj, timer->at + timer->in, timer->in, timer->func, timer->data);
_efl_timer_set(timer, timer->at + timer->in, timer->in);
}
void
@ -594,14 +582,15 @@ _efl_timer_expired_call(double when)
if (!timer_current)
{
/* regular main loop, start from head */
timer_current = timers;
timer_current = (Efl_Timer_Data *)timers;
}
else
{
/* recursive main loop, continue from where we were */
Efl_Timer_Data *timer_old = timer_current;
timer_current = (Efl_Timer_Data *)EINA_INLIST_GET(timer_current)->next;
_efl_timer_reschedule(timer_old->obj, when);
_efl_timer_reschedule(timer_old, when);
}
while (timer_current)
@ -614,60 +603,42 @@ _efl_timer_expired_call(double when)
return 0;
}
if ((timer->just_added) || (timer->delete_me))
if (timer->just_added)
{
timer_current = (Efl_Timer_Data *)EINA_INLIST_GET(timer_current)->next;
continue;
}
timer->references++;
eo_ref(timer->object);
eina_evlog("+timer", timer, 0.0, NULL);
if (!_ecore_call_task_cb(timer->func, timer->data))
{
if (!timer->delete_me) _efl_timer_del(timer->obj);
}
eo_event_callback_call(timer->object, EFL_TIMER_EVENT_TICK, NULL);
eina_evlog("-timer", timer, 0.0, NULL);
timer->references--;
if (timer_current) /* may have changed in recursive main loops */
/* may have changed in recursive main loops */
/* this current timer can not die yet as we hold a reference on it */
if (timer_current)
timer_current = (Efl_Timer_Data *)EINA_INLIST_GET(timer_current)->next;
_efl_timer_reschedule(timer->obj, when);
_efl_timer_reschedule(timer, when);
eo_unref(timer->object);
}
return 0;
}
static void
_efl_timer_set(Ecore_Timer *obj,
double at,
double in,
Ecore_Task_Cb func,
void *data)
_efl_timer_set(Efl_Timer_Data *timer,
double at,
double in)
{
Efl_Timer_Data *t2;
Efl_Timer_Data *timer = eo_data_ref(obj, MY_CLASS);
timers_added = 1;
timer->at = at;
timer->in = in;
timer->func = func;
timer->data = data;
timer->just_added = 1;
timer->initialized = 1;
timer->frozen = 0;
timer->pending = 0.0;
if (timers)
{
EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(timers), t2)
{
if (timer->at > t2->at)
{
timers = (Efl_Timer_Data *)eina_inlist_append_relative(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer), EINA_INLIST_GET(t2));
return;
}
}
}
timers = (Efl_Timer_Data *)eina_inlist_prepend(EINA_INLIST_GET(timers), EINA_INLIST_GET(timer));
_efl_timer_util_instanciate(timer);
}
#include "efl_timer.eo.c"

View File

@ -30,30 +30,6 @@ class Efl.Timer (Eo.Base)
return: double;
}
}
loop_constructor {
[[Create a timer to call in a given time from now]]
legacy: null;
params {
@in in: double; [[The time, in seconds, from now when to go off]]
@in func: Ecore_Task_Cb; [[The callback function to call when the
timer goes off]]
@in data: const(void)*; [[A pointer to pass to the callback function
as its data pointer]]
}
}
constructor {
[[Create a timer to call in a given time from when the main loop woke
up from sleep]]
legacy: null;
params {
@in in: double; [[The time, in seconds, from when the main loop
woke up, to go off]]
@in func: Ecore_Task_Cb; [[The callback function to call when the
timer goes off]]
@in data: const(void)*; [[A pointer to pass to the callback
function as its data pointer]]
}
}
reset {
/* FIXME-doc:
* @note This is equivalent to (but faster than)
@ -67,6 +43,11 @@ class Efl.Timer (Eo.Base)
@since 1.2
]]
}
loop_reset {
[[This effectively reset a timer, but based on the time when this iteration of the main loop started.
@since 1.18
]]
}
delay {
[[Add some delay for the next occurrence of a timer.
This doesn't affect the interval of a timer.
@ -76,7 +57,11 @@ class Efl.Timer (Eo.Base)
}
}
}
events {
tick; [[Event triggered when the specified time as passed.]]
}
implements {
Eo.Base.constructor;
Eo.Base.destructor;
Eo.Base.finalize;
Eo.Base.event_freeze;
@ -110,8 +95,4 @@ class Efl.Timer (Eo.Base)
* @see ecore_timer_freeze()
*/
}
constructors {
.constructor;
.loop_constructor;
}
}