Reputation: 54113
Right now, in my game gui API, I have, for example, a MouseListener.
This is just an abstract class with methods. Right now, the way it is used is as follows:
Lets say I want a Widget to accept mouse listeners:
I create a vector of mouse listeners and provide add and remove functions to remove listeners. Every time an event happens, that Widget will call all the mouse listeners' method (ex: mouse down).
On the other side of things, you would have a class that implements MouseListener's methods.
The only problem I have with this system, is that, if the Listener gets destroyed, it has no way of notifying all the things it is listening to.
So I'd like a system where if either end gets destroyed, they both get notified and remove each other from each other as though they'd never been added.
I'd also like to do it so that every Listener (ex: MouseListener) inherit from Listener so that this functionality is easy for anyone who wants to create more elaborate Listener classes.
Any ideas on designing something like this would be appreciated. Thanks
A design that is, non boost, non c++0x, non auto garbage collected, non smart pointer.... Just plain old C++ 98 standard solution.
Upvotes: 0
Views: 108
Reputation: 6819
You can use boost::weak_ptr when any side of an association can be destroyed. In your case a widget would have a vector of weak_ptrs and each listener will be created as a boost::shared_ptr. when iterating over the vector you will try to lock the weak_ptr as a shared_ptr and use it if it has not beeen destroyed. Example from boost page that shows converting a weak_ptr into a shared_ptr is below
shared_ptr<int> p(new int(5));
weak_ptr<int> q(p);
// some time later
if(shared_ptr<int> r = q.lock())
{
// use *r
}
This design helps you break the association with a container and contained element easily without having a notification mechanism but rather at container iteration time.
Upvotes: 0
Reputation:
How do the things a listener is listening to (from now on called vocalizers) know about the listener? They store a pointer right?
If so I recommend giving the vocalizers a weak pointer to the listener. Once the listener destructs, the weak pointer will no longer be valid, so when the vocalizer attempts to notify the listener, it will see that and can remove the pointer from its list of things to notify.
The same can be done the other way too ( listeners can store weak pointers to vocalizers, although I don't see why you need this ).
You can implement your own weak and strong pointers, or you can use those in the c++0x standard library (available with gcc and vc++10)
Upvotes: 2
Reputation: 249153
Would you consider using something existing, such as Boost Signals2 or Qt?
Upvotes: 0