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

Reply via email to