Improving dispatch in an event manager

Hello all,

I’ve recently started building an event manager in Julia as part of a larger project. I’ve done this in OO languages before and I implemented a similar one in Julia. In such an event manager you have events which may pass some data, listeners waiting for events, and a manager that knows who is listening for what events and sends them to the right locations when they are dispatched.

This event manager works fine but requires a lot of composition making it clunky to use. I wanted to take a stab at using Julia’s multiple dispatch to circumvent the need for so many objects and also practice more functional approaches so solving problems.

The solution I’ve come up with is clean but very slow. It makes use of type parameterization so that a unique method is created for handling an event of some type. An example handle method might look like this:

handle(s::Listener{:sys1}, e::Event{:key_pressed}) = print(e.data) #do something

The Symbol “:sys1” would correspond to some system (like a renderer) waiting for the event “:key_pressed”. When something dispatches an event, it runs the dispatch function which then finds the methods of “handle” corresponding to that event and runs them all. It’s important that the dispatcher knows nothing about where the event goes. It is essentially broadcasting it to any interested listeners.

Here is how I implemented the dispatch function:

function dispatch(event::Event{T}) where T
    matchedMethods = methodswith(typeof(event),handle)
    matchedListeners = [m.sig.parameters[2].parameters[1] for m in matchedMethods] #extraction of signature
    for L in matchedListeners handle(Listener{L}(),event) end
end

It is a bit hacky as I’m making use of methodswith() to extract method signatures. It’s also very slow and slows down as the number of handle methods increases. I’ve also tried methods() which allows you to add a tuple of argument types but this was even slower.

I was wondering if anyone knew of a way of quickly finding the methods associated with an argument type? Is there some table that Julia keeps in the background that could be accessed? Or would you recommend some other approach?

Thanks for your help!

I did a little more research and found that the Julia manual has some advice about using types with values as parameters. It essentially boils down to “don’t do this” (in most cases).

https://docs.julialang.org/en/v1/manual/performance-tips/#The-dangers-of-abusing-multiple-dispatch-(aka,-more-on-types-with-values-as-parameters)

Regardless, it was interesting to play around with the type system.

1 Like