1 # Copyright (C) 2016 The Android Open Source Project 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 15 '''Timer utility''' 16 17 from __future__ import absolute_import 18 19 import threading 20 21 22 class Timer(object): 23 '''A Timer utility to execute a callback after a certain interval.''' 24 25 def __init__(self, interval, callback): 26 '''Initialise the Timer without starting it. 27 28 Args: 29 interval: int or float, interval in seconds to count, before 30 invoking the callback 31 callback: function, it handles the function to call once 32 the timeout expires. 33 ''' 34 35 # validate input parameters 36 if not isinstance(interval, (int, float)): 37 raise TypeError('Argument "interval" is not a number: ' 38 '{0}'.format(type(interval))) 39 if not callable(callback): 40 raise TypeError('Argument "callback" is not a function: ' 41 '{0}'.format(type(callback))) 42 43 self._timer = None 44 self._callback = callback 45 self._interval = interval 46 47 def _is_running(self): 48 '''Checks whether the timer is executing. 49 50 Returns: 51 boolean, true if the timer is currently running, false otherwise 52 ''' 53 return self._timer is not None 54 55 def start(self): 56 '''Starts the timer. 57 58 Returns: 59 self, the Timer instance 60 61 Throws: 62 RuntimeError: if the timer is already running 63 ''' 64 if self._is_running(): 65 raise RuntimeError('Timer already running') 66 67 self._timer = threading.Timer(self._interval, self._callback) 68 self._timer.start() 69 return self # so that we can perform Timer(...).start() 70 71 def stop(self): 72 '''Stops the timer if it's executing. 73 74 Returns: 75 self, the Timer instance 76 ''' 77 78 if self._is_running(): 79 self._timer.cancel() 80 self._timer = None 81 return self 82 83 def reset(self): 84 '''Restart the timer. 85 86 Returns: 87 self, the Timer instance 88 ''' 89 90 self.stop() 91 self.start() 92 return self 93