ecore: move Ecore_Idler to legacy and rely on Eo event restart capability.
authorCedric BAIL <cedric@osg.samsung.com>
Thu, 21 Apr 2016 18:57:14 +0000 (11:57 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Thu, 21 Apr 2016 19:07:50 +0000 (12:07 -0700)
src/Makefile_Ecore.am
src/lib/ecore/Ecore_Common.h
src/lib/ecore/Ecore_Eo.h
src/lib/ecore/Ecore_Legacy.h
src/lib/ecore/ecore.c
src/lib/ecore/ecore_idler.c
src/lib/ecore/ecore_idler.eo [deleted file]
src/lib/ecore/ecore_main.c
src/lib/ecore/ecore_mainloop.eo
src/lib/ecore/ecore_private.h

index 78a256d..1411945 100644 (file)
@@ -6,7 +6,6 @@ ecore_eolian_files_legacy = \
        lib/ecore/ecore_poller.eo \
        lib/ecore/ecore_job.eo \
        lib/ecore/ecore_exe.eo \
-       lib/ecore/ecore_idler.eo \
        lib/ecore/ecore_idle_enterer.eo \
        lib/ecore/ecore_idle_exiter.eo \
        lib/ecore/ecore_animator.eo
index 47024af..7e61301 100644 (file)
@@ -3033,9 +3033,7 @@ EAPI char *ecore_timer_dump(void);
 /*
  * @since 1.8
  */
-typedef Eo Ecore_Idler; /**< A handle for idlers */
-
-#define _ECORE_IDLER_EO_CLASS_TYPE
+typedef struct _Ecore_Idler Ecore_Idler; /**< A handle for idlers */
 
 /*
  * @since 1.8
index 0000526..1dce5fd 100644 (file)
@@ -47,7 +47,6 @@ extern "C" {
  * @{
  */
 
-#include "ecore_idler.eo.h"
 #include "ecore_idle_exiter.eo.h"
 #include "ecore_idle_enterer.eo.h"
 
index ab9df2d..f0acb5d 100644 (file)
@@ -246,6 +246,7 @@ EAPI void ecore_timer_thaw(Ecore_Timer *timer);
  *
  * @{
  */
+
 /**
  * Add an idler handler.
  * @param  func The function to call when idling.
@@ -321,8 +322,6 @@ EAPI Ecore_Idle_Exiter *ecore_idle_exiter_add(Ecore_Task_Cb func, const void *da
  */
 EAPI void *ecore_idle_exiter_del(Ecore_Idle_Exiter *idle_exiter);
 
-#include "ecore_idler.eo.legacy.h"
-
 /**
  * @}
  */
index 1f31476..48d823f 100644 (file)
@@ -402,7 +402,6 @@ ecore_shutdown(void)
 #endif
      _ecore_idle_enterer_shutdown();
      _ecore_idle_exiter_shutdown();
-     _ecore_idler_shutdown();
      _ecore_timer_shutdown();
      _ecore_event_shutdown();
      _ecore_main_shutdown();
index 54f08cf..a946c66 100644 (file)
 #include "Ecore.h"
 #include "ecore_private.h"
 
-#define MY_CLASS ECORE_IDLER_CLASS
-
-#define MY_CLASS_NAME "Ecore_Idler"
-
-struct _Ecore_Idler_Data
+struct _Ecore_Idler
 {
-   EINA_INLIST;
-   Ecore_Idler  *obj;
    Ecore_Task_Cb func;
    void         *data;
-   int           references;
-   Eina_Bool     delete_me : 1;
 };
 
-typedef struct _Ecore_Idler_Data Ecore_Idler_Data;
-static Ecore_Idler_Data *idlers = NULL;
-static Ecore_Idler_Data *idler_current = NULL;
-static int idlers_delete_me = 0;
-
-static void *
-_ecore_idler_del(Ecore_Idler *idler);
+static void *_ecore_idler_del(Ecore_Idler *idler);
 
-EAPI Ecore_Idler *
-ecore_idler_add(Ecore_Task_Cb func,
-                const void   *data)
+static Eina_Bool
+_ecore_idler_event_del(void *data, const Eo_Event *event EINA_UNUSED)
 {
-   return eo_add(MY_CLASS, _ecore_parent, ecore_idler_constructor(eo_self, func, data));
+   _ecore_idler_del(data);
+
+   return EO_CALLBACK_CONTINUE;
 }
 
-EOLIAN static void
-_ecore_idler_constructor(Eo *obj, Ecore_Idler_Data *ie, Ecore_Task_Cb func, const void *data)
+static Eina_Bool
+_ecore_idler_process(void *data, const Eo_Event *event EINA_UNUSED)
 {
-    if (EINA_UNLIKELY(!eina_main_loop_is()))
-      {
-         EINA_MAIN_LOOP_CHECK_RETURN;
-      }
+   Ecore_Idler *idler = data;
 
-   ie->obj = obj;
-   eo_manual_free_set(obj, EINA_TRUE);
+   if (!_ecore_call_task_cb(idler->func, idler->data))
+     _ecore_idler_del(idler);
 
-   if (!func)
-     {
-        ERR("callback function must be set up for an object of class: '%s'", MY_CLASS_NAME);
-        return;
-     }
-
-   ie->func = func;
-   ie->data = (void *)data;
-   idlers = (Ecore_Idler_Data *)eina_inlist_append(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
+   return EO_CALLBACK_CONTINUE;
 }
 
-EAPI void *
-ecore_idler_del(Ecore_Idler *idler)
-{
-   if (!idler) return NULL;
-   EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
-
-   return _ecore_idler_del(idler);
-}
+EO_CALLBACKS_ARRAY_DEFINE(ecore_idler_callbacks,
+                          { ECORE_MAINLOOP_EVENT_IDLE, _ecore_idler_process },
+                          { EO_BASE_EVENT_DEL, _ecore_idler_event_del });
 
 static void *
-_ecore_idler_del(Ecore_Idler *obj)
+_ecore_idler_del(Ecore_Idler *idler)
 {
-   Ecore_Idler_Data *idler = eo_data_scope_get(obj, MY_CLASS);
+   void *data;
+
    if (!idler) return NULL;
-   EINA_SAFETY_ON_TRUE_RETURN_VAL(idler->delete_me, NULL);
-   idler->delete_me = 1;
-   idlers_delete_me = 1;
-   return idler->data;
-}
 
-EOLIAN static void
-_ecore_idler_eo_base_destructor(Eo *obj, Ecore_Idler_Data *idler)
-{
-   idler->delete_me = 1;
-   idlers_delete_me = 1;
+   eo_event_callback_array_del(_mainloop_singleton, ecore_idler_callbacks(), idler);
 
-   eo_destructor(eo_super(obj, MY_CLASS));
+   data = idler->data;
+   free(idler);
+   return data;
 }
 
-EOLIAN static Eo *
-_ecore_idler_eo_base_finalize(Eo *obj, Ecore_Idler_Data *idler)
+EAPI Ecore_Idler *
+ecore_idler_add(Ecore_Task_Cb func,
+                const void   *data)
 {
-   if (!idler->func)
+   Ecore_Idler *ret;
+
+   if (EINA_UNLIKELY(!eina_main_loop_is()))
      {
+        EINA_MAIN_LOOP_CHECK_RETURN;
+     }
+
+   if (!func)
+     {
+        ERR("callback function must be set up for an object of Ecore_Idler.");
         return NULL;
      }
 
-   return eo_finalize(eo_super(obj, MY_CLASS));
+   ret = malloc(sizeof (Ecore_Idler));
+   if (!ret) return NULL;
+
+   ret->func = func;
+   ret->data = (void*) data;
+
+   eo_event_callback_array_add(_mainloop_singleton, ecore_idler_callbacks(), ret);
+
+   return ret;
 }
 
-void
-_ecore_idler_shutdown(void)
+EAPI void *
+ecore_idler_del(Ecore_Idler *idler)
 {
-   Ecore_Idler_Data *ie;
-   while ((ie = idlers))
-     {
-        idlers = (Ecore_Idler_Data *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(idlers));
+   if (!idler) return NULL;
+   EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
 
-        eo_parent_set(ie->obj, NULL);
-        if (eo_destructed_is(ie->obj))
-          eo_manual_free(ie->obj);
-        else
-          eo_manual_free_set(ie->obj, EINA_FALSE);
-     }
-   idlers_delete_me = 0;
-   idler_current = NULL;
+   return _ecore_idler_del(idler);
 }
 
-int
-_ecore_idler_all_call(void)
+void
+_ecore_idler_all_call(Eo *loop)
 {
-   if (!idler_current)
-     {
-        /* regular main loop, start from head */
-         idler_current = idlers;
-     }
-   else
-     {
-        /* recursive main loop, continue from where we were */
-         idler_current = (Ecore_Idler_Data *)EINA_INLIST_GET(idler_current)->next;
-     }
-
-   while (idler_current)
-     {
-        Ecore_Idler_Data *ie = (Ecore_Idler_Data *)idler_current;
-        if (!ie->delete_me)
-          {
-             ie->references++;
-             eina_evlog("+idler", ie, 0.0, NULL);
-             if (!_ecore_call_task_cb(ie->func, ie->data))
-               {
-                  if (!ie->delete_me) _ecore_idler_del(ie->obj);
-               }
-             eina_evlog("-idler", ie, 0.0, NULL);
-             ie->references--;
-          }
-        if (idler_current) /* may have changed in recursive main loops */
-          idler_current = (Ecore_Idler_Data *)EINA_INLIST_GET(idler_current)->next;
-     }
-   if (idlers_delete_me)
-     {
-        Ecore_Idler_Data *l;
-        int deleted_idlers_in_use = 0;
-        for (l = idlers; l; )
-          {
-             Ecore_Idler_Data *ie = l;
-             l = (Ecore_Idler_Data *)EINA_INLIST_GET(l)->next;
-             if (ie->delete_me)
-               {
-                  if (ie->references)
-                    {
-                       deleted_idlers_in_use++;
-                       continue;
-                    }
-
-                  idlers = (Ecore_Idler_Data *)eina_inlist_remove(EINA_INLIST_GET(idlers), EINA_INLIST_GET(ie));
-
-                  eo_parent_set(ie->obj, NULL);
-                  if (eo_destructed_is(ie->obj))
-                     eo_manual_free(ie->obj);
-                  else
-                     eo_manual_free_set(ie->obj, EINA_FALSE);
-               }
-          }
-        if (!deleted_idlers_in_use)
-          idlers_delete_me = 0;
-     }
-   if (idlers) return 1;
-   return 0;
+   eo_event_callback_call(loop, ECORE_MAINLOOP_EVENT_IDLE, NULL);
 }
 
 int
-_ecore_idler_exist(void)
+_ecore_idler_exist(Eo *loop)
 {
-   if (idlers) return 1;
-   return 0;
-}
+   Ecore_Mainloop_Data *dt = eo_data_scope_get(loop, ECORE_MAINLOOP_CLASS);
 
-#include "ecore_idler.eo.c"
+   return dt->idlers;
+}
diff --git a/src/lib/ecore/ecore_idler.eo b/src/lib/ecore/ecore_idler.eo
deleted file mode 100644 (file)
index bf25d4a..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-import ecore_types;
-
-class Ecore.Idler (Eo.Base)
-{
-   [[Setup callbacks to be called when the program is in idle state.
-
-   Once the mainloop has called all enterer handlers it calls the registered
-   idler callbacks.
-   ]]
-   eo_prefix: ecore_idler;
-   methods {
-      constructor {
-         [[Constructor.]]
-         legacy: null;
-         params {
-            @in func: Ecore_Task_Cb; [[Idler callback function.]]
-            @in data: const(void)*; [[Private data passed to callback functions.]]
-         }
-      }
-   }
-   implements {
-      Eo.Base.destructor;
-      Eo.Base.finalize;
-   }
-   constructors {
-      .constructor;
-   }
-}
index 4a6f52d..dcf3bf0 100644 (file)
@@ -722,7 +722,7 @@ _ecore_main_gsource_prepare(GSource *source EINA_UNUSED,
    if (g_main_loop_is_running(ecore_main_loop))
      {
         /* only set idling state in dispatch */
-         if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist())
+         if (ecore_idling && !_ecore_idler_exist(_mainloop_singleton) && !_ecore_event_exist())
            {
               if (_ecore_timers_exists())
                 {
@@ -791,7 +791,7 @@ _ecore_main_gsource_check(GSource *source EINA_UNUSED)
    in_main_loop++;
 
    /* check if old timers expired */
-   if (ecore_idling && !_ecore_idler_exist() && !_ecore_event_exist())
+   if (ecore_idling && !_ecore_idler_exist(_mainloop_singleton) && !_ecore_event_exist())
      {
         if (timer_fd >= 0)
           {
@@ -846,7 +846,7 @@ _ecore_main_gsource_dispatch(GSource    *source EINA_UNUSED,
 
    events_ready = _ecore_event_exist();
    timers_ready = _ecore_timers_exists() && (0.0 == next_time);
-   idlers_ready = _ecore_idler_exist();
+   idlers_ready = _ecore_idler_exist(_mainloop_singleton);
 
    in_main_loop++;
    DBG("enter idling=%d fds=%d events=%d timers=%d (next=%.2f) idlers=%d",
@@ -866,7 +866,7 @@ _ecore_main_gsource_dispatch(GSource    *source EINA_UNUSED,
 
    if (ecore_idling)
      {
-        _ecore_idler_all_call();
+        _ecore_idler_all_call(_mainloop_singleton);
 
         events_ready = _ecore_event_exist();
 
@@ -2091,9 +2091,9 @@ _ecore_main_loop_uv_prepare(uv_prepare_t* handle EINA_UNUSED)
    double t = -1;
    if(_ecore_main_uv_idling)
      {
-       _ecore_idler_all_call();
+       _ecore_idler_all_call(_mainloop_singleton);
        DBG("called idles");
-       if(_ecore_idler_exist() || _ecore_event_exist())
+       if(_ecore_idler_exist(_mainloop_singleton) || _ecore_event_exist())
          t = 0.0;
      }
 
@@ -2159,8 +2159,10 @@ _ecore_main_loop_spin_core(void)
 {
    /* as we are spinning we need to update loop time per spin */
     _ecore_time_loop_time = ecore_time_get();
-    /* call all idlers, which returns false if no more idelrs exist */
-    if (!_ecore_idler_all_call()) return SPIN_RESTART;
+    /* call all idlers */
+    _ecore_idler_all_call(_mainloop_singleton);
+    /* which returns false if no more idelrs exist */
+    if (!_ecore_idler_exist(_mainloop_singleton)) return SPIN_RESTART;
     /* sneaky - drop through or if checks - the first one to succeed
      * drops through and returns "continue" so further ones dont run */
     if ((_ecore_main_select(0.0) > 0) || (_ecore_event_exist()) ||
@@ -2305,7 +2307,7 @@ start_loop: /*-*************************************************************/
         /* init flags */
         next_time = _ecore_timer_next_get();
         /* no idlers */
-        if (!_ecore_idler_exist())
+        if (!_ecore_idler_exist(_mainloop_singleton))
           {
              /* sleep until timeout or forever (-1.0) waiting for on fds */
              _ecore_main_select(next_time);
@@ -2764,4 +2766,53 @@ _ecore_mainloop_animator_ticked(Eo *obj EINA_UNUSED, Ecore_Mainloop_Data *pd EIN
    return ecore_main_loop_animator_ticked_get();
 }
 
+static Eina_Bool
+_check_event_catcher_add(void *data, const Eo_Event *event)
+{
+   const Eo_Callback_Array_Item *array = event->info;
+   Ecore_Mainloop_Data *pd = data;
+   int i;
+
+   for (i = 0; array[i].desc != NULL; i++)
+     {
+        if (array[i].desc == ECORE_MAINLOOP_EVENT_IDLE)
+          {
+             ++pd->idlers;
+          }
+     }
+
+   return EO_CALLBACK_CONTINUE;
+}
+
+static Eina_Bool
+_check_event_catcher_del(void *data, const Eo_Event *event)
+{
+   const Eo_Callback_Array_Item *array = event->info;
+   Ecore_Mainloop_Data *pd = data;
+   int i;
+
+   for (i = 0; array[i].desc != NULL; i++)
+     {
+        if (array[i].desc == ECORE_MAINLOOP_EVENT_IDLE)
+          {
+             --pd->idlers;
+          }
+     }
+
+   return EO_CALLBACK_CONTINUE;
+}
+
+EO_CALLBACKS_ARRAY_DEFINE(event_catcher_watch,
+                          { EO_BASE_EVENT_CALLBACK_ADD, _check_event_catcher_add },
+                          { EO_BASE_EVENT_CALLBACK_DEL, _check_event_catcher_del });
+
+EOLIAN static Eo_Base *
+_ecore_mainloop_eo_base_constructor(Eo *obj, Ecore_Mainloop_Data *pd)
+{
+   eo_constructor(eo_super(obj, ECORE_MAINLOOP_CLASS));
+   eo_event_callback_array_add(obj, event_catcher_watch(), pd);
+
+   return obj;
+}
+
 #include "ecore_mainloop.eo.c"
index 076cb46..1b04de1 100644 (file)
@@ -52,7 +52,10 @@ class Ecore_Mainloop (Eo.Base)
    events {
       idle,enter @restart; [[Event occurs once the main loop enters the idle state.]]
       idle,exit @restart; [[Event occurs once the main loop exits the idle state.]]
-      idle @restart; /* FIXME: We need to make sure we can get it work. */
+      idle @restart; [[Event occurs once the main loop is idler. Be carefull, this will spin your CPU high if you keep listening on this event.]]
       /* TODO: All of the legacy ecore events. (Ecore.h header) */
    }
+   implements {
+      Eo.Base.constructor;
+   }
 }
index 547a947..0a1b108 100644 (file)
@@ -85,6 +85,12 @@ extern int _ecore_log_dom;
 # define CLAMP(x, min, max) (((x) > (max)) ? (max) : (((x) < (min)) ? (min) : (x)))
 #endif
 
+typedef struct _Ecore_Mainloop_Data Ecore_Mainloop_Data;
+struct _Ecore_Mainloop_Data
+{
+   int idlers;
+};
+
 #define EVAS_FRAME_QUEUING        1 /* for test */
 
 #define READBUFSIZ                65536
@@ -165,9 +171,8 @@ int          _ecore_timers_exists(void);
 
 int          _ecore_timer_expired_call(double when);
 
-void         _ecore_idler_shutdown(void);
-int          _ecore_idler_all_call(void);
-int          _ecore_idler_exist(void);
+void         _ecore_idler_all_call(Eo *loop);
+int          _ecore_idler_exist(Eo *loop);
 
 void         _ecore_idle_enterer_shutdown(void);
 void         _ecore_idle_enterer_call(void);