davemds pushed a commit to branch master.
commit 1c255024d3bcf0f95cf93c067c976f9139d11ef9
Author: davemds <[email protected]>
Date: Mon May 13 01:27:00 2013 +0200
Python-EFL: implemented ecore.Poller, with docs and unittest.
---
TODO | 2 -
doc/ecore/class-poller.rst | 4 ++
doc/ecore/ecore.rst | 13 +++++
efl/ecore/efl.ecore.pyx | 4 ++
efl/ecore/efl.ecore_poller.pxi | 112 +++++++++++++++++++++++++++++++++++++++++
include/efl.ecore.enums.pxd | 3 ++
include/efl.ecore.pxd | 15 +++++-
tests/ecore/test_03_poller.py | 44 ++++++++++++++++
8 files changed, 194 insertions(+), 3 deletions(-)
diff --git a/TODO b/TODO
index 80dddd1..8ad1ecb 100644
--- a/TODO
+++ b/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
diff --git a/doc/ecore/class-poller.rst b/doc/ecore/class-poller.rst
new file mode 100644
index 0000000..a7425dd
--- /dev/null
+++ b/doc/ecore/class-poller.rst
@@ -0,0 +1,4 @@
+:class:`efl.ecore.Poller` Class
+==============================
+
+.. autoclass:: efl.ecore.Poller
diff --git a/doc/ecore/ecore.rst b/doc/ecore/ecore.rst
index 30d232f..f6d2e11 100644
--- a/doc/ecore/ecore.rst
+++ b/doc/ecore/ecore.rst
@@ -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
diff --git a/efl/ecore/efl.ecore.pyx b/efl/ecore/efl.ecore.pyx
index fb40296..7cb2985 100644
--- a/efl/ecore/efl.ecore.pyx
+++ b/efl/ecore/efl.ecore.pyx
@@ -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"
diff --git a/efl/ecore/efl.ecore_poller.pxi b/efl/ecore/efl.ecore_poller.pxi
new file mode 100644
index 0000000..2d7713b
--- /dev/null
+++ b/efl/ecore/efl.ecore_poller.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)
+
diff --git a/include/efl.ecore.enums.pxd b/include/efl.ecore.enums.pxd
index fe72acb..7e2df6c 100644
--- a/include/efl.ecore.enums.pxd
+++ b/include/efl.ecore.enums.pxd
@@ -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:
diff --git a/include/efl.ecore.pxd b/include/efl.ecore.pxd
index 5b7bd26..19e6220 100644
--- a/include/efl.ecore.pxd
+++ b/include/efl.ecore.pxd
@@ -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)
diff --git a/tests/ecore/test_03_poller.py b/tests/ecore/test_03_poller.py
new file mode 100644
index 0000000..12a243b
--- /dev/null
+++ b/tests/ecore/test_03_poller.py
@@ -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()
--
------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and
their applications. This 200-page book is written by three acclaimed
leaders in the field. The early access version is available now.
Download your free book today! http://p.sf.net/sfu/neotech_d2d_may