1ggAddObserver(3) GGI ggAddObserver(3)
2
3
4
6 ggAddObserver, ggDelObserver, ggNotifyObservers, ggClearPublisher :
7 Simple observer framework
8
10 #include <ggi/gg.h>
11
12 typedef int (ggfunc_observer_update)(void *arg, int flag, void *data);
13
14 struct gg_observer {
15 ggfunc_observer_update *update;
16 void *arg;
17 GG_LIST_ENTRY(gg_observer) _others;
18 };
19
20 struct gg_publisher {
21 GG_LIST_HEAD(gg_observer_list, gg_observer) observers;
22 };
23
24 #define INIT_PUBLISHER(pub) GG_LIST_INIT(&((pub)->observers))
25
26 struct gg_observer * ggAddObserver(struct gg_publisher *,
27 ggfunc_observer_update *, void *);
28
29 void ggDelObserver(struct gg_observer *);
30
31 void ggNotifyObservers(struct gg_publisher *, int, void *);
32
33 void ggClearPublisher(struct gg_publisher *);
34
35
37 The observer pattern is very useful and commonly found in many software
38 packages, even if not explicitly called that way. The problem is that
39 every different software will often use a particular implementation of
40 this pattern, depending on a specific use-case. So usually everybody
41 prefers to roll its own. LibGG observers are defined as part of the
42 forth-coming api infrastructure, as light-weight cooperation model
43 between libraries. The model is very simple:
44
45 struct gg_publisher defines a channel on which observers can be regis‐
46 tered. An observer is simply an opaque value and a callback receiving
47 that value as first argument, a flag, and an opaque channel-specific
48 message. The idea is that if you known the observable you're listening
49 on, you know the semantics behind the flag and message. When the
50 observable is triggered, all observers' callbacks will be fired.
51
52 ggAddObserver registers a new observer on a publisher.
53
54 ggDelObserver unregisters the given observer from its publisher and
55 frees it.
56
57 ggNotifyObservers triggers all observers update functions for that pub‐
58 lisher. The flag and message will be given to the observers' update
59 callbacks. An observer Bmust not* call ggDelObserver on itself in the
60 update function to unregister. Instead it must return a non-zero value.
61
62 ggClearPublisher frees all observers registered on the publisher.
63 If at least one is left, then there is probably a logical error
64 in the observer code, since it must already have been notified
65 somehow of the publisher going down, and unregistered all call‐
66 backs before.
67
68
70 ggAddObserver returns a newly constructed observer hook. Normally, the
71 caller will keep a reference to it to call if he needs to call ggDelOb‐
72 server later.
73
75 #include <ggi/gg.h>
76 #include <stdio.h>
77
78 int update(void* o, int f, void *d) {
79 printf("update called for observer %p, flag=%i, data=%p\n", o, f ,d);
80 if (o == 1) {
81 return 1; /* unregister */
82 }
83 return 0;
84 }
85
86 int main() {
87 struct gg_publisher pub;
88 struct gg_observer *o1, *o2;
89
90 INIT_PUBLISHER(&pub);
91
92 o1 = ggAddObserver(&pub, update, (void*)1);
93 o2 = ggAddObserver(&pub, update, (void*)2);
94
95 ggNotifyObservers(&pub, 0, NULL);
96 ggNotifyObservers(&pub, 1, NULL);
97
98 ggClearPublisher(&pub);
99
100 return 0;
101 }
102
103
104
105
106libgg-1.0.x 2005-08-26 ggAddObserver(3)