4 from twisted.internet import defer, reactor
5 from twisted.python import failure, log
10 self.id_generator = itertools.count()
14 def run_and_watch(self, func):
16 return self.watch(func)
17 def watch_weakref(self, obj, func):
18 # func must not contain a reference to obj!
19 watch_id = self.watch(lambda *args: func(obj_ref(), *args))
20 obj_ref = weakref.ref(obj, lambda _: self.unwatch(watch_id))
21 def watch(self, func):
22 id = self.id_generator.next()
23 self.observers[id] = func
25 def unwatch(self, id):
26 self.observers.pop(id)
32 res = self._once = Event()
35 def happened(self, *event):
38 once, self._once = self._once, None
40 for id, func in sorted(self.observers.iteritems()):
44 log.err(None, "Error while processing Event callbacks:")
49 def get_deferred(self, timeout=None):
52 id1 = once.watch(lambda *event: df.callback(event))
53 if timeout is not None:
55 df.errback(failure.Failure(defer.TimeoutError('in Event.get_deferred')))
58 delay = reactor.callLater(timeout, do_timeout)
59 x = once.watch(lambda *event: delay.cancel())
62 class Variable(object):
63 def __init__(self, value):
65 self.changed = Event()
66 self.transitioned = Event()
69 if value == self.value:
74 self.changed.happened(value)
75 self.transitioned.happened(oldvalue, value)
77 @defer.inlineCallbacks
78 def get_when_satisfies(self, func):
81 defer.returnValue(self.value)
82 yield self.changed.once.get_deferred()
84 def get_not_none(self):
85 return self.get_when_satisfies(lambda val: val is not None)