From a4e781298c7e884506f0aa6efeea8efb84e3ee00 Mon Sep 17 00:00:00 2001 From: fluxgen Date: Mon, 8 Sep 2003 15:38:46 +0000 Subject: fixed dead observer while notifying --- src/FbTk/Subject.cc | 24 +++++++++++++++++++----- src/FbTk/Subject.hh | 5 ++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/FbTk/Subject.cc b/src/FbTk/Subject.cc index 961d6a8..a575cfd 100644 --- a/src/FbTk/Subject.cc +++ b/src/FbTk/Subject.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Subject.cc,v 1.2 2003/08/19 16:03:26 fluxgen Exp $ +// $Id: Subject.cc,v 1.3 2003/09/08 15:38:46 fluxgen Exp $ #include "Subject.hh" #include "Observer.hh" @@ -31,7 +31,7 @@ namespace FbTk { Subject::SubjectList Subject::s_subjectlist; -Subject::Subject() { +Subject::Subject():m_notify_mode(false) { s_subjectlist.push_back(this); } @@ -48,14 +48,28 @@ void Subject::attach(Observer *obj) { } void Subject::detach(Observer *obj) { - m_observerlist.erase(std::remove(m_observerlist.begin(), - m_observerlist.end(), obj), - m_observerlist.end()); + if (m_notify_mode) + m_dead_observers.push_back(obj); + else { + m_observerlist.erase(std::remove(m_observerlist.begin(), + m_observerlist.end(), obj), + m_observerlist.end()); + } } void Subject::notify() { + m_notify_mode = true; std::for_each(m_observerlist.begin(), m_observerlist.end(), std::bind2nd(std::mem_fun(&Observer::update), this)); + m_notify_mode = false; + + // remove dead observers + if (m_dead_observers.size()) { + std::for_each(m_dead_observers.begin(), + m_dead_observers.end(), + std::bind1st(std::mem_fun(&Subject::detach), this)); + m_dead_observers.clear(); + } } void Subject::removeObserver(Observer *obj) { diff --git a/src/FbTk/Subject.hh b/src/FbTk/Subject.hh index ca8d142..000fc2e 100644 --- a/src/FbTk/Subject.hh +++ b/src/FbTk/Subject.hh @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// $Id: Subject.hh,v 1.3 2003/08/19 16:03:52 fluxgen Exp $ +// $Id: Subject.hh,v 1.4 2003/09/08 15:38:46 fluxgen Exp $ #ifndef FBTK_SUBJECT_HH #define FBTK_SUBJECT_HH @@ -44,8 +44,11 @@ public: void notify(); static void removeObserver(Observer *obs); private: + bool m_notify_mode; + typedef std::list ObserverList; ObserverList m_observerlist; + ObserverList m_dead_observers; typedef std::list SubjectList; static SubjectList s_subjectlist; -- cgit v0.11.2