from twisted.internet import reactor


class Observer(object):
    def __init__(self):
        self.dispatch = {}

    def emit(self, signal, *msg):
        """ emit a signal, return True if sent somewhere. """
        if signal in self.dispatch:
            # key exists, but is there anything in the list?
            if self.dispatch[signal]:
                # Yes there is.
                for listener in self.dispatch[signal]:
                    reactor.callLater(0, listener, *msg)
                return True
            return False
        return False

    def connect(self, signal, func):
        """ Connect a signal to a given function. """
        if not signal in self.dispatch:
            self.dispatch[signal] = []

        self.dispatch[signal].append(func)

    def disconnect(self, signal, func):
        """ Disconnect a signal with a certain function. """
        if signal in self.dispatch:
            self.dispatch[signal].remove(func)
            if len(self.dispatch[signal]) == 0:
                self.dispatch.pop(signal)

    def save(self):
        """ Save the current dispatch, and clears it. """
        ret = dict(self.dispatch)
        self.dispatch = {}
        return ret

    def load(self, dispatch):
        """ Load/restore the dispatch. """
        assert not dispatch is None
        self.dispatch = dict(dispatch)