Two new callbacks for RepeatedTimer when cancelled or condition untrue

This commit is contained in:
Gina Häußge 2015-08-28 16:53:22 +02:00
parent 5df088cfee
commit 9b9ecfe9be

View file

@ -562,13 +562,18 @@ class RepeatedTimer(threading.Thread):
run_first (boolean): If set to True, the function will be run for the first time *before* the first wait period. run_first (boolean): If set to True, the function will be run for the first time *before* the first wait period.
If set to False (the default), the function will be run for the first time *after* the first wait period. If set to False (the default), the function will be run for the first time *after* the first wait period.
condition (callable): Condition that needs to be True for loop to continue. Defaults to ``lambda: True``. condition (callable): Condition that needs to be True for loop to continue. Defaults to ``lambda: True``.
on_condition_false (callable): Callback to call when the timer finishes due to condition becoming false. Will
be called before the ``on_finish`` callback.
on_cancelled (callable): Callback to call when the timer finishes due to being cancelled. Will be called
before the ``on_finish`` callback.
on_finish (callable): Callback to call when the timer finishes, either due to being cancelled or since on_finish (callable): Callback to call when the timer finishes, either due to being cancelled or since
the condition became false. the condition became false.
daemon (bool): daemon flag to set on underlying thread. daemon (bool): daemon flag to set on underlying thread.
""" """
def __init__(self, interval, function, args=None, kwargs=None, def __init__(self, interval, function, args=None, kwargs=None,
run_first=False, condition=None, on_finish=None, daemon=True): run_first=False, condition=None, on_condition_false=None,
on_cancelled=None, on_finish=None, daemon=True):
threading.Thread.__init__(self) threading.Thread.__init__(self)
if args is None: if args is None:
@ -589,11 +594,15 @@ class RepeatedTimer(threading.Thread):
self.kwargs = kwargs self.kwargs = kwargs
self.run_first = run_first self.run_first = run_first
self.condition = condition self.condition = condition
self.on_condition_false = on_condition_false
self.on_cancelled = on_cancelled
self.on_finish = on_finish self.on_finish = on_finish
self.daemon = daemon self.daemon = daemon
def cancel(self): def cancel(self):
self.finish() self._finish(self.on_cancelled)
def run(self): def run(self):
while self.condition(): while self.condition():
@ -608,17 +617,23 @@ class RepeatedTimer(threading.Thread):
# wait, but break if we are cancelled # wait, but break if we are cancelled
self.finished.wait(self.interval()) self.finished.wait(self.interval())
if self.finished.is_set(): if self.finished.is_set():
break return
if not self.run_first: if not self.run_first:
# if we are to run the function AFTER waiting for the first time # if we are to run the function AFTER waiting for the first time
self.function(*self.args, **self.kwargs) self.function(*self.args, **self.kwargs)
self.finish() # we'll only get here if the condition was false
self._finish(self.on_condition_false)
def finish(self): def _finish(self, *callbacks):
# make sure we set our finished event so we can detect that the loop was finished
self.finished.set() self.finished.set()
for callback in callbacks:
if not callable(callback):
continue
callback()
if callable(self.on_finish): if callable(self.on_finish):
self.on_finish() self.on_finish()