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