fp12's Tech blog

C++ / Python / Unreal Engine / Unity...

A simple event system

17 Nov 2016
  • yahtr
  • python

As I didn’t want my game logic to know about the UI system, I needed a simple way to let the UI know when game things happen.

Solution

I searched for existing Python event systems and many sources use the same principle:

  • a single class to register callbacks
  • use the self increment/decrement operators to add/remove yourself to the event
  • use the call operator to fire the event

So here is what you can find an other sites: a very clean Event class, which is very close to the one I use in yahtr.

class Event:
    def __init__(self, *args, **kwargs):
        self.handlers = set()

    def handle(self, handler):
        self.handlers.add(handler)
        return self

    def unhandle(self, handler):
        try:
            self.handlers.remove(handler)
        except:
            raise ValueError("Handler is not handling this event, so cannot unhandle it.")
        return self

    def fire(self, *args, **kargs):
        for handler in self.handlers:
            handler(*args, **kargs)

    __iadd__ = handle
    __isub__ = unhandle
    __call__ = fire

Note: I added *args and **kwargs to the __init__ so I can expose the argument(s) at event declaration. No checks are ever done though.

Then you can use it like that:

class MyEventSender:
    def __init__(self):
        # declare the event
        self.on_event = Event('arg1', 'arg2')
    
    def process(self, x, y):
        # fire the event
        self.on_event(x, y)

event_sender = MyEventSender()

class MyEventReceiver:
    def __init__(self):
        # register to the event with self callback
        event_sender.on_event += self.on_event_received
        
    def on_event_received(self, arg1, arg2)
        # receive the event here
        pass

Fabien.