00001
00002
00003
00004 import weakref
00005
00006 class WeakCallback (object):
00007 """A Weak Callback object that will keep a reference to
00008 the connecting object with weakref semantics.
00009
00010 This allows object A to pass a callback method to object S,
00011 without object S keeping A alive.
00012 """
00013 def __init__(self, mcallback):
00014 """Create a new Weak Callback calling the method @mcallback"""
00015 obj = mcallback.im_self
00016 attr = mcallback.im_func.__name__
00017 self.wref = weakref.ref(obj, self.object_deleted)
00018 self.callback_attr = attr
00019 self.token = None
00020
00021 def __call__(self, *args, **kwargs):
00022 obj = self.wref()
00023 if obj:
00024 attr = getattr(obj, self.callback_attr)
00025 attr(*args, **kwargs)
00026 else:
00027 self.default_callback(*args, **kwargs)
00028
00029 def default_callback(self, *args, **kwargs):
00030 """Called instead of callback when expired"""
00031 pass
00032
00033 def object_deleted(self, wref):
00034 """Called when callback expires"""
00035 pass
00036
00037 class WeakCallbackCb(WeakCallback):
00038 def __init__(self, mcallback):
00039 WeakCallback.__init__(self, mcallback)
00040 self._deleted_cb = None
00041
00042 def object_deleted(self, wref):
00043 if self._deleted_cb:
00044 self._deleted_cb(*self._args, **self._kwargs)
00045
00046
00047
00048 self.set_deleted_cb()
00049
00050 def set_deleted_cb(self, cb = None, *args, **kwargs):
00051 self._deleted_cb = cb
00052 self._args = args
00053 self._kwargs = kwargs
00054 if not cb:
00055 self._args = None
00056 self._kwargs = None
00057
00058