-
Notifications
You must be signed in to change notification settings - Fork 0
/
clock.py
executable file
·104 lines (81 loc) · 2.69 KB
/
clock.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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
from twistymud.settings import TICK_TIME
from persist import Persistent, getP
from twisted.internet import reactor
from twisted.internet import task
class Clock(Persistent):
instance = None
@classmethod
def getInstance(cls,*args,**kwargs):
if not cls.instance:
cls.instance = cls(*args,**kwargs)
return cls.instance
def __init__(self,id=None):
Persistent.__init__(self)
self.id = id
self.events = {}
self.time = 0L
self.nextEventId=1
self.stopped = False
self.debug = False
def callLater(self,time,function,*args,**kwargs):
return reactor.callLater(time,function,*args,**kwargs)
def start(self):
self.callLater(TICK_TIME,self.tick)
self.stopped = False
def stop(self):
self.stopped = True
def tick(self):
self.time+=1
if self.debug:
print self.time
self.callLater(TICK_TIME,self.tick)
def addEvent(self,time,o,name,*args,**kwargs):
eventId = self.nextEventId
self.nextEventId+=1
self.events[eventId] = (self.time,self.time+time,getP(o),name,args,kwargs)
self.callLater(time,self.callEvent,eventId)
return eventId
def callEvent(self,eventId):
if self.stopped:
return
if eventId not in self.events:
return
start,end,p,name,args,kwargs = self.events[eventId]
del self.events[eventId]
o = p()
if o and hasattr(o,name):
func = getattr(o,name)
func(*args,**kwargs)
def cancel(self,eventId):
if eventId in self.events:
del self.events[eventId]
def __setstate__(self,d):
self.__dict__.update(d)
self.restartEvents()
def restartEvents(self):
for (eventId, (scheduleTime, eventTime, p, names, args, kwargs)) in self.events.iteritems():
time = eventTime - self.time
if time < 0:
time = 0
self.callLater(time,self.callEvent,eventId)
class TestableClock(Clock):
@classmethod
def makeTestClock(cls):
Clock.instance = TestableClock()
return Clock.instance
def __init__(self):
Clock.__init__(self)
self.clock = task.Clock()
def advance(self,time):
for i in xrange(time):
self.clock.advance(1)
def callLater(self,time,function,*args,**kwargs):
return self.clock.callLater(time,function,*args,**kwargs)
def __getstate__(self):
d = self.__dict__.copy()
del d['clock']
return d
def __setstate__(self,d):
self.__dict__.update(d)
self.clock = task.Clock()
self.restartEvents()