Saturday, August 07, 2004

Messaging on one channel

For a simple application wanting to talk to itself, messaging on a single channel works well (or on two channels, input/output, to keep republishing from within an event handler from recursing). But to support class-hierarchy events instead of attribute-based ones calls for a decent data structure since you need reflection in both discovery and publishing.

The key code is:

public void publish(final Event event) { final Set<Receiver> receivers = new HashSet<Receiver>(); for (Class eventClass = event.getClass(); Event.class.isAssignableFrom(eventClass); eventClass = eventClass.getSuperclass()) for (final Pair<Receiver, Method> pair : getPairs(eventClass)) invokeOnce(receivers, pair.first, pair.second, event); }

Which looks up receiver/method pairs from an eventClass/pair map built from receiver subscriptions to the channel. InvokeOnce uses a set to remember if a receiver was already given the incoming event. Since publish starts with the most derived event class and works its way up towards the event base class, this ensures that only the receive method with the most derived event class argument is invoked.

You can have several receive methods, each with a different event class argument, and the best matching one is called. (For once, I am glad for single inheritance: this scheme would break with diamond inheritance.)

No comments: