if (!efl_isa((obj), ECORE_POLLER_CLASS)) \
return
-struct _Ecore_Poller_Data
+struct _Ecore_Poller
{
EINA_INLIST;
ECORE_MAGIC;
- Ecore_Poller *obj;
int ibit;
unsigned char delete_me : 1;
Ecore_Task_Cb func;
void *data;
};
-typedef struct _Ecore_Poller_Data Ecore_Poller_Data;
-
static Ecore_Timer *timer = NULL;
static int min_interval = -1;
static int interval_incr = 0;
static double poll_interval = 0.125;
static double poll_cur_interval = 0.0;
static double last_tick = 0.0;
-static Ecore_Poller_Data *pollers[16] =
+static Ecore_Poller *pollers[16] =
{
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
static void _ecore_poller_next_tick_eval(void);
static Eina_Bool _ecore_poller_cb_timer(void *data);
+static void *
+_ecore_poller_cleanup(Ecore_Poller *poller)
+{
+ void *data;
+
+ data = poller->data;
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+
+ free(poller);
+
+ return data;
+}
+
static void
_ecore_poller_next_tick_eval(void)
{
static Eina_Bool
_ecore_poller_cb_timer(void *data EINA_UNUSED)
{
+ Ecore_Poller *poller;
int i;
- Ecore_Poller_Data *poller, *l;
int changes = 0;
at_tick++;
/* FIXME: walk all pollers and remove deleted ones */
for (i = 0; i < 15; i++)
{
- for (l = pollers[i]; l; )
+ Eina_Inlist *l;
+
+ EINA_INLIST_FOREACH_SAFE(pollers[i], l, poller)
{
- poller = l;
- l = (Ecore_Poller_Data *)EINA_INLIST_GET(l)->next;
if (poller->delete_me)
{
- pollers[i] = (Ecore_Poller_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(poller));
-
- efl_parent_set(poller->obj, NULL);
- if (efl_destructed_is(poller->obj))
- efl_manual_free(poller->obj);
- else
- efl_manual_free_set(poller->obj, EINA_FALSE);
+ _ecore_poller_cleanup(poller);
poller_delete_count--;
changes++;
const void *data)
{
Ecore_Poller *poller;
- poller = efl_add(MY_CLASS, _mainloop_singleton, ecore_poller_constructor(efl_added, type, interval, func, data));
- return poller;
-}
-
-EOLIAN static void
-_ecore_poller_constructor(Eo *obj, Ecore_Poller_Data *poller, Ecore_Poller_Type type EINA_UNUSED, int interval, Ecore_Task_Cb func, const void *data)
-{
- poller->obj = obj;
-
int ibit;
- if (EINA_UNLIKELY(!eina_main_loop_is()))
- {
- EINA_MAIN_LOOP_CHECK_RETURN;
- }
+ poller = calloc(1, sizeof (Ecore_Poller));
+ if (!poller) return NULL;
- efl_manual_free_set(obj, EINA_TRUE);
+ 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 class: '%s'", MY_CLASS_NAME);
- return;
+ return NULL;
}
/* interval MUST be a power of 2, so enforce it */
poller->ibit = ibit;
poller->func = func;
poller->data = (void *)data;
- pollers[poller->ibit] = (Ecore_Poller_Data *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
if (poller_walking)
just_added_poller++;
else
_ecore_poller_next_tick_eval();
+
+ return poller;
}
-EOLIAN static Eina_Bool
-_ecore_poller_interval_set(Eo *obj EINA_UNUSED, Ecore_Poller_Data *poller, int interval)
+EAPI Eina_Bool
+ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval)
{
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
-
int ibit;
+ if (!poller) return EINA_FALSE;
+ EINA_MAIN_LOOP_CHECK_RETURN_VAL(EINA_FALSE);
+
/* interval MUST be a power of 2, so enforce it */
if (interval < 1) interval = 1;
ibit = -1;
/* if interval specified is the same as interval set, return true without wasting time */
if (poller->ibit == ibit) return EINA_TRUE;
- pollers[poller->ibit] = (Ecore_Poller_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
poller->ibit = ibit;
- pollers[poller->ibit] = (Ecore_Poller_Data *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
+ pollers[poller->ibit] = (Ecore_Poller *)eina_inlist_prepend(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
if (poller_walking)
just_added_poller++;
else
return EINA_TRUE;
}
-EOLIAN static int
-_ecore_poller_interval_get(Eo *obj EINA_UNUSED, Ecore_Poller_Data *poller)
+EAPI int
+ecore_poller_poller_interval_get(const Ecore_Poller *poller)
{
int ibit, interval = 1;
+ if (!poller) return -1;
EINA_MAIN_LOOP_CHECK_RETURN_VAL(interval);
ibit = poller->ibit;
ibit--;
interval <<= 1;
}
-
+
return interval;
}
EAPI void *
-ecore_poller_del(Ecore_Poller *obj)
+ecore_poller_del(Ecore_Poller *poller)
{
void *data;
- if (!obj) return NULL;
- EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
- Ecore_Poller_Data *poller = efl_data_scope_get(obj, MY_CLASS);
if (!poller) return NULL;
+ EINA_MAIN_LOOP_CHECK_RETURN_VAL(NULL);
/* we are walking the poller list - a bad idea to remove from it while
* walking it, so just flag it as delete_me and come back to it after
* the loop has finished */
return poller->data;
}
/* not in loop so safe - delete immediately */
- data = poller->data;
- pollers[poller->ibit] = (Ecore_Poller_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[poller->ibit]), EINA_INLIST_GET(poller));
-
- efl_parent_set(poller->obj, NULL);
- if (efl_destructed_is(poller->obj))
- efl_manual_free(obj);
- else
- efl_manual_free_set(obj, EINA_FALSE);
+ data = _ecore_poller_cleanup(poller);
_ecore_poller_next_tick_eval();
- return data;
-}
-EOLIAN static void
-_ecore_poller_efl_object_destructor(Eo *obj, Ecore_Poller_Data *pd)
-{
- if (!pd->delete_me)
- {
- pd->delete_me = 1;
- poller_delete_count++;
- }
-
- efl_destructor(efl_super(obj, MY_CLASS));
-}
-
-EOLIAN static Eo *
-_ecore_poller_efl_object_finalize(Eo *obj, Ecore_Poller_Data *pd)
-{
- if (!pd->func)
- {
- return NULL;
- }
-
- return efl_finalize(efl_super(obj, MY_CLASS));
+ return data;
}
void
_ecore_poller_shutdown(void)
{
+ Ecore_Poller *poller;
int i;
- Ecore_Poller_Data *poller;
for (i = 0; i < 15; i++)
{
while ((poller = pollers[i]))
- {
- pollers[i] = (Ecore_Poller_Data *)eina_inlist_remove(EINA_INLIST_GET(pollers[i]), EINA_INLIST_GET(pollers[i]));
- efl_parent_set(poller->obj, NULL);
- if (efl_destructed_is(poller->obj))
- efl_manual_free(poller->obj);
- else
- efl_manual_free_set(poller->obj, EINA_FALSE);
- }
+ _ecore_poller_cleanup(poller);
}
}
-
-#include "ecore_poller.eo.c"
+++ /dev/null
-type @extern Ecore_Task_Cb: __undefined_type; [[Ecore task callback type]]
-
-enum Ecore.Poller_Type
-{
- [[Defines the frequency of ticks for the poller.]]
- legacy: ecore_poller;
- core = 0 [[The core poller interval]]
-}
-
-class Ecore.Poller (Efl.Object)
-{
- [[Ecore poller provides infrastructure for the creation of pollers.
-
- Pollers are, in essence, callbacks that share a single timer per type. Because
- not all pollers need to be called at the same frequency the user may specify
- the frequency in ticks(each expiration of the shared timer is called a tick,
- in ecore poller parlance) for each added poller. Ecore pollers should only be
- used when the poller doesn't have specific requirements on the exact times to
- poll.
-
- This architecture means that the main loop is only woken up once to handle
- all pollers of that type, this will save power as the CPU has more of a
- chance to go into a low power state the longer it is asleep for, so this
- should be used in situations where power usage is a concern.
-
- For now only 1 core poller type is supported: ECORE_POLLER_CORE, the default
- interval for ECORE_POLLER_CORE is 0.125(or 1/8th) second.
- ]]
- methods {
- constructor {
- [[Constructor with parameters for Ecore Poller.]]
- legacy: null;
- params {
- @in type: Ecore.Poller_Type; [[Ecore poller type which defines the frequency of ticks
- for the poller.]]
- @in interval: int; [[The tick interval; must be a power of 2 and <= 32768.]]
- @in func: Ecore_Task_Cb; [[Ecore poller callback function.]]
- @in data: const(void_ptr); [[Private data passed to callback function.]]
- }
- }
- @property interval {
- [[Polling interval rate of the poller.]]
- set {
- legacy: ecore_poller_poller_interval_set;
- return: bool; [[$true on success, $false on failure.]]
- }
- get {
- legacy: ecore_poller_poller_interval_get;
- }
- values {
- interval: int; [[The tick interval; must be a power of 2 and <= 32768.]]
- }
- }
- }
- implements {
- Efl.Object.destructor;
- Efl.Object.finalize;
- }
- constructors {
- .constructor;
- }
-}