PageRenderTime 30ms CodeModel.GetById 15ms app.highlight 10ms RepoModel.GetById 1ms app.codeStats 1ms

/circuits/core/timers.py

https://bitbucket.org/prologic/circuits/
Python | 89 lines | 41 code | 19 blank | 29 comment | 8 complexity | 67c00da65a35cc1fb2b056aa702d6c46 MD5 | raw file
 1# Module:   timers
 2# Date:     04th August 2004
 3# Author:   James Mills <prologic@shortcircuit.net.au>
 4
 5"""Timer component to facilitate timed events."""
 6
 7from circuits.core.handlers import handler
 8
 9from time import time, mktime
10from datetime import datetime
11
12from .components import BaseComponent
13
14
15class Timer(BaseComponent):
16    """Timer Component
17
18    A timer is a component that fires an event once after a certain
19    delay or periodically at a regular interval.
20    """
21
22    def __init__(self, interval, event, *channels, **kwargs):
23        """
24        :param interval: the delay or interval to wait for until
25                         the event is fired. If interval is specified as
26                         datetime, the interval is recalculated as the
27                         time span from now to the given datetime.
28        :type interval:  ``datetime`` or number of seconds as a ``float``
29
30        :param event:    the event to fire.
31        :type event:     :class:`~.events.Event`
32
33        :param persist:  An optional keyword argument which if ``True``
34                         will cause the event to be fired repeatedly
35                         once per configured interval until the timer
36                         is unregistered. **Default:** ``False``
37        :type persist:   ``bool``
38        """
39
40        super(Timer, self).__init__()
41
42        self.expiry = None
43        self.interval = None
44        self.event = event
45        self.channels = channels
46        self.persist = kwargs.get("persist", False)
47
48        self.reset(interval)
49
50    @handler("generate_events")
51    def _on_generate_events(self, event):
52        if self.expiry is None:
53            return
54
55        now = time()
56
57        if now >= self.expiry:
58            if self.unregister_pending:
59                return
60            self.fire(self.event, *self.channels)
61
62            if self.persist:
63                self.reset()
64            else:
65                self.unregister()
66            event.reduce_time_left(0)
67        else:
68            event.reduce_time_left(self.expiry - now)
69
70    def reset(self, interval=None):
71        """
72        Reset the timer, i.e. clear the amount of time already waited
73        for.
74        """
75
76        if interval is not None and isinstance(interval, datetime):
77            self.interval = mktime(interval.timetuple()) - time()
78        elif interval is not None:
79            self.interval = interval
80
81        self.expiry = time() + self.interval
82
83    @property
84    def expiry(self):
85        return getattr(self, "_expiry", None)
86
87    @expiry.setter
88    def expiry(self, seconds):
89        self._expiry = seconds