import collections
import inspect
import time

_EVENTS = {}

_QUEUE = collections.deque()

ANY, QUIT = range(2)

_EVENTS[ANY] = set()


def register(event, func):
    if not callable(func):
        # XXX could raise an exception
        return
    if event not in _EVENTS:
        _EVENTS[event] = set()
    _EVENTS[event].add(func)


def unregister(event, func=None):
    if event not in _EVENTS:
        # XXX may raise an exception
        return
    if func is None and event is not ANY:
        del _EVENTS[event]
        return
    if func in _EVENTS[event]:
        _EVENTS[event].remove(func)


def post(event, **kargs):
    if event not in _EVENTS:
        return
    _QUEUE.append((event, kargs)) 


def _consume_event_queue():
    stop = False
    while _QUEUE:
        event, ekargs = _QUEUE.popleft()
        if event == QUIT:
            stop = True 
        handlers = _EVENTS[event] | _EVENTS[ANY]
        for handler in handlers:
            hargs, _, hkeywords, _ = inspect.getargspec(handler)
            kargs = dict(ekargs)
            if not hkeywords:
                for key in kargs:
                    if key not in hargs:
                        del kargs[key]
            handler(**kargs)
    return stop


def run():
    ''' Sample main loop of yaranullin '''
    stop = False
    while not stop:
        time.sleep(0.01)
        stop = _consume_event_queue()

import collections
import inspect
import time
import weakref

_EVENTS = {}

_QUEUE = collections.deque()

ANY, QUIT = range(2)

_EVENTS[ANY] = weakref.WeakSet()


def register(event, func):
    if not callable(func):
        # XXX could raise an exception
        return
    if event not in _EVENTS:
        _EVENTS[event] = weakref.WeakSet()
    _EVENTS[event].add(func)


def unregister(event, func=None):
    if event not in _EVENTS:
        # XXX may raise an exception
        return
    if func is None and event is not ANY:
        del _EVENTS[event]
        return
    if func in _EVENTS[event]:
        _EVENTS[event].remove(func)


def post(event, **kargs):
    if event not in _EVENTS:
        return
    _QUEUE.append((event, kargs)) 


def _consume_event_queue():
    stop = False
    while _QUEUE:
        event, ekargs = _QUEUE.popleft()
        if event == QUIT:
            stop = True 
        handlers = _EVENTS[event] | _EVENTS[ANY]
        for handler in handlers:
            hargs, _, hkeywords, _ = inspect.getargspec(handler)
            kargs = dict(ekargs)
            if not hkeywords:
                for key in kargs:
                    if key not in hargs:
                        del kargs[key]
            handler(**kargs)
    return stop


def run():
    ''' Sample main loop of yaranullin '''
    stop = False
    while not stop:
        time.sleep(0.01)
        stop = _consume_event_queue()

use weakref.WeakSet