Boost logo

Boost Users :

From: Lukasz (lkudra_at_[hidden])
Date: 2007-06-22 15:41:13


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<Event, EventTest> event_container;

 it will work, but it will always trigger the processEvent with the base
class type. I haven't found any information as to how boost::variant treats
a case of a pointer to a base class (in this case, i'm not even actually
passing the pointer but an object since for pointers it just doesn't seem to
work). Should it be able to automatically convert the type ? If not, then i
guess i'm back to square one, since i still can't cast the event... unless i
maybe misunderstood something ? The code i tried is pretty much what you
gave me, with some minor modifications.

Thanks in advance for any further assistance.

Lukasz K.

Ovanes Markarian wrote:
>
> 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<event1, event2, event3, event4, ...>
> event_container;
>
>
>
> template<class Handler_>
> struct EventDispatcher : boost::static_visitor<result_type_of_functor>
> //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 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 mailing list
>> Boost-users_at_[hidden]
>> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>>
>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> 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#a11258859
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