Thanks for the fast reply. Your solution looked very good for my problem, so
i tried to apply it. However, there seems to be a problem. At the point when
i call dispatchEvent (as in the below example) is when i have the actual
event to be sent. But i still only have a pointer to the base class and by
assigning it to the container, it always gets interpreted as a base event,
even when in reality it's some derived type.
I tried a couple of approaches. In the first one, my variant contains only
the derived type (base class is Event, derived is EventTest) , i.e.
typedef boost::variant<EventTest> event_container;
....
event_container m_eventContainer;
...
void sendEvent(Event * event)
{
// Call Helper to dispatch the event to correct type
m_eventContainer = *event;
m_derivedHelper->dispatchEvent(&m_eventContainer);
}
This won't work. The compiler complains that none of the overloads for
boost::detail::variant::make_initializer_node::apply can convert parameter
2. If i add the base event type to the variant list, i.e.
typedef boost::variant
In your case I would suggest using a Visitor pattern. You can use boost::variant to contain all possible events and query the stored one by applying a visitor to a variant. The Variant visitor can be a template function which will offer you the type safety and you could do casting to the correct type...
This might look like:
typedef boost::variant
event_container; template<class Handler_> struct EventDispatcher : boost::static_visitor
//result can be void { EventDispatcher(Handler_& h) : handler_(h){} template<class EventType_> result_type_of_functor operator()(EventType_ const& ev)const { return handler_.processEvent(ev); }
private: mutable Handler_& handler_; }
template<class Derived_> class MostDerivedHelper { .... void dispatchEvent(event_container* container) { // Do dispatching here boost::apply_visitor(container, EventDispatcher(*derived)); //apply visitor returns the result specified as static_visitor param
}
private: Derived_* derived_; };
I think this approach should work. And is probably has better performance as boost::bind.
With Kind Regards,
Ovanes Markarian
On Thu, June 21, 2007 19:56, Lukasz wrote:
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 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#a1123... Sent from the Boost - Users mailing list archive at Nabble.com.
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- View this message in context: http://www.nabble.com/problem...-maybe-boost-could-help-tf3959613.html#a1125... Sent from the Boost - Users mailing list archive at Nabble.com.