jacob navia
3/29/2011 6:13:00 AM
I think it is easier to understand when you read the doc. Here is
an excerpt of the essential parts of the doc:
The observer interface
---------------------
When a container changes its state, specifically when elements are added
or removed, it is sometimes necessary to update relationships that can
be very complex. The observer interface is designed to simplify this
operation by allowing the container to emit notifications to other
objects that have previously manifested interest in receiving them by
subscribing to them.
This interface then, establishes a relationship between two software
entities:
1. The container, that is responsible for sending the notifications when
appropriate
2. The receiver, that is an unspecified object represented by its
callback function that is called when a change occurs that matches the
notifications specified in the subscription.
Since this relationship needs both objects, it will be finished when
either object goes out of scope or breaks the relationship for whatever
reason. Both objects can unsubscribe (terminate) their relationship.
The interface
-------------
typedef void (*ObserverFunction)(void *ObservedObject, unsigned
Operation, void *ExtraInfo[]);
typedef struct tagObserverInterface { int (*Subscribe)(void
*ObservedObject,ObserverFunction callback, unsigned Operations);
int (*Notify)(void *ObservedObject,unsigned operation,void
*ExtraInfo1,void *ExtraInfo2);
size_t (*Unsubscribe)(void *ObservedObject,ObserverFunction callback);
extern ObserverInterface iObserver;
ObserverFunction
typedef void (*ObserverFunction)(void *ObservedObject, unsigned
Operation, void *ExtraInfo[]);
Description:
This function will be called by the interface when a notification is
received for an observed object. The call happens after al arguments
have been processed by the actual work of the function and they are in a
consistent state. For the callbacks that are called when an object is
deleted from a container the call happens before the call to free() and
before any call to a destructor (if any) is done.
Arguments:
1. ObservedObject: Specifies the object that sends the notification,
i.e. the container that has the subscription. It is assumed that this
container conforms to the iGeneric interface.
2. Operation: The operation that provoked the notification. Since it is
possible to subscribe to several operations with only one callback
function, this argument allows the callback to discriminate between the
operation notifications.
3. ExtraInfo: This argument is specific to each operation and conveys
further infor- mation1 for each operation.
None of the arguments will be ever NULL or zero.
Subscribe
int (*Subscribe)(void *ObservedObject, ObserverFunction callback,
unsigned Operations);
Description:
This function establishes the relationship between the observed object
(argument 1) and the observer, represented by its callback (argument 2).
The third argument establishes which operations are to be observed. This
operation performs an allocation to register the relationship in the
observer interface tables, therefore it can fail with an out of memory
condition.
Notify
int (*Notify)(void *ObservedObject,unsigned Operation, void
*ExtraInfo1,void *ExtraInfo2);
Description:
This function will be used by the container to send a message to the
receiver callback. The arguments correspond roughly to the arguments the
callback func- tion will receive. This function will call all the
objects that are observing ObservedObject and that have subscribed to
the operation specified in the Operation argument. This implies a search
through the observer interface table, and possibly several calls, making
this function quite expensive. The time needed is roughly proportional
to the number of registered callbacks and the complexity of the
callbacks themselves.
Unsubscribe
size_t (*Unsubscribe)(void *ObservedObject, ObserverFunction callback);
Description:
This function breaks the relationship between the observed object and
the observer. There are several combinations of both arguments:
? The ObservedObject argument is NULL . This means that the callback
object wants to break its relationship to all objects it is observing.
The observer interface will remove all relationships that contain this
callback from its tables.
? The callback argument is NULL . This means that the given
ObservedObject is going out of scope and wants to break all
relationships to all its observers. The interface removes from its
tables all relationships that have this object as the observed object.
This happens normally immediately after the notification FINALIZE is sent.
? If both callback and ObservedObject are non NULL , only the matching
relationships will be removed from the tables.