fixed dead observer while notifying
fluxgen fluxgen
2 files changed,
23 insertions(+),
6 deletions(-)
M
src/FbTk/Subject.cc
→
src/FbTk/Subject.cc
@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// 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 @@ m_observerlist.end());
} 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) {
M
src/FbTk/Subject.hh
→
src/FbTk/Subject.hh
@@ -19,7 +19,7 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// 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 @@ /// notify all attached observers
void notify(); static void removeObserver(Observer *obs); private: + bool m_notify_mode; + typedef std::list<Observer *> ObserverList; ObserverList m_observerlist; + ObserverList m_dead_observers; typedef std::list<Subject *> SubjectList; static SubjectList s_subjectlist;