Designing an event mechanism in C++
<p>I am trying to design a generic (but somewhat use-case-specific) event-passing mechanism in C++ without going against the grain with regard to "new style" C++, and at the same time without going overboard with templates.</p>

<p>My use case is somewhat particular in that I require complete control over when events are distributed. The event system underlies a world simulation where each iteration of the world acts on the events generated by the previous frame. So I require all events to be queued up before they are dispatched, so that the app can flush the queue at specific intervals, somewhat like the classic GUI event loop.</p>

<p>My use case is trivial to implement in Ruby, Python or even C, but with C++ I am coming up a bit short. I <em>have</em> looked at Boost::Signal and other similar libraries, but they seem too complex or inflexible to suit my particular use case. (Boost, in particular, is templated-based often to the point of utter confusion, especially things like boost::bind or boost::function.)</p>

<hr>

<h3>Here's the system, in broad strokes:</h3>

<ul>
<li><p>Consumers listen to events by registering themselves directly with the objects that produce the events.</p></li>
<li><p>Events are just string names, but each event may have additional data attached to it.</p></li>
<li><p>Listeners are just methods. If this were C++11 I would use lambdas, but I need broad compiler portability, so using methods for the moment.</p></li>
<li><p>When a producer triggers an event, the event goes into the queue until the time comes to dispatch it to the list of listeners.</p></li>
<li><p>The queue is dispatched in strict order of event triggering. (So if producer A triggers event x, an producer B triggers y, and producer B triggers z again, then the total order is x, y, z.)</p></li>
<li><p>It's important that whatever events are produced by the listeners during will not be dispatched until the <em>next</em> iteration -- so there are really two queues internally.</p></li>
</ul>

<hr>

<h3>Here's an "ideal" pseudo-code example of a consumer:</h3>

<pre><code>SpaceshipController::create() {
    spaceship.listen("crash", &amp;on_crash);
}

SpaceshipController::on_crash(CrashEvent event) {
    spaceship.unlisten("crash", &amp;on_crash);
    spaceship.remove();
    add(new ExplosionDebris);
    add(new ExplosionSound);
}
</code></pre>

<p>And here is a producer:</p>

<pre><code>Spaceship::collided_with(CollisionObject object) {
    trigger("crash", new CrashEvent(object));
}
</code></pre>

<p>All this is well and good, but translating into modern C++ is where I meet difficulty.</p>

<hr>

<p>The problem is that either one has to go with old-style C++ with casting polymorphic instances and ugliness, or one has to go with template-level polymorphism with compile-time defined typing.</p>

<p>I have experimented with using boost::bind(), and I can produce a listen method like this:</p>

<pre><code>class EventManager
{
    template &lt;class ProducerClass, class ListenerClass, class EventClass&gt;
        void EventManager::listen(
            shared_ptr&lt;ProducerClass&gt; producer,
            string event_name,
            shared_ptr&lt;ListenerClass&gt; listener,
            void (ListenerClass::*method)(EventClass* event)
        )
    {
        boost::function1&lt;void, EventClass*&gt; bound_method = boost::bind(method, listener, _1);
        // ... add handler to a map for later execution ...
    }
}
</code></pre>

<p>(Note how I am defining central event manager; that is because I need to maintain a single queue across all producers. For convenience, individual classes still inherit a mixin that provides listen() and trigger() that delegate to the event manager.)</p>

<p>Now it's possible to listen by doing:</p>

<pre><code>void SpaceshipController::create()
{
    event_manager.listen(spaceship, "crash", shared_from_this(),
        &amp;SpaceshipController::on_crash);
}

void SpaceshipController::on_crash(CrashEvent* event)
{
    // ...
}
</code></pre>

<p>That's pretty good, although it's verbose. I hate forcing every class to inherit enable_shared_from_this, and C++ requires that method references include the class name, which sucks, but both problems are probably unavoidable.</p>

<p>Unfortunately, I don't see how to implement listen() this way, since the classes are only known at compile time. I need to store the listeners in a per-producer map, which in turn contains a per-event-name map, something like:</p>

<pre><code>unordered_map&lt;shared_ptr&lt;ProducerClass&gt;,
    unordered_map&lt;string, vector&lt;boost:function1&lt;void, EventClass*&gt; &gt; &gt; &gt; listeners;
</code></pre>

<p>But of course C++ doesn't let me. I could cheat:</p>

<pre><code>unordered_map&lt;shared_ptr&lt;void*&gt;,
    unordered_map&lt;string, vector&lt;boost:function1&lt;void, void*&gt; &gt; &gt; &gt; listeners;
</code></pre>

<p>but then that feels terribly dirty.</p>

<p>So now I have to templatize EventManager or something, and keep one for each producer, perhaps? But I don't see how to do that without splitting up the queue, and I can't do that.</p>

<hr>

<p>Note how I am explicitly trying to avoid having to define pure interface classes for each type of event, Java-style:</p>

<pre><code>class CrashEventListener
{
    virtual void on_crash(CrashEvent* event) = 0;
}
</code></pre>

<p>With the number of events I have in mind, that would get awful, fast.</p>

<p>It also raises another issue: I want to have fine-grained control over event handlers. For example, there are many producers that simply provide an event called "change". I want to be able to hook producer A's "change" event to on_a_change, and producer's B "change" event to on_b_change, for example. Per-event interfaces would make that inconvenient at best.</p>

<hr>

<p>With all this in mind, could someone please point me in the right direction?</p>
