0001from weakref import ref
0002
0003__all__ = ['EventHub', 'Signal']
0004
0005class EventHub(object):
0006
0007    def __init__(self):
0008        self._events = {}
0009
0010    def copy(self):
0011        new = self.__class__()
0012        new._events = self._events.copy()
0013        return new
0014
0015    def listen(self, signal, listener, attr=None, weak=True):
0016        if weak:
0017            listener = ref(listener)
0018        else:
0019            listener = lambda l=listener: l
0020        self._events.setdefault(signal, []).append((listener, attr))
0021
0022    def send(self, signal, **kw):
0023        for listener, attr in self._events.get(signal, ()):
0024            l = listener()
0025            if l is not None:
0026                if attr is not None:
0027                    l = getattr(l, attr)
0028                l(**kw)
0029
0030class _Signal(object):
0031    """
0032    Base event for all SQLObject events.
0033
0034    In general the sender for these methods is the class, not the
0035    instance.
0036    """
0037
0038    def __init__(self, class_name, bases, attrs):
0039        self.name = self.__name__ = class_name
0040        for name, value in attrs.items():
0041            setattr(self, name, value)
0042
0043    def __repr__(self):
0044        return '<Signal:%s>' % (self.name)
0045
0046Signal = _Signal('Signal', (), {})