CSharpMessenger

Author: Rod Hyde (badlydrawnrod)

Description
This is a delegate-based event system for C#. It uses generics to achieve static typing. As with other messaging systems, such as CSharpEventManager it allows for messaging between event producers and event consumers, without the need for producers or consumers to be aware of each other. The messengers are implemented as static classes, so there is never any need to instantiate a Messenger object. The use of generics means that parameters can be of any type and are not restricted to subclasses of a special Message class - if a callback only needs a float then supply it with a float.

Writing an event listener
To create an event listener, just write a method with the appropriate parameters. Here's an example of a listener that takes a float parameter. Note that although this example uses a method called OnSpeedChanged, this is merely convention and is not enforced. It could equally be called HandleSpeedChanged or any other valid identifier.

Registering an event listener
Of course, the listener will never be invoked unless it is registered with the messenger. This is done with the AddListener method. If the listener is part of a MonoBehaviour then it is good practice to register it when the behaviour is enabled.

Unregistering an event listener
If the listener should not be invoked when an event is fired then it must be unregistered with the RemoveListener method. As before, if the listener is part of a MonoBehaviour then it is good practice to unregister it when the behaviour is disabled.

Warning
RemoveListener should always be called on messages when loading a new level. Otherwise many MissingReferenceExceptions will be thrown, when invoking messages on destroyed objects. For example: 1. We registered a "speed changed" message in a Level1 scene. Afterwards the scene has been destroyed, but the "speed changed" message is still pointing to the OnSpeedChanged message handler in the destroyed class. 2. We loaded Level2 and registered another "speed changed" message, but the previous reference to the destroyed object hasn't been removed. We'll get a MissingReferenceException, because by invoking the "speed changed" message, the messaging system will first invoke the OnSpeedChanged handler of the destroyed object.

Invoking an event
To fire all the listeners for an event type, call the messenger's Invoke method, passing in the event type followed by the arguments.

Code
There are two files, Callback.cs and Messenger.cs. The code below contains callbacks and messengers for delegates that take no arguments, delegates that take one argument and delegates that take two arguments. It is straightforward to extend the code to take more arguments if needed.