Mercurial > MadButterfly
comparison src/observer.c @ 125:1c1f28c124c9
Postponding free request when a subject is in subject_notify
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Tue, 16 Sep 2008 15:31:49 +0800 |
parents | a6763f080da5 |
children | 55f2c6402c81 |
comparison
equal
deleted
inserted
replaced
124:ad5ab8e61c2b | 125:1c1f28c124c9 |
---|---|
16 STAILQ_INIT(subject->observers); | 16 STAILQ_INIT(subject->observers); |
17 | 17 |
18 return subject; | 18 return subject; |
19 } | 19 } |
20 | 20 |
21 /*! | |
22 * \todo Keep ob_factory following subject objects. | |
23 */ | |
21 void subject_free(ob_factory_t *factory, subject_t *subject) { | 24 void subject_free(ob_factory_t *factory, subject_t *subject) { |
22 observer_t *observer; | 25 observer_t *observer; |
23 | 26 |
27 if(subject->flags & SUBF_BUSY) { | |
28 /* Postpond the request until busy status been stoped. | |
29 * SUBF_BUSY means in subject_notify(). | |
30 */ | |
31 subject->flags |= SUBF_FREE; | |
32 return; | |
33 } | |
34 | |
24 while((observer = STAILQ_HEAD(subject->observers))) { | 35 while((observer = STAILQ_HEAD(subject->observers))) { |
25 STAILQ_REMOVE(subject->observers, observer_t, next, observer); | 36 STAILQ_REMOVE(subject->observers, observer_t, next, observer); |
26 factory->observer_free(factory, observer); | 37 factory->observer_free(factory, observer); |
27 } | 38 } |
28 factory->subject_free(factory, subject); | 39 factory->subject_free(factory, subject); |
29 } | 40 } |
30 | 41 |
31 | 42 |
32 void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) { | 43 void subject_notify(ob_factory_t *factory, subject_t *subject, event_t *evt) { |
33 observer_t *observer; | 44 observer_t *observer; |
45 | |
46 /*! | |
47 * \note What is happend when the subject is freed by observer? | |
48 * Postponding the request of free until notification | |
49 * been finished. (\ref SUBF_BUSY / \ref SUBF_FREE) | |
50 */ | |
51 subject->flags |= SUBF_BUSY; | |
34 | 52 |
35 evt->tgt = subject; | 53 evt->tgt = subject; |
36 while(subject) { | 54 while(subject) { |
37 evt->cur_tgt = subject->obj; | 55 evt->cur_tgt = subject->obj; |
38 for(observer = STAILQ_HEAD(subject->observers); | 56 for(observer = STAILQ_HEAD(subject->observers); |
44 if(subject->flags & SUBF_STOP_PROPAGATE) | 62 if(subject->flags & SUBF_STOP_PROPAGATE) |
45 break; | 63 break; |
46 | 64 |
47 subject = factory->get_parent_subject(factory, subject); | 65 subject = factory->get_parent_subject(factory, subject); |
48 } | 66 } |
67 | |
68 subject->flags &= ~SUBF_BUSY; | |
69 if(subject->flags & SUBF_FREE) | |
70 subject_free(factory, subject); | |
49 } | 71 } |
50 | 72 |
51 observer_t *subject_add_observer(ob_factory_t *factory, | 73 observer_t *subject_add_observer(ob_factory_t *factory, |
52 subject_t *subject, | 74 subject_t *subject, |
53 evt_handler hdr, void *arg) { | 75 evt_handler hdr, void *arg) { |