Python-EFL: implemented ecore.Poller, with docs and unittest.
This commit is contained in:
parent
fcac9e23ad
commit
1c255024d3
2
TODO
2
TODO
|
@ -19,14 +19,12 @@ BUGS
|
|||
TODO
|
||||
====
|
||||
|
||||
* ecore.Poller
|
||||
* alert on signal and subprocess module usage (was in python-ecore/ecore/__init__.py)
|
||||
* evas.SmartObject
|
||||
* edje: complete the unit tests
|
||||
* elm.Web need a test
|
||||
* elm.PhotoCam need a test
|
||||
* include python-ethumb
|
||||
* include python-e_dbus (or make edbus2 ??)
|
||||
* Review the internal functions and name them consistently
|
||||
* Add more documentation for the use of callbacks
|
||||
* Document our use of exceptions
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
:class:`efl.ecore.Poller` Class
|
||||
==============================
|
||||
|
||||
.. autoclass:: efl.ecore.Poller
|
|
@ -31,6 +31,18 @@ limited to that use, it can, for example, also be used to create a progress
|
|||
bar. see :py:class:`Animator<efl.ecore.Animator>`
|
||||
|
||||
|
||||
Pollers
|
||||
-------
|
||||
|
||||
Ecore :py:class:`Poller<efl.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.
|
||||
|
||||
|
||||
Idlers
|
||||
------
|
||||
|
||||
|
@ -82,6 +94,7 @@ Reference
|
|||
|
||||
class-timer
|
||||
class-animator
|
||||
class-poller
|
||||
class-idler
|
||||
class-idleenterer
|
||||
class-idleexiter
|
||||
|
|
|
@ -242,6 +242,9 @@ ECORE_FILE_EVENT_DELETED_SELF = enums.ECORE_FILE_EVENT_DELETED_SELF
|
|||
ECORE_FILE_EVENT_MODIFIED = enums.ECORE_FILE_EVENT_MODIFIED
|
||||
ECORE_FILE_EVENT_CLOSED = enums.ECORE_FILE_EVENT_CLOSED
|
||||
|
||||
# Ecore_Poller_Type:
|
||||
ECORE_POLLER_CORE = enums.ECORE_POLLER_CORE
|
||||
|
||||
|
||||
cdef Eina_Bool _ecore_task_cb(void *data) with gil:
|
||||
cdef Eo obj = <Eo>data
|
||||
|
@ -323,6 +326,7 @@ def loop_time_get():
|
|||
|
||||
include "efl.ecore_animator.pxi"
|
||||
include "efl.ecore_timer.pxi"
|
||||
include "efl.ecore_poller.pxi"
|
||||
include "efl.ecore_idler.pxi"
|
||||
include "efl.ecore_fd_handler.pxi"
|
||||
include "efl.ecore_events.pxi"
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
# Copyright (C) 2007-2013 various contributors (see AUTHORS)
|
||||
#
|
||||
# This file is part of Python-EFL.
|
||||
#
|
||||
# Python-EFL is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public
|
||||
# License as published by the Free Software Foundation; either
|
||||
# version 2.1 of the License, or (at your option) any later version.
|
||||
#
|
||||
# Python-EFL is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
cdef class Poller(Eo):
|
||||
"""
|
||||
|
||||
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.
|
||||
|
||||
The `interval` must be between 1 and 32768 inclusive, and must be a power of
|
||||
2 (i.e. 1, 2, 4, 8, 16, ... 16384, 32768). The exact tick in which `func`
|
||||
will be called is undefined, as only the interval between calls can be
|
||||
defined. Ecore will endeavor to keep pollers synchronized and to call as
|
||||
many in 1 wakeup event as possible. If `interval` is not a power of two, the
|
||||
closest power of 2 greater than `interval` will be used.
|
||||
|
||||
When the poller `func` is called, it must return a value of either
|
||||
ECORE_CALLBACK_RENEW(or True) or ECORE_CALLBACK_CANCEL(or False). If it
|
||||
returns 1, it will be called again at the next tick, or if it returns
|
||||
0 it will be deleted automatically making any references/handles for it
|
||||
invalid.
|
||||
|
||||
Example::
|
||||
|
||||
def poller_cb():
|
||||
print("Poller")
|
||||
return True
|
||||
|
||||
ecore.Poller(4, poller_cb)
|
||||
|
||||
:param interval: The poll interval
|
||||
:type interval: int
|
||||
:param func: The cunction to call at every intervat
|
||||
:type func: callable
|
||||
:param poll_type: The ticker type to attach the poller to. Must be ECORE_POLLER_CORE
|
||||
:type poll_type: Ecore_Poll_Type
|
||||
|
||||
"""
|
||||
def __init__(self, int interval, func, pol_type=0, *args, **kargs):
|
||||
if not callable(func):
|
||||
raise TypeError("Parameter 'func' must be callable")
|
||||
self.func = func
|
||||
self.args = args
|
||||
self.kargs = kargs
|
||||
self._set_obj(ecore_poller_add(pol_type, interval, _ecore_task_cb, <void *>self))
|
||||
|
||||
def __str__(self):
|
||||
return "%s Poller(func=%s, args=%s, kargs=%s)" % (Eo.__str__(self),
|
||||
self.func, self.args, self.kargs)
|
||||
|
||||
def __repr__(self):
|
||||
return "%s Poller(interval=%d, func=%s, args=%s, kargs=%s)" % (Eo.__repr__(self),
|
||||
self.interval if self.obj else -1,
|
||||
self.func, self.args, self.kargs)
|
||||
|
||||
cpdef bint _task_exec(self):
|
||||
return self.func(*self.args, **self.kargs)
|
||||
|
||||
def delete(self):
|
||||
""" Stop callback emission and free internal resources. """
|
||||
ecore_poller_del(self.obj)
|
||||
|
||||
|
||||
property interval:
|
||||
""" The interval (in ticks) between each call of the poller
|
||||
|
||||
:type: int
|
||||
|
||||
"""
|
||||
def __get__(self):
|
||||
return ecore_poller_poller_interval_get(self.obj)
|
||||
|
||||
def __set__(self, int t):
|
||||
ecore_poller_poller_interval_set(self.obj, t)
|
||||
|
||||
def interval_set(self, int t):
|
||||
ecore_poller_poller_interval_set(self.obj, t)
|
||||
def interval_get(self):
|
||||
return ecore_poller_poller_interval_get(self.obj)
|
||||
|
||||
|
||||
def poller_add(int t, func, *args, **kargs):
|
||||
return Poller(t, func, *args, **kargs)
|
||||
|
|
@ -53,6 +53,9 @@ cdef extern from "Ecore.h":
|
|||
ECORE_ANIMATOR_SOURCE_TIMER
|
||||
ECORE_ANIMATOR_SOURCE_CUSTOM
|
||||
|
||||
ctypedef enum Ecore_Poller_Type:
|
||||
ECORE_POLLER_CORE
|
||||
|
||||
|
||||
cdef extern from "Ecore_File.h":
|
||||
ctypedef enum Ecore_File_Event:
|
||||
|
|
|
@ -19,7 +19,7 @@ from efl cimport *
|
|||
from efl.c_eo cimport Eo as cEo
|
||||
from efl.eo cimport Eo
|
||||
from efl.ecore.enums cimport Ecore_Fd_Handler_Flags, Ecore_Exe_Flags, \
|
||||
Ecore_File_Event
|
||||
Ecore_File_Event, Ecore_Poller_Type
|
||||
|
||||
|
||||
cdef extern from "Ecore.h":
|
||||
|
@ -28,6 +28,7 @@ cdef extern from "Ecore.h":
|
|||
#
|
||||
ctypedef cEo Ecore_Timer
|
||||
ctypedef cEo Ecore_Animator
|
||||
ctypedef cEo Ecore_Poller
|
||||
ctypedef cEo Ecore_Idler
|
||||
ctypedef cEo Ecore_Idle_Enterer
|
||||
ctypedef cEo Ecore_Idle_Exiter
|
||||
|
@ -105,6 +106,11 @@ cdef extern from "Ecore.h":
|
|||
void ecore_animator_frametime_set(double frametime)
|
||||
double ecore_animator_frametime_get()
|
||||
|
||||
Ecore_Poller *ecore_poller_add(Ecore_Poller_Type type, int interval, Ecore_Task_Cb func, const_void *data)
|
||||
void *ecore_poller_del(Ecore_Poller *poller)
|
||||
Eina_Bool ecore_poller_poller_interval_set(Ecore_Poller *poller, int interval)
|
||||
int ecore_poller_poller_interval_get(Ecore_Poller *poller)
|
||||
|
||||
Ecore_Timer *ecore_timer_add(double t, Ecore_Task_Cb func, void *data)
|
||||
void *ecore_timer_del(Ecore_Timer *timer)
|
||||
void ecore_timer_freeze(Ecore_Timer *timer)
|
||||
|
@ -205,6 +211,13 @@ cdef class Animator(Eo):
|
|||
cpdef bint _task_exec(self)
|
||||
|
||||
|
||||
cdef class Poller(Eo):
|
||||
cdef readonly object func
|
||||
cdef readonly tuple args
|
||||
cdef readonly dict kargs
|
||||
cpdef bint _task_exec(self)
|
||||
|
||||
|
||||
cdef class Idler(Eo):
|
||||
cdef readonly object func, args, kargs
|
||||
cpdef bint _task_exec(self)
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from efl import ecore
|
||||
import unittest
|
||||
|
||||
|
||||
counters = [0, 0]
|
||||
params = None
|
||||
|
||||
|
||||
def poller_cb():
|
||||
counters[0] += 1
|
||||
return True
|
||||
|
||||
def poller_cb2(one, two, three, test):
|
||||
global params
|
||||
|
||||
params = (one, two, three)
|
||||
counters[1] += 1
|
||||
return False
|
||||
|
||||
|
||||
class TestPoller(unittest.TestCase):
|
||||
def testInit(self):
|
||||
|
||||
p1 = ecore.Poller(4, poller_cb)
|
||||
p2 = ecore.Poller(2, poller_cb2, ecore.ECORE_POLLER_CORE,
|
||||
"uno", "due", three="tre", test=self)
|
||||
p3 = ecore.Poller(16, lambda: ecore.main_loop_quit())
|
||||
|
||||
self.assertIsInstance(p1, ecore.Poller)
|
||||
self.assertIsInstance(p2, ecore.Poller)
|
||||
self.assertIsInstance(p3, ecore.Poller)
|
||||
|
||||
ecore.main_loop_begin()
|
||||
|
||||
self.assertEqual(counters, [4, 1])
|
||||
self.assertEqual(params, ("uno", "due", "tre"))
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity=2)
|
||||
ecore.shutdown()
|
Loading…
Reference in New Issue