comparison src/observer.c @ 192:54fdc2a65242

Remove factory from observer APIs. - Save factory that used to new a subject as subject's attribute. - Get factory from subject himself instead of passing as an argument. - It make API of observer more simple and clean.
author Thinker K.F. Li <thinker@branda.to>
date Tue, 18 Nov 2008 21:42:30 +0800
parents 530bb7728546
children 45d9a1e2764d f9d507a3e1d9
comparison
equal deleted inserted replaced
191:18f8c3126cdb 192:54fdc2a65242
17 subject->obj = obj; 17 subject->obj = obj;
18 subject->obj_type = obj_type; 18 subject->obj_type = obj_type;
19 subject->flags = 0; 19 subject->flags = 0;
20 STAILQ_INIT(subject->observers); 20 STAILQ_INIT(subject->observers);
21 21
22 subject->factory = factory;
23
22 return subject; 24 return subject;
23 } 25 }
24 26
25 /*! 27 /*!
26 * \todo Keep ob_factory following subject objects. 28 * \todo Keep ob_factory following subject objects.
27 */ 29 */
28 void subject_free(ob_factory_t *factory, subject_t *subject) { 30 void subject_free(subject_t *subject) {
31 ob_factory_t *factory = subject->factory;
29 observer_t *observer; 32 observer_t *observer;
30 33
31 ASSERT(!(subject->flags & SUBF_FREE)); 34 ASSERT(!(subject->flags & SUBF_FREE));
32 if(subject->flags & SUBF_BUSY) { 35 if(subject->flags & SUBF_BUSY) {
33 /* Postpond the request until busy status been stoped. 36 /* Postpond the request until busy status been stoped.
43 } 46 }
44 factory->subject_free(factory, subject); 47 factory->subject_free(factory, subject);
45 } 48 }
46 49
47 50
48 void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) { 51 void subject_notify(subject_t *subject, event_t *evt) {
52 ob_factory_t *factory = subject->factory;
49 observer_t *observer; 53 observer_t *observer;
50 54
51 evt->tgt = subject; 55 evt->tgt = subject;
52 while(subject) { 56 while(subject) {
53 /*! 57 /*!
64 observer->hdr(evt, observer->arg); 68 observer->hdr(evt, observer->arg);
65 } 69 }
66 70
67 subject->flags &= ~SUBF_BUSY; 71 subject->flags &= ~SUBF_BUSY;
68 if(subject->flags & SUBF_FREE) 72 if(subject->flags & SUBF_FREE)
69 subject_free(factory, subject); 73 subject_free(subject);
70 74
71 if(subject->flags & SUBF_STOP_PROPAGATE) 75 if(subject->flags & SUBF_STOP_PROPAGATE)
72 break; 76 break;
73 77
74 subject = factory->get_parent_subject(factory, subject); 78 subject = factory->get_parent_subject(factory, subject);
75 } 79 }
76 80
77 } 81 }
78 82
79 observer_t *subject_add_observer(ob_factory_t *factory, 83 observer_t *subject_add_observer(subject_t *subject,
80 subject_t *subject,
81 evt_handler hdr, void *arg) { 84 evt_handler hdr, void *arg) {
85 ob_factory_t *factory = subject->factory;
82 observer_t *observer; 86 observer_t *observer;
83 87
84 observer = factory->observer_alloc(factory); 88 observer = factory->observer_alloc(factory);
85 if(observer == NULL) 89 if(observer == NULL)
86 return NULL; 90 return NULL;
90 STAILQ_INS_TAIL(subject->observers, observer_t, next, observer); 94 STAILQ_INS_TAIL(subject->observers, observer_t, next, observer);
91 95
92 return observer; 96 return observer;
93 } 97 }
94 98
95 void subject_remove_observer(ob_factory_t *factory, 99 void subject_remove_observer(subject_t *subject,
96 subject_t *subject,
97 observer_t *observer) { 100 observer_t *observer) {
101 ob_factory_t *factory = subject->factory;
102
98 STAILQ_REMOVE(subject->observers, observer_t, next, observer); 103 STAILQ_REMOVE(subject->observers, observer_t, next, observer);
99 factory->observer_free(factory, observer); 104 factory->observer_free(factory, observer);
100 } 105 }
101 106
102 #ifdef UNITTEST 107 #ifdef UNITTEST
152 event_t evt; 157 event_t evt;
153 int cnt = 0; 158 int cnt = 0;
154 159
155 subject = subject_new(&test_factory, NULL, 0); 160 subject = subject_new(&test_factory, NULL, 0);
156 subject->flags |= SUBF_STOP_PROPAGATE; 161 subject->flags |= SUBF_STOP_PROPAGATE;
157 observer[0] = subject_add_observer(&test_factory, subject, 162 observer[0] = subject_add_observer(subject, handler, &cnt);
158 handler, &cnt); 163 observer[1] = subject_add_observer(subject, handler, &cnt);
159 observer[1] = subject_add_observer(&test_factory, subject,
160 handler, &cnt);
161 164
162 evt.type = EVT_MOUSE_OUT; 165 evt.type = EVT_MOUSE_OUT;
163 evt.tgt = NULL; 166 evt.tgt = NULL;
164 evt.cur_tgt = NULL; 167 evt.cur_tgt = NULL;
165 subject_notify(&test_factory, subject, &evt); 168 subject_notify(subject, &evt);
166 CU_ASSERT(cnt == 2); 169 CU_ASSERT(cnt == 2);
167 170
168 subject_remove_observer(&test_factory, subject, observer[0]); 171 subject_remove_observer(subject, observer[0]);
169 subject_remove_observer(&test_factory, subject, observer[1]); 172 subject_remove_observer(subject, observer[1]);
170 subject_free(&test_factory, subject); 173 subject_free(subject);
171 } 174 }
172 175
173 CU_pSuite get_observer_suite(void) { 176 CU_pSuite get_observer_suite(void) {
174 CU_pSuite suite; 177 CU_pSuite suite;
175 178