Man Linux: Main Page and Category List

NAME

       ggAddObserver,  ggDelObserver,  ggNotifyObservers,  ggClearPublisher  -
       Simple observer framework

SYNOPSIS

       #include <ggi/gg.h>

       typedef int (ggfunc_observer_update)(void *arg, int flag, void *data);

       struct gg_observer {
             ggfunc_observer_update     *update;
             void                       *arg;
             GG_LIST_ENTRY(gg_observer) _others;
       };

       struct gg_publisher {
             GG_LIST_HEAD(gg_observer_list,  gg_observer)  observers;
       };

       #define INIT_PUBLISHER(pub) GG_LIST_INIT(&((pub)->observers))

       struct gg_observer * ggAddObserver(struct gg_publisher *,
                                          ggfunc_observer_update *, void *);

       void ggDelObserver(struct gg_observer *);

       void ggNotifyObservers(struct gg_publisher *, int, void *);

       void ggClearPublisher(struct gg_publisher *);

DESCRIPTION

       The observer pattern is very useful and commonly found in many software
       packages,  even if not explicitly called that way.  The problem is that
       every different software will often use a particular implementation  of
       this  pattern,  depending on a specific use-case.  So usually everybody
       prefers to roll its own.  LibGG observers are defined as  part  of  the
       forth-coming  api  infrastructure,  as  light-weight  cooperation model
       between libraries. The model is very simple:

       struct gg_publisher  defines  a  channel  on  which  observers  can  be
       registered.  An  observer  is  simply  an  opaque  value and a callback
       receiving that value as first argument, a flag, and an opaque  channel-
       specific  message.  The idea is that if you known the observable you’re
       listening on, you know the semantics behind the flag and message.  When
       the observable is triggered, all observers’ callbacks will be fired.

       ggAddObserver registers a new observer on a publisher.

       ggDelObserver  unregisters  the  given  observer from its publisher and
       frees it.

       ggNotifyObservers triggers all  observers  update  functions  for  that
       publisher.  The flag and message will be given to the observers’ update
       callbacks. An observer *must not* call ggDelObserver on itself  in  the
       update function to unregister. Instead it must return a non-zero value.

       ggClearPublisher frees all observers registered on the publisher.
              If at least one is left, then there is probably a logical  error
              in  the  observer code, since it must already have been notified
              somehow of  the  publisher  going  down,  and  unregistered  all
              callbacks before.

RETURN VALUES

       ggAddObserver  returns a newly constructed observer hook. Normally, the
       caller will keep a reference  to  it  to  call  if  he  needs  to  call
       ggDelObserver later.

EXAMPLE

       #include <ggi/gg.h>
       #include <stdio.h>

       int update(void* o, int f, void *d) {
           printf("update called for observer %p, flag=%i, data=%p\n", o, f ,d);
           if (o == 1) {
              return 1; /* unregister */
           }
           return 0;
       }

       int main() {
           struct gg_publisher pub;
           struct gg_observer *o1, *o2;

           INIT_PUBLISHER(&pub);

           o1 = ggAddObserver(&pub, update, (void*)1);
           o2 = ggAddObserver(&pub, update, (void*)2);

           ggNotifyObservers(&pub, 0, NULL);
           ggNotifyObservers(&pub, 1, NULL);

           ggClearPublisher(&pub);

           return 0;
       }