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
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
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
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.
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of Lukasz Sent: Thursday, June 21, 2007 1:56 PM To: boost-users@lists.boost.org Subject: [Boost-users] problem... maybe boost could help
If anyone has some brilliant idea as to how this can be done (if it can), then i would appreciate the input.
[Nat] No such thing around here, just a half-baked thought. I wonder whether it would make any sense to introduce, for a given event subclass type, a canonical filter listener object. For a simple event class hierarchy, it might even work to register such listeners in a new map keyed by the typeid().name of the event subclass. So any receiver can look up any specific filter listener in a central registry. Each filter listener itself contains a registry of dependent receivers who want to process the events it's willing to pass. Its own processing method dynamic_casts each event to the desired event subclass type, and forwards only successfully-downcast events. Let's say we have receiver class SomeReceiver with a method that wants to process only EventTypeA events (processEventTypeA()), and another method that wants to process only EventTypeB events (processEventTypeB()). The SomeReceiver constructor looks up the canonical filter listener for EventTypeA and registers bind(&SomeReceiver::processEventTypeA, this, _1) with that filter listener. Similarly for processEventTypeB(). The filter listener could be a template class, and the registry through which they're looked up could use find-or-create logic to instantiate each specialization of filter listener on demand. That way you wouldn't need to maintain a central list of instantiations. So it would be up to the receiver's self-registration code to decide whether it wants to handle all events or only some subclass. If it wants to receive all events, it registers with the central event dispatcher as now. If it wants to receive only specific events, it registers instead with the filter that forwards only those specific events. Filter listeners, of course, listen to the central dispatcher. Or if you want to get fancy with the event hierarchy -- let's say EventTypeA and EventTypeB are each subclasses of EventTypeABBase -- I suppose you could register the filter listeners for each of EventTypeA and EventTypeB on the filter listener for EventTypeABBase. That way the filter listeners for EventTypeA and EventTypeB impose less overhead because they only see EventTypeABBase events. (If you combine this idea with a fully generic filter-listener template class and on-demand filter instantiation, the filter listener for EventTypeA needs to know enough to register itself with the filter listener for EventTypeABBase. It's not yet clear to me how to automate that. I guess you could hand-specialize the filter listeners for EventTypeA and EventTypeB so they'd know where to self-register. Alternatively, it's not strictly necessary for the EventTypeA and EventTypeB filter listeners to register on the filter listener EventTypeABBase -- that just appeals to my sense of elegance. They could all be neighbors on the central dispatcher.) I hope this will at least prompt other people to contribute more sensible ideas... ;-)
participants (3)
-
Lukasz
-
Nat Goodspeed
-
Ovanes Markarian