annotate src/observer.c @ 73:9ab15ebc9061

Observer for mouse events
author Thinker K.F. Li <thinker@branda.to>
date Mon, 18 Aug 2008 01:59:26 +0800
parents
children 3e3e074120a7
rev   line source
73
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
1 #include <stdio.h>
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
2 #include "redraw_man.h"
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
3 #include "observer.h"
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
4 #include "tools.h"
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
5
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
6 subject_t *subject_new(ob_factory_t *factory, void *obj, int obj_type) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
7 subject_t *subject;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
8
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
9 subject = factory->subject_alloc(factory);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
10 if(subject == NULL)
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
11 return NULL;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
12
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
13 subject->obj = obj;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
14 subject->obj_type = obj_type;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
15 subject->flags = 0;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
16 STAILQ_INIT(subject->observers);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
17
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
18 return subject;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
19 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
20
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
21 void subject_free(ob_factory_t *factory, subject_t *subject) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
22 observer_t *observer;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
23
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
24 while((observer = STAILQ_HEAD(subject->observers))) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
25 STAILQ_REMOVE(subject->observers, observer_t, next, observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
26 factory->observer_free(factory, observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
27 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
28 factory->subject_free(factory, subject);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
29 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
30
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
31
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
32 void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
33 observer_t *observer;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
34
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
35 while(subject) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
36 for(observer = STAILQ_HEAD(subject->observers);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
37 observer != NULL;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
38 observer = STAILQ_NEXT(observer_t, next, observer)) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
39 observer->hdr(evt, observer->arg);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
40 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
41
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
42 if(subject->flags & SUBF_STOP_PROPAGATE)
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
43 break;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
44
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
45 subject = factory->get_parent_subject(factory, subject);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
46 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
47 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
48
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
49 observer_t *subject_add_observer(ob_factory_t *factory,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
50 subject_t *subject,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
51 evt_handler hdr, void *arg) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
52 observer_t *observer;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
53
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
54 observer = factory->observer_alloc(factory);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
55 if(observer == NULL)
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
56 return NULL;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
57 observer->hdr = hdr;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
58 observer->arg = arg;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
59
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
60 STAILQ_INS_TAIL(subject->observers, observer_t, next, observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
61
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
62 return observer;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
63 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
64
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
65 void subject_remove_observer(ob_factory_t *factory,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
66 subject_t *subject,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
67 observer_t *observer) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
68 STAILQ_REMOVE(subject->observers, observer_t, next, observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
69 factory->observer_free(factory, observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
70 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
71
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
72 #ifdef UNITTEST
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
73
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
74 #include <CUnit/Basic.h>
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
75 #include <stdlib.h>
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
76
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
77 static subject_t *test_subject_alloc(ob_factory_t *factory) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
78 subject_t *subject;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
79
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
80 subject = (subject_t *)malloc(sizeof(subject_t));
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
81 return subject;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
82 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
83
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
84 static void test_subject_free(ob_factory_t *factory, subject_t *subject) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
85 free(subject);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
86 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
87
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
88 static observer_t *test_observer_alloc(ob_factory_t *factory) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
89 observer_t *observer;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
90
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
91 observer = (observer_t *)malloc(sizeof(observer_t));
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
92 return observer;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
93 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
94
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
95 static void test_observer_free(ob_factory_t *factory, observer_t *observer) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
96 free(observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
97 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
98
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
99 static subject_t *test_get_parent_subject(ob_factory_t *factory,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
100 subject_t *subject) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
101 return NULL;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
102 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
103
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
104 static ob_factory_t test_factory = {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
105 test_subject_alloc,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
106 test_subject_free,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
107 test_observer_alloc,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
108 test_observer_free,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
109 test_get_parent_subject
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
110 };
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
111
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
112 static void handler(event_t *evt, void *arg) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
113 int *cnt = (int *)arg;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
114
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
115 CU_ASSERT(evt->type == EVT_MOUSE_OVER);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
116 (*cnt)++;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
117 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
118
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
119 void test_observer(void) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
120 subject_t *subject;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
121 observer_t *observer;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
122 event_t evt;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
123 int cnt = 0;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
124
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
125 subject = subject_new(&test_factory, NULL, 0);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
126 subject->flags |= SUBF_STOP_PROPAGATE;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
127 observer = subject_add_observer(&test_factory, subject,
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
128 handler, &cnt);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
129
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
130 evt.type = EVT_MOUSE_OVER;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
131 evt.tgt = NULL;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
132 evt.cur_tgt = NULL;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
133 subject_notify(&test_factory, subject, &evt);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
134 CU_ASSERT(cnt == 1);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
135
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
136 subject_remove_observer(&test_factory, subject, observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
137 subject_free(&test_factory, subject);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
138 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
139
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
140 CU_pSuite get_observer_suite(void) {
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
141 CU_pSuite suite;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
142
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
143 suite = CU_add_suite("Suite_observer", NULL, NULL);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
144 CU_ADD_TEST(suite, test_observer);
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
145
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
146 return suite;
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
147 }
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
148
9ab15ebc9061 Observer for mouse events
Thinker K.F. Li <thinker@branda.to>
parents:
diff changeset
149 #endif /* UNITTEST */