tuikit/core/timer.py
author Radek Brich <radek.brich@devl.cz>
Wed, 19 Mar 2014 20:42:52 +0100
changeset 90 781774a8d568
permissions -rw-r--r--
Add timer, adjust inheritance of Widget, Container, Window.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
90
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
import time
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     2
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     3
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     4
class TimerEvent:
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     5
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     6
    __slots__ = ('time', 'callback', 'args')
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     7
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     8
    def __init__(self, delay, callback, args):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     9
        self.time = time.time() + delay
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    10
        self.callback = callback
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    11
        self.args = args
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    12
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    13
    def execute(self):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    14
        self.callback(*self.args)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    15
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    16
    def __lt__(self, other):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    17
        return self.time < other.time
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    18
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    19
    def __str__(self):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    20
        return '{:.2f}s {} {}'.format(
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    21
            self.time - time.time(), self.callback, self.args)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    22
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    23
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    24
class Timer:
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    25
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    26
    def __init__(self):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    27
        #: Each timeout
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    28
        self.events = []
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    29
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    30
    def add_timeout(self, delay, callback, *args):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    31
        """Register `callback` to be called after `delay` seconds."""
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    32
        self.events.append(TimerEvent(delay, callback, args))
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    33
        self.events.sort(reverse=True)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    34
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    35
    def remove_timeout(self, callback, *args):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    36
        """Unregister callback previously registered with add_timeout.
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    37
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    38
        Removes all timeouts with the `callback` and `args`.
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    39
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    40
        """
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    41
        for event in self.events[:]:
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    42
            if event.callback == callback and event.args == args:
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    43
                self.events.remove(event)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    44
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    45
    def nearest_timeout(self):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    46
        """Get interval in seconds when next timeout expires.
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    47
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    48
        Returns None when no timeout is registered.
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    49
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    50
        """
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    51
        if not len(self.events):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    52
            return None
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    53
        timeout = self.events[-1].time - time.time()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    54
        return max(0, timeout)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    55
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    56
    def process_timeouts(self):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    57
        """Execute all expired timeouts."""
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    58
        now = time.time()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    59
        while len(self.events) and self.events[-1].time <= now:
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    60
            self.events[-1].execute()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    61
            self.events.pop()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    62
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    63
    def __str__(self):
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    64
        return '\n'.join(str(event) for event in self.events)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    65
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    66
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    67
if __name__ == '__main__':
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    68
    # Self Test
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    69
    t = Timer()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    70
    t.process_timeouts()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    71
    t.add_timeout(1, print, 'timeout 1')
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    72
    t.add_timeout(3, print, 'timeout 3')
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    73
    t.add_timeout(2, print, 'timeout 2')
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    74
    print(t)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    75
    print('Nearest: %.2f' % t.nearest_timeout())
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    76
    t.process_timeouts()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    77
    time.sleep(1)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    78
    t.process_timeouts()
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    79
    print(t)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    80
    time.sleep(2)
781774a8d568 Add timer, adjust inheritance of Widget, Container, Window.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    81
    t.process_timeouts()