Boost logo

Boost Users :

From: Lukasz (lkudra_at_[hidden])
Date: 2007-06-21 13:56:20


Hello,

I'm fairly new to boost and don't know all of the functionality. I have been
using the serialization library, read about mpl, signals and that's about
it. Maybe someone will have an idea if there is anything in boost that i
could use to solve the following problem (or any other solution).

I'm working a an Agent framework, and at this point, specifically on an
event (messaging system). The basic layout is the following (what concerns
the messaging part):

The framework contains Agents and Behaviors. They all need to communicate
with each other. Both of these classes derive from an interface
EventReceiver, which declares, amongst other things, a pure virtual
ProcessEvent(Event * event) function. Specific behaviors and agents are
obviously derived from the base ones. All events are derived from the base
Event class (to allow users to create their own events with whatever
information they need in there). The main messaging hub is a class
MessengerService, which contains two maps, the first one relates static
UUID's of events to UUID's of receivers , and the second receiver UUID's
with a list of actual events of type Event*. The basic use case is: a
behavior calls a register function in MessengerService to add itself as a
receiver for a certain type of event (register/unregister can happen at
anytime). At anytime, a behavior/agent can create an event, and call a send
function, which adds it to the list of events that are pending for a given
receiver (if a receiver was registered for this event type). As all
agents/behaviors are ticked, a "Monitor" is moved to the current
agent/behavior. The monitor queries the messenger service for all pending
events destined for the current agent/behavior, and calls a processEvent
function on the agent/behavior passing it the event as an argument. The
problem is here. I want agents/behaviors to add handlers for different event
types that they registered for, i.e.

class SomeBehavior: public Behavior
{
     ...
     processEvent(EventTest1 & event);
     processEvent(EventTest2 & event);
     ...
}

Since the events were registered, i know that the correct handlers exist in
the most derived class types (there will also be a forwarding scheme for
unregistered or broadcast events). The problem is that i only have a pointer
to the base class (EventReceiver) and to the base class of the event
(Event). I can't cast directly because i don't know the type to cast to.
Also, i don't want to add virtual functions for all possible events to the
base class, because that would mean that users would have to play around in
the base class (framework) every time they add a new event. Lastly, i wanted
to avoid having a general processEvent(Event & event) function and then have
the users "switch" on the event type. I solved part of the problem (the
first half) by adding a "MostDerviedHelper", which looks sort of like this:

template<class Derived>
class MostDerivedHelper
{
     ....
     void dispatchEvent(Event * event)
    {
        // Do dispatching here
        m_derivedPointer->processEvent(*(event->This()));

    }

private:
    Derived * m_derivedPointer;
}

Each derived type has a helper, which obviously contains the correct most
derived type (since it's itself). The problem now, is that i don't know what
to cast the event to so that it calls the correct handler. I can't add the
same type of helper to event, because then i would have to pass it the
receiver derived type through a template, but since it would have to be a
template, i can't call it using my base class event pointer (can't create
templated virtual functions). I tried adding a virtual function called
"This()" to all events, which would return the derived classes' this
pointer, but eventhough it's the correct type, i still need to cast it
(which i can't) since it has to be resolved at compile time. I read quite a
few things about double/multiple dispatch (in Loki for example), but it's
not quite the solution i'm looking for because a usual implementation uses a
callback, and that would require that i make my handlers static. MPL is not
much of a help either because it's based on static polymorphism, and what i
actually need is dynamic. I thought of using boost function & boost bind
combined with a double dispatch scheme, but this doesn't work either because
then i can't serialize it (i could re-perform the binding after a restore,
which i already do for boost::signals, but it's a hassle). So, i'm pretty
much out of ideas. I think to sum it up, what i would sort of need is:

template<class ReceiverType, class EventType>
class Dispatcher
{
     ...
     send(ReceiverType * receiver, eventType * event)
     {
           receiver->processEvent(event);
     }
}

In this situation, i would already have all the correct types. The problem
is that i can't get all this info at the same time.

I also thought about using the curiously recurring template pattern as such:

template<class Derived>
class Event
{
      template<class derivedReceiver>
      dispatch(derivedReceiver, Derived event) { .... }
}

This would work, except that since all events now must specialize to some
type of base, i can't use a base class pointer to store in my map, i.e. i
can't store all of my events in a map.

If anyone has some brilliant idea as to how this can be done (if it can),
then i would appreciate the input.

Thanks,

Lukasz

-- 
View this message in context: http://www.nabble.com/problem...-maybe-boost-could-help-tf3959613.html#a11235990
Sent from the Boost - Users mailing list archive at Nabble.com.

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net