Boost logo

Boost Users :

From: Nat Goodspeed (nat_at_[hidden])
Date: 2008-05-24 21:34:30


Igor R wrote:

>> We took the opposite approach of explicitly queuing event
>> objects. When we "pump" the queue, it sends each of those pending events
>> through the signal to all connected slots.

> Could you please elaborate a bit more or just post a short code
> snippet?

I don't think I'm allowed to post a snippet of the real code. ;-)

> You queued functors containing shared_ptr to the original
> signal objects?

No -- or at least it doesn't sound to me like a match. Here's what we
do. Bear in mind that this is a single thread using classic Boost.Signals.

Let's say that Event is the data object we intend to propagate through
the system. Further suppose this typedef:

typedef boost::signal<void(const Event&)> MySignal;

We defined an EventQueue object containing an instance of MySignal and
(I believe) a std::vector<Event>. We gave EventQueue a method
addListener(const MySignal::slot_type&) that just forwards to
MySignal::connect(). EventQueue also has a method queueEvent(const
Event&) that forwards to std::vector<Event>::push_back(); finally it has
a pump() method that I'll describe in a moment.

So during initialization, various listeners locate this EventQueue and
call its addListener(), typically using boost::bind() to bind a member
function of some specific listener-class instance.

During normal operation, components call queueEvent(someEvent), which
simply adds a copy of someEvent to the EventQueue's std::vector.

Once per frame, the controller calls pump(), which iterates through the
std::vector<Event>, passing each Event to the MySignal instance. When
done, it clears the vector.

> You used some generic approach or you made a specific
> "subscription" function for each type of notification?

Heh -- our app is a hybrid of C++ and Python. We use Boost.Python's
convenient dict wrapper to embed a Python dict in our Event object. So
you can instantiate an Event (and call queueEvent() with it) in either
Python or C++, and any such caller can embed any information it wants in
the Event.

I realize there's a great controversy raging about free-form events vs.
a rigid event hierarchy. Without jumping on a soapbox here, I'll just
say that the free-form model works well for us. It does allow us to
capture Event objects by copying. If we used polymorphic Events, I guess
we could have used a std::vector< boost::shared_ptr<Event> > instead.
Anyway, we found the generic approach simple and manageable.


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