Figure 1
You have a certain data "packet" that you want to send to interested listeners. In the diagram, it is the YourEvent class. It is typically a struct with a bunch of const data members and a constructor to initialize them.
Listener< EvType > is an abstract base class template. Your class interested in YourEvent events, called YourListener in Fig. 1, derives from this abstract base class (with the template parameter EvType = YourEvent). Listener< EvType > provides a virtual method, processEvent(const EvType&), to be overriden in YourListener, and provides other concrete methods useful to listeners.
EventSender< EvType > is the dispatcher. It accepts registration by classes that inherit from Listener< EvType >, i.e. objects interested in EvType. It also dispatches EvType events to those listeners when EventSender< EvType>::send(const EvType&) is called.
If one of your listeners for EvType events causes another EvType event to be generated as a consequence of a first EvType being generated, a EventSender< EvType>::IllegalSendError exception will be thrown by the EventSender< EvType>::send() method mentioned above.
More "advanced" uses:
Figure 2
EvType can inherit from PolymorphEvent, and be stored in a container, e.g. in std::queue< PolymorphEvent> . PolymorphEvent is an abstract base class that defines a pure virtual send() method for you, which you trivially override to call send< EvType >(). You give each event in the container to EventSender<PolymorphEvent>::send() (or you can call send() directly on the event).
Figure 3
1.2.18