|
| ObserverSet () |
|
| ~ObserverSet () |
|
template<typename EventIDSingletonType , typename ReceiverType , typename ReceiverOrBaseType , typename ReturnType > |
Observer * | add (Observable &sender, const EventIDSingletonType &eventId, ReceiverType &receiver, ReturnType(ReceiverOrBaseType::*func)(), bool threaded) |
|
template<typename EventIDSingletonType , typename ReceiverType , typename ReceiverOrBaseType , typename ReturnType > |
Observer * | add (Observable &sender, const EventIDSingletonType &eventId, ReceiverType &receiver, ReturnType(ReceiverOrBaseType::*func)(), ObserverThreadType threaded=UnthreadedObserver) |
|
template<typename EventIDSingletonType , typename ReceiverEventType , typename ReceiverType , typename ReceiverOrBaseType , typename ReturnType > |
Observer * | add (Observable &sender, const EventIDSingletonType &eventId, ReceiverType &receiver, ReturnType(ReceiverOrBaseType::*func)(const ReceiverEventType &), bool threaded) |
|
template<typename EventIDSingletonType , typename ReceiverEventType , typename ReceiverType , typename ReceiverOrBaseType , typename ReturnType > |
Observer * | add (Observable &sender, const EventIDSingletonType &eventId, ReceiverType &receiver, ReturnType(ReceiverOrBaseType::*func)(const ReceiverEventType &), ObserverThreadType threaded=UnthreadedObserver) |
|
void | add (Observer *observer) |
|
void | clear () |
|
bool | empty () const |
|
Observer * | operator[] (int i) |
|
bool | remove (Observable &subject) |
|
bool | remove (Observable &subject, const EventID &eventID) |
|
void | remove (Observer *observer) |
|
unsigned | size () const |
|
This class is useful for managing the lifetime of observers where the observers must be deleted when the receiving object is deleted. Clients add observers they dynamically allocate using the add() member function. If observers need to be deleted individually or before the container is deleted, the remove() member functions allows clients to destroy observers or just take back ownership.
The most common and useful way to use an ObserverSet is to hold an instance of one in the object that will receive the event notifications. By making the instance a member of the receiving object, the ObserverSet will be automatically deleted when the receiver is. Since the ObserverSet also deletes all observers it contains when it is itself deleted, this means that the lifetime of all observers added to such a set is handled automatically. Thus, if either the subject being observed or the receiver of the notifications is deleted, the observer will also be automatically deleted. This frees up developers from having to keep track of the order of destruction between observers, the things they are observing and the objects receiving the event notifications.
The one restriction is that all observers added to an ObserverSet must be dynamically allocated. This is normally easy, since by far the most common way to create an observer is with a call to one of the templated add() functions.
Observer * add |
( |
Observable & |
sender, |
|
|
const EventIDSingletonType & |
eventId, |
|
|
ReceiverType & |
receiver, |
|
|
ReturnType(ReceiverOrBaseType::*)(const ReceiverEventType &) |
func, |
|
|
ObserverThreadType |
threaded = UnthreadedObserver |
|
) |
| |
|
inline |
- Template Parameters
-
EventIDSingletonType | This is the type of the EventID subclass to be caught. In addition to this being a subclass of EventID, it must also have a typedef for EventType which specifies what event class is associated with it. In almost all cases, this is all handled transparently by making your event class derive from ObservableEventType and by calling that event type's eventID() function to provide the EventIDSingletonType needed for the second parameter to this function. |
ReceiverEventType | This is the type for the receiver's parameter. It must be the same as EventIDSingletonType::EventType or be a base class of it. Failure to meet this requirement will result in the compiler discarding the templated add() functions from the possible set of matching functions, leaving only add(Observer*) as a candidate. The compiler will then complain and may include a note that only add(Observer*) can be found. In reality, it just means the ReceiverEventType did not match the sender event type. Note also that the other function template overload for add() provides support for receiver functions which take no parameter at all. |
ReceiverType | The class type of the receiving object. This can be any class, but not a free function (it is trivial to wrap a free function inside a class object's member function). |
ReceiverOrBaseType | This will be the class type whose member function will be called. In most cases, it will be the same as ReceiverType, but if the function to be called comes from a base class of ReceiverType then it will be different. We have to use a different template parameter for this to support such cases and still get automatic type deduction when calling the function without the template arguments being specified. |
ReturnType | The return type of the receiver's member function. This is only used to allow arbitrary return types. The actual return type or return value is not used. |
- Parameters
-
sender | The object from which events are to be observed. |
eventId | The specific EventID to respond to. |
receiver | The object be notified of the event. |
func | The member function to be called on the receiver. |
threaded | If true, a threaded observer will be created. A threaded observer overrides Observer::updateInObserverThread() instead of Observer::update() to ensure that if the notification happens in a different thread to that in which the observer was created, the observer will be notified through its event loop rather than via a direct function call. The sender thread is blocked until the observer finishes handling the event notification. |
Instances of this member function template will forward a specified event type from an Observable object to a designated receiver. The receiver can be of any class type. The event is forwarded to a designated non-const member function of the receiver, where that member function takes a single parameter of a type that matches the event being sent. The other template overload of add() allows for receiver member functions which take no parameters. In either case, the return value of the receiving function can be any type and is not used in any way.
Checks to ensure the receiver can accept the specified event type are all done at compile time. If the receiver member function's parameter does not match the event type, the compiler will complain that it could not find a match for the call to add(). It may claim that the only candidate is the non-template add() function taking only a single Observer parameter, but this is because none of the templated versions matched and the C++ rules allow non-instantiable template functions to be silently discarded from the set of potentially matching functions.
For observers where threaded is false, the update() member function is overridden. If, however, threaded is true, then the updateInObserverThread() member function is overridden instead.
- Returns
- A dynamically allocated Observer object which will have already been added to the observer set. The returned object should be destroyed by calling its destroy() member function, not by using operator
delete
on it.