deferred.py
上传用户:ghyvgy
上传日期:2009-05-26
资源大小:547k
文件大小:3k
源码类别:

其他游戏

开发平台:

Python

  1. # deferred.py
  2. #
  3. # Implement a deferred (asynchronous) call framework.
  4. # Allows the storing of method and function calls in
  5. # a list, sorted by the time in which they are to be 
  6. # called. Using this module, a client may schedule a
  7. # call on any object that is addressable via the objmgr
  8. # module (i.e. has an id).
  9. #
  10. # Author: Matthew Walker
  11. #         mwalker@softhome.net
  12. #
  13. import time
  14. import bisect  # efficient list operations
  15. import objmgr
  16. # module-scoped list; protect against reload
  17. try:
  18.   deferredCalls
  19. except NameError:
  20.   deferredCalls = []
  21. class DeferredCall:
  22.   """
  23.   Responsible for representing the state of a method or
  24.   function call that is intended to be executed at some
  25.   time in the future.
  26.   """
  27.   def __init__(self, id, call, args, t, cb, cbArgs):
  28.     self.targetId  = id
  29.     self.call      = call
  30.     self.args      = args
  31.     self.time      = t
  32.     self.callback  = cb
  33.     self.cbArgs    = cbArgs
  34.   def __cmp__(self, other):
  35.     return cmp(self.time, other.time)
  36.   def __call__(self):
  37.     """
  38.     Make this class a callable object (a.k.a. a functor),
  39.     which acts just like a fuction or method.
  40.     """
  41.     target = objmgr.GetObject(self.targetId)
  42.     if target is not None:
  43.       try:
  44.         method = getattr(target, self.call)
  45.       except AttributeError:
  46.         print "No %s on %s" % (self.call, target)
  47.         return
  48.       apply(method, self.args) # make the call
  49.       if self.callback is not None:
  50.         # notify that call is complete
  51.         apply(self.callback, self.cbArgs)
  52.     else:
  53.       print 'No valid target for %s' % (self,)
  54.   def __repr__(self):
  55.     """
  56.     Return a string representation of this object.
  57.     """
  58.     return '<%s: call [%s] args [%s] time [%s] cb [%s] cbArgs [%s]>' % 
  59.       (self.__class__.__name__, self.call, self.args, self.time, self.callback, self.cbArgs)
  60. def Call(target, call, args, delay=0, cb=None, cbArgs=()):
  61.   """
  62.   Schedule a call for later execution. This 
  63.   is the API for making a deferred call.
  64.   """
  65.   #print 'Call( %s, %s, %s, %s, %s, %s )' % (target, call, args, delay, cb, cbArgs)
  66.   callTime = time.time() + float(delay) / 1000.0
  67.   dCall = DeferredCall(target, call, args,
  68.                        callTime, cb, cbArgs)
  69.   bisect.insort_right(deferredCalls, dCall)
  70. def ExecuteDeferredCalls():
  71.   """
  72.   Run deferred method calls whose time has come.
  73.   """
  74.   dCall = None
  75.   now = time.time()
  76.   while deferredCalls:
  77.     dCall = deferredCalls.pop(0) # front of the list
  78.     if dCall.time > now:
  79.       # not time yet, put it back at front of the list
  80.       deferredCalls.insert(0, dCall)
  81.       break
  82.     
  83.     dCall() # execute the call, and any callbacks
  84.   # now return how long in ms until next call
  85.   next = None  # forever
  86.   if dCall is not None:
  87.     next = int((dCall.time - time.time()) * 1000.0)
  88.     if next < 0:
  89.       next = 0
  90.   return next