2021-02-10 07:38:55 +01:00
|
|
|
import time
|
|
|
|
import asyncio
|
|
|
|
import math
|
|
|
|
|
|
|
|
|
|
|
|
class Timer(object):
|
|
|
|
|
2021-02-16 20:37:51 +01:00
|
|
|
def __init__(self, timeout, on_done = None, on_update = None) -> None:
|
2021-02-10 07:38:55 +01:00
|
|
|
super().__init__()
|
|
|
|
self.timeout = timeout
|
|
|
|
self._timemout = self.timeout
|
|
|
|
self._task = None
|
2021-02-16 20:37:51 +01:00
|
|
|
self._callback = on_done
|
|
|
|
self._update = on_update
|
2021-02-10 07:38:55 +01:00
|
|
|
self.start_time = None
|
2021-02-16 20:37:51 +01:00
|
|
|
|
|
|
|
def done(self, task):
|
|
|
|
if self._callback is not None:
|
|
|
|
asyncio.create_task(self._callback(self))
|
|
|
|
|
2021-02-10 07:38:55 +01:00
|
|
|
async def _job(self):
|
|
|
|
self.start_time = time.time()
|
|
|
|
self.count = int(round(self._timemout, 0))
|
|
|
|
try:
|
2021-03-03 07:37:54 +01:00
|
|
|
while self.count > 0:
|
|
|
|
self.count -= 1
|
2021-02-10 07:38:55 +01:00
|
|
|
if self._update is not None:
|
2021-03-03 07:37:54 +01:00
|
|
|
await self._update(self,self.count)
|
2021-02-10 07:38:55 +01:00
|
|
|
await asyncio.sleep(1)
|
|
|
|
except asyncio.CancelledError:
|
|
|
|
end = time.time()
|
|
|
|
duration = end - self.start_time
|
|
|
|
self._timemout = self._timemout - duration
|
2021-03-03 07:37:54 +01:00
|
|
|
|
|
|
|
async def add(self, seconds):
|
|
|
|
self.count = self.count + seconds
|
|
|
|
|
2021-02-10 07:38:55 +01:00
|
|
|
def start(self):
|
|
|
|
self._task = asyncio.create_task(self._job())
|
2021-02-16 20:37:51 +01:00
|
|
|
self._task.add_done_callback(self.done)
|
2021-02-10 07:38:55 +01:00
|
|
|
|
|
|
|
async def stop(self):
|
2021-02-16 20:37:51 +01:00
|
|
|
if self._task and self._task.done() is False:
|
|
|
|
self._task.cancel()
|
|
|
|
await self._task
|
2021-02-10 07:38:55 +01:00
|
|
|
|
|
|
|
def reset(self):
|
|
|
|
if self.is_running is True:
|
|
|
|
return
|
|
|
|
self._timemout = self.timeout
|
|
|
|
|
|
|
|
def is_running(self):
|
|
|
|
return not self._task.done()
|
|
|
|
|
|
|
|
def set_time(self,timeout):
|
|
|
|
if self.is_running is True:
|
|
|
|
return
|
|
|
|
self.timeout = timeout
|
|
|
|
|
|
|
|
def get_time(self):
|
|
|
|
return self.format_time(int(round(self._timemout,0)))
|
|
|
|
|
2021-02-16 20:37:51 +01:00
|
|
|
@classmethod
|
|
|
|
def format_time(cls, time):
|
2021-02-10 07:38:55 +01:00
|
|
|
pattern = '{0:02d}:{1:02d}:{2:02d}'
|
|
|
|
seconds = time % 60
|
|
|
|
minutes = math.floor(time / 60) % 60
|
|
|
|
hours = math.floor(time / 3600)
|
2021-02-16 20:37:51 +01:00
|
|
|
return pattern.format(hours, minutes, seconds)
|