cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=3ba901f15e06b10b488f4fc7f4c41adb806ba0a8

commit 3ba901f15e06b10b488f4fc7f4c41adb806ba0a8
Author: Cedric BAIL <ced...@osg.samsung.com>
Date:   Wed May 4 13:37:39 2016 -0700

    ecore: rework efl_timer to be a proper eo object emiting signal.
---
 src/lib/ecore/ecore_main.c    |   5 -
 src/lib/ecore/ecore_private.h |   6 -
 src/lib/ecore/ecore_timer.c   | 561 ++++++++++++++++++++----------------------
 src/lib/ecore/efl_timer.eo    |  37 +--
 4 files changed, 275 insertions(+), 334 deletions(-)

diff --git a/src/lib/ecore/ecore_main.c b/src/lib/ecore/ecore_main.c
index 394fd17..71ce95b 100644
--- a/src/lib/ecore/ecore_main.c
+++ b/src/lib/ecore/ecore_main.c
@@ -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();
diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h
index bba1361..c95a4d9 100644
--- a/src/lib/ecore/ecore_private.h
+++ b/src/lib/ecore/ecore_private.h
@@ -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);
diff --git a/src/lib/ecore/ecore_timer.c b/src/lib/ecore/ecore_timer.c
index 284f16a..54cf773 100644
--- a/src/lib/ecore/ecore_timer.c
+++ b/src/lib/ecore/ecore_timer.c
@@ -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;
-
-
-   int                 references;
-   unsigned char       delete_me : 1;
-   unsigned char       just_added : 1;
-   unsigned char       frozen : 1;
+
+   Eo            *object;
+
+   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 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 int timers_added = 0;
+
 static double last_check = 0.0;
 static double precision = 10.0 / 1000000.0;
 
@@ -70,65 +73,116 @@ ecore_timer_precision_set(double value)
    precision = value;
 }
 
-EAPI Ecore_Timer *
-ecore_timer_add(double        in,
-                Ecore_Task_Cb func,
-                const void   *data)
+static Eina_Bool
+_check_timer_event_catcher_add(void *data, const Eo_Event *event)
 {
-   Ecore_Timer *timer = NULL;
+   const Eo_Callback_Array_Item *array = event->info;
+   Efl_Timer_Data *timer = data;
+   int i;
 
-   EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
-   timer = eo_add(MY_CLASS, _ecore_parent, efl_timer_constructor(eo_self, in, 
func, data));
-   return timer;
+   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
-_efl_timer_add(Ecore_Timer *obj,
-                 Efl_Timer_Data *timer,
-                 double now,
-                 double in,
-                 Ecore_Task_Cb func,
-                 const void *data)
+_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;
 
-   if (EINA_UNLIKELY(!eina_main_loop_is()))
+   for (i = 0; array[i].desc != NULL; i++)
      {
-        EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
+        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;
+          }
      }
 
-   timer->obj = obj;
-   eo_manual_free_set(obj, EINA_TRUE);
+   return EO_CALLBACK_CONTINUE;
+}
 
-   if (!func)
-     {
-        ERR("callback function must be set up for an object of class: '%s'", 
MY_CLASS_NAME);
-        return EINA_FALSE;
-     }
+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 });
 
-   if (in < 0.0) in = 0.0;
+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;
 
-   _efl_timer_set(obj, now + in, in, func, (void *)data);
-   return EINA_TRUE;
+   return obj;
 }
 
-EOLIAN static void
-_efl_timer_constructor(Eo *obj, Efl_Timer_Data *timer, double in, 
Ecore_Task_Cb func, const void *data)
+
+EOLIAN static Eo *
+_efl_timer_eo_base_finalize(Eo *obj, Efl_Timer_Data *pd)
 {
-   double now;
+   _efl_timer_util_instanciate(pd);
 
-   now = ecore_time_get();
+   return eo_finalize(eo_super(obj, MY_CLASS));
+}
 
-   _efl_timer_add(obj, timer, now, in, func, data);
+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;
 }
 
-EOLIAN static void
-_efl_timer_loop_constructor(Eo *obj, Efl_Timer_Data *timer, double in, 
Ecore_Task_Cb func, const void *data)
+EAPI Ecore_Timer *
+ecore_timer_add(double        in,
+                Ecore_Task_Cb func,
+                const void   *data)
 {
-   double now;
+   Ecore_Timer_Legacy *legacy;
+   Eo *timer;
 
-   now = ecore_loop_time_get();
+   legacy = calloc(1, sizeof (Ecore_Timer_Legacy));
+   if (!legacy) return NULL;
 
-   _efl_timer_add(obj, timer, now, in, func, data);
+   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));
+
+   return timer;
 }
 
 EAPI Ecore_Timer *
@@ -136,16 +190,40 @@ 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(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(obj, timer->in - add);
+   _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,88 +395,69 @@ 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));
-
-   return timer;
-}
+   Efl_Timer_Data *t2;
+   Eina_Inlist *first;
 
-EAPI void
-_efl_timer_util_delay(Ecore_Timer *obj,
-                   double       add)
-{
-   Efl_Timer_Data *timer = eo_data_scope_get(obj, MY_CLASS);
+   // 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));
 
-   if (timer->frozen)
+   // And start putting it back where it belong
+   if (!timer->listening || timer->frozen || timer->at <= 0.0 || timer->in < 
0.0)
      {
-        timer->pending += add;
+        suspended = eina_inlist_prepend(suspended, EINA_INLIST_GET(timer));
+        return ;
      }
-   else
+
+   EINA_INLIST_REVERSE_FOREACH(timers, t2)
      {
-        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);
+        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));
 }
 
-void *
-_efl_timer_del(Ecore_Timer *obj)
+static void
+_efl_timer_util_delay(Efl_Timer_Data *timer,
+                      double add)
 {
-   Efl_Timer_Data *timer = eo_data_scope_get(obj, MY_CLASS);
-
-   EINA_SAFETY_ON_NULL_RETURN_VAL(timer, NULL);
-
-   if (timer->frozen && !timer->references)
+   if (timer->frozen)
      {
-        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;
+        timer->pending += add;
+        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;
 
-   eo_destructor(eo_super(obj, MY_CLASS));
-}
+   // 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;
 
-EOLIAN static Eo *
-_efl_timer_eo_base_finalize(Eo *obj, Efl_Timer_Data *pd)
-{
-   if (!pd->func)
-   {
-      return NULL;
-   }
+   // 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));
 
-   return eo_finalize(eo_super(obj, MY_CLASS));
+   eo_destructor(eo_super(obj, MY_CLASS));
 }
 
 void
@@ -373,102 +465,16 @@ _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));
-
-        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(timers, timer)
+     eo_del(timer->object);
 
-   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)
 {
    Efl_Timer_Data *timer;
@@ -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"
diff --git a/src/lib/ecore/efl_timer.eo b/src/lib/ecore/efl_timer.eo
index 9a3b54f..6e114ed 100644
--- a/src/lib/ecore/efl_timer.eo
+++ b/src/lib/ecore/efl_timer.eo
@@ -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;
-   }
 }

-- 


Reply via email to