/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2010 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * Notification.cpp * * Created on: Dec 1, 2011 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "CodePatterns/MemDebug.hpp" #include #include "CodePatterns/Observer/Notification.hpp" #include "CodePatterns/Observer/Observer.hpp" #include "CodePatterns/Observer/ObserverLog.hpp" Notification::Notification(size_t _channelno) : channelno(_channelno) {} Notification::~Notification(){} void Notification::addObserver(Observer *target, const int priority) { boost::recursive_mutex::scoped_lock guard(TargetsLock); targets.insert( std::make_pair(priority, target) ); } void Notification::removeObserver(Observer *target) { boost::recursive_mutex::scoped_lock guard(TargetsLock); for(targets_t::iterator iter=targets.begin();iter!=targets.end();) { if((*iter).second == target) { targets.erase(iter++); } else { ++iter; } } } void Notification::notifyAll(Observable * const publisher) { boost::recursive_mutex::scoped_lock guard(TargetsLock); // copy such that signOff() within receiving update() does not affect iterating // this is because within the same thread and with the update() signOff() may be // called and when executed it modifies targets targets_t temp_targets = targets; for(targets_t::iterator it=temp_targets.begin(); it!=temp_targets.end();++it){ #ifdef LOG_OBSERVER observerLog().addMessage() << "-> Sending update from " << observerLog().getName(publisher) << " for channel " << channelno << " to " << observerLog().getName((*it).second); #endif (*it).second->recieveNotification(publisher,this); } } void Notification::subjectKilled(Observable * const publisher) { boost::recursive_mutex::scoped_lock guard(TargetsLock); // copy such that signOff() within receiving subjectKilled() does not affect iterating // this is because within the same thread and with the subjectKilled() signOff() may be // called and when executed it modifies targets for(targets_t::iterator it=targets.begin(); !targets.empty();it=targets.begin()){ Observer *target = (*it).second; const size_t prior_size = targets.size(); target->subjectKilled(publisher); if (prior_size == targets.size()) targets.erase(it); } }