73
|
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
|
77
|
35 evt->tgt = subject;
|
73
|
36 while(subject) {
|
77
|
37 evt->cur_tgt = subject->obj;
|
73
|
38 for(observer = STAILQ_HEAD(subject->observers);
|
|
39 observer != NULL;
|
|
40 observer = STAILQ_NEXT(observer_t, next, observer)) {
|
|
41 observer->hdr(evt, observer->arg);
|
|
42 }
|
|
43
|
|
44 if(subject->flags & SUBF_STOP_PROPAGATE)
|
|
45 break;
|
|
46
|
|
47 subject = factory->get_parent_subject(factory, subject);
|
|
48 }
|
|
49 }
|
|
50
|
|
51 observer_t *subject_add_observer(ob_factory_t *factory,
|
|
52 subject_t *subject,
|
|
53 evt_handler hdr, void *arg) {
|
|
54 observer_t *observer;
|
|
55
|
|
56 observer = factory->observer_alloc(factory);
|
|
57 if(observer == NULL)
|
|
58 return NULL;
|
|
59 observer->hdr = hdr;
|
|
60 observer->arg = arg;
|
|
61
|
|
62 STAILQ_INS_TAIL(subject->observers, observer_t, next, observer);
|
|
63
|
|
64 return observer;
|
|
65 }
|
|
66
|
|
67 void subject_remove_observer(ob_factory_t *factory,
|
|
68 subject_t *subject,
|
|
69 observer_t *observer) {
|
|
70 STAILQ_REMOVE(subject->observers, observer_t, next, observer);
|
|
71 factory->observer_free(factory, observer);
|
|
72 }
|
|
73
|
|
74 #ifdef UNITTEST
|
|
75
|
|
76 #include <CUnit/Basic.h>
|
|
77 #include <stdlib.h>
|
|
78
|
|
79 static subject_t *test_subject_alloc(ob_factory_t *factory) {
|
|
80 subject_t *subject;
|
|
81
|
|
82 subject = (subject_t *)malloc(sizeof(subject_t));
|
|
83 return subject;
|
|
84 }
|
|
85
|
|
86 static void test_subject_free(ob_factory_t *factory, subject_t *subject) {
|
|
87 free(subject);
|
|
88 }
|
|
89
|
|
90 static observer_t *test_observer_alloc(ob_factory_t *factory) {
|
|
91 observer_t *observer;
|
|
92
|
|
93 observer = (observer_t *)malloc(sizeof(observer_t));
|
|
94 return observer;
|
|
95 }
|
|
96
|
|
97 static void test_observer_free(ob_factory_t *factory, observer_t *observer) {
|
|
98 free(observer);
|
|
99 }
|
|
100
|
|
101 static subject_t *test_get_parent_subject(ob_factory_t *factory,
|
|
102 subject_t *subject) {
|
|
103 return NULL;
|
|
104 }
|
|
105
|
|
106 static ob_factory_t test_factory = {
|
|
107 test_subject_alloc,
|
|
108 test_subject_free,
|
|
109 test_observer_alloc,
|
|
110 test_observer_free,
|
|
111 test_get_parent_subject
|
|
112 };
|
|
113
|
|
114 static void handler(event_t *evt, void *arg) {
|
|
115 int *cnt = (int *)arg;
|
|
116
|
74
|
117 CU_ASSERT(evt->type == EVT_MOUSE_OUT);
|
73
|
118 (*cnt)++;
|
|
119 }
|
|
120
|
|
121 void test_observer(void) {
|
|
122 subject_t *subject;
|
74
|
123 observer_t *observer[2];
|
73
|
124 event_t evt;
|
|
125 int cnt = 0;
|
|
126
|
|
127 subject = subject_new(&test_factory, NULL, 0);
|
|
128 subject->flags |= SUBF_STOP_PROPAGATE;
|
74
|
129 observer[0] = subject_add_observer(&test_factory, subject,
|
|
130 handler, &cnt);
|
|
131 observer[1] = subject_add_observer(&test_factory, subject,
|
|
132 handler, &cnt);
|
73
|
133
|
74
|
134 evt.type = EVT_MOUSE_OUT;
|
73
|
135 evt.tgt = NULL;
|
|
136 evt.cur_tgt = NULL;
|
|
137 subject_notify(&test_factory, subject, &evt);
|
74
|
138 CU_ASSERT(cnt == 2);
|
73
|
139
|
74
|
140 subject_remove_observer(&test_factory, subject, observer[0]);
|
|
141 subject_remove_observer(&test_factory, subject, observer[1]);
|
73
|
142 subject_free(&test_factory, subject);
|
|
143 }
|
|
144
|
|
145 CU_pSuite get_observer_suite(void) {
|
|
146 CU_pSuite suite;
|
|
147
|
|
148 suite = CU_add_suite("Suite_observer", NULL, NULL);
|
|
149 CU_ADD_TEST(suite, test_observer);
|
|
150
|
|
151 return suite;
|
|
152 }
|
|
153
|
|
154 #endif /* UNITTEST */
|