ecore: simplify usage of poller by giving 3 class of event on the main loop object.
authorCedric BAIL <cedric@osg.samsung.com>
Fri, 2 Jun 2017 23:27:02 +0000 (16:27 -0700)
committerCedric BAIL <cedric@osg.samsung.com>
Fri, 2 Jun 2017 23:28:28 +0000 (16:28 -0700)
The internal logic should be improved further in the future to synchronize itself
with loop wake up whenever possible (Especially true for the high frequency poller).

src/lib/ecore/ecore_main.c
src/lib/ecore/ecore_private.h
src/lib/ecore/efl_loop.eo

index 6cf9e81..868fc4c 100644 (file)
@@ -2869,6 +2869,14 @@ _efl_loop_efl_object_provider_find(Eo *obj, Efl_Loop_Data *pd, const Efl_Object
 }
 
 static void
+_poll_trigger(void *data, const Efl_Event *event)
+{
+   Eo *parent = efl_parent_get(event->object);
+
+   efl_event_callback_call(parent, data, NULL);
+}
+
+static void
 _check_event_catcher_add(void *data, const Efl_Event *event)
 {
    const Efl_Callback_Array_Item *array = event->info;
@@ -2881,6 +2889,38 @@ _check_event_catcher_add(void *data, const Efl_Event *event)
           {
              ++pd->idlers;
           }
+        else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
+          {
+             if (!pd->poll_high)
+               {
+                  // Would be better to have it in sync with normal wake up
+                  // of the main loop for better energy efficiency, I guess.
+                  pd->poll_high = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
+                                          efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_HIGH),
+                                          efl_loop_timer_interval_set(efl_added, 1/60));
+               }
+             ++pd->pollers.high;
+          }
+        else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
+          {
+             if (!pd->poll_medium)
+               {
+                  pd->poll_medium = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
+                                            efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_MEDIUM),
+                                            efl_loop_timer_interval_set(efl_added, 6));
+               }
+             ++pd->pollers.medium;
+          }
+        else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
+          {
+             if (!pd->poll_low)
+               {
+                  pd->poll_low = efl_add(EFL_LOOP_TIMER_CLASS, event->object,
+                                         efl_event_callback_add(efl_added, EFL_LOOP_TIMER_EVENT_TICK, _poll_trigger, EFL_LOOP_EVENT_POLL_LOW),
+                                         efl_loop_timer_interval_set(efl_added, 66));
+               }
+             ++pd->pollers.low;
+          }
      }
 }
 
@@ -2897,6 +2937,33 @@ _check_event_catcher_del(void *data, const Efl_Event *event)
           {
              --pd->idlers;
           }
+        else if (array[i].desc == EFL_LOOP_EVENT_POLL_HIGH)
+          {
+             --pd->pollers.high;
+             if (!pd->pollers.high)
+               {
+                  ecore_timer_del(pd->poll_high);
+                  pd->poll_high = NULL;
+               }
+          }
+        else if (array[i].desc == EFL_LOOP_EVENT_POLL_MEDIUM)
+          {
+             --pd->pollers.medium;
+             if (!pd->pollers.medium)
+               {
+                  ecore_timer_del(pd->poll_medium);
+                  pd->poll_medium = NULL;
+               }
+          }
+        else if (array[i].desc == EFL_LOOP_EVENT_POLL_LOW)
+          {
+             --pd->pollers.low;
+             if (!pd->pollers.low)
+               {
+                  ecore_timer_del(pd->poll_low);
+                  pd->poll_low = NULL;
+               }
+          }
      }
 }
 
@@ -2920,9 +2987,13 @@ _efl_loop_efl_object_constructor(Eo *obj, Efl_Loop_Data *pd)
 EOLIAN static void
 _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
 {
-   efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
-
    eina_hash_free(pd->providers);
+
+   efl_del(pd->poll_low);
+   efl_del(pd->poll_medium);
+   efl_del(pd->poll_high);
+
+   efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
 }
 
 typedef struct _Efl_Internal_Promise Efl_Internal_Promise;
index 54daa5e..de6838b 100644 (file)
@@ -86,7 +86,17 @@ struct _Efl_Loop_Data
 {
    Eina_Hash *providers;
 
+   Ecore_Timer *poll_high;
+   Ecore_Timer *poll_medium;
+   Ecore_Timer *poll_low;
+
    int idlers;
+
+   struct {
+      int high;
+      int medium;
+      int low;
+   } pollers;
 };
 
 #define EVAS_FRAME_QUEUING        1 /* for test */
index 0f00720..aa8ae08 100644 (file)
@@ -106,6 +106,9 @@ class Efl.Loop (Efl.Object)
       idle,exit @restart; [[Event occurs once the main loop exits the idle state.]]
       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.]]
       arguments: Efl.Loop.Arguments; [[Event happens when args are provided to the loop by args_add().]]
+      poll,high; [[Event occurs multiple time per second. The exact tick is undefined and could be adjusted system wide.]]
+      poll,medium; [[Event occurs multiple time per minute. The exact tick is undefined and could be adjusted system wide.]]
+      poll,low; [[Event occurs multiple time every 15 minutes. The exact tick is undefined and could be adjusted system wide.]]
    }
    implements {
       Efl.Object.constructor;