-
Notifications
You must be signed in to change notification settings - Fork 0
/
timerthread.py
86 lines (64 loc) · 2.29 KB
/
timerthread.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import math
import time
import threading
from datetime import datetime
from datetime import timedelta
class TimerThread(threading.Thread):
def __init__(self, duration, incrementFunction, tickCallback, gameOverCallback):
threading.Thread.__init__(self)
self.remaining = duration
self.incrementFunction = incrementFunction
self.tickCallback = tickCallback
self.gameOverCallback = gameOverCallback
self.daemon = True
self.paused = True
self.running = True
self.state = threading.Condition()
self.lastSec = 0
self.tick()
def run(self):
while self.running:
with self.state:
if self.paused:
self.state.wait() # block until notified
# sleeping and recording lenght of pause. (this can be interrupted)
before = datetime.now()
with self.state:
self.state.wait(0.05)
slept = datetime.now() - before
self.remaining -= slept
self.tick()
if self.remaining < timedelta(seconds=0):
self.gameOverCallback()
break
def tick(self):
rem = self.remainingTime()
hours, remainder = divmod(self.remaining.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
sec = int(math.floor(seconds))
if self.lastSec != rem['seconds']:
self.lastSec = rem['seconds']
self.tickCallback(rem)
def remainingTime(self):
hours, remainder = divmod(self.remaining.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
sec = int(math.floor(seconds))
return {
'hours' : hours,
'minutes' : minutes,
'seconds' : sec
}
def resume(self):
with self.state:
self.incrementFunction();
self.paused = False
self.state.notify() # unblock self if waiting
def pause(self):
with self.state:
self.paused = True # make self block and wait
self.state.notify() # unblock self if waiting
def stop(self):
self.running = False
self.paused = False
with self.state:
self.state.notify() # unblock self if waiting