source: src/Observer/Notification.cpp@ 9e619e

Last change on this file since 9e619e was 454bc54, checked in by Frederik Heber <heber@…>, 10 years ago

Added new pattern ObservedValue, contrary to Cacheable.

  • essentially updates immediately and caches a value for off-line use, safe- guard with mutexes.
  • added unit test for ObservedValue.
  • factored threeNumbers stub out of CacheableUnitTest, also used the stub in ObservedValueUnitTest.
  • we may now signOn() to Notification with a priority.
  • Cacheable can also update now via notification channels not just for global updates.
  • Observable can now also instantiate the channels directly if given a list. This was necessary as Cacheable or ObservedValue are instantiated in the constructor, too, and if listening to channels, these must already be present.
  • FIX: Channels::addChannels() used NDEBUG wrong way round.
  • ObservedValue::get() returns reference.
  • Property mode set to 100644
File size: 2.5 KB
RevLine 
[e2e035e]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * Notification.cpp
10 *
11 * Created on: Dec 1, 2011
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
[9b8fa4]20#include "CodePatterns/MemDebug.hpp"
[e2e035e]21
[454bc54]22#include <boost/thread/locks.hpp>
23
[9b8fa4]24#include "CodePatterns/Observer/Notification.hpp"
25#include "CodePatterns/Observer/Observer.hpp"
[f3d16a]26#include "CodePatterns/Observer/ObserverLog.hpp"
[e2e035e]27
28Notification::Notification(size_t _channelno) :
29 channelno(_channelno)
30{}
31
32Notification::~Notification(){}
33
[454bc54]34void Notification::addObserver(Observer *target, const int priority)
[e2e035e]35{
[454bc54]36 boost::recursive_mutex::scoped_lock guard(TargetsLock);
37 targets.insert( std::make_pair(priority, target) );
[e2e035e]38}
39
40void Notification::removeObserver(Observer *target)
41{
[454bc54]42 boost::recursive_mutex::scoped_lock guard(TargetsLock);
43 for(targets_t::iterator iter=targets.begin();iter!=targets.end();) {
44 if((*iter).second == target) {
45 targets.erase(iter++);
46 } else {
47 ++iter;
48 }
49 }
[e2e035e]50}
51
52void Notification::notifyAll(Observable * const publisher)
53{
[454bc54]54 boost::recursive_mutex::scoped_lock guard(TargetsLock);
55 // copy such that signOff() within receiving update() does not affect iterating
56 // this is because within the same thread and with the update() signOff() may be
57 // called and when executed it modifies targets
58 targets_t temp_targets = targets;
59 for(targets_t::iterator it=temp_targets.begin();
60 it!=temp_targets.end();++it){
[f3d16a]61#ifdef LOG_OBSERVER
62 observerLog().addMessage() << "-> Sending update from " << observerLog().getName(publisher)
63 << " for channel " << channelno
[454bc54]64 << " to " << observerLog().getName((*it).second);
[f3d16a]65#endif
[454bc54]66 (*it).second->recieveNotification(publisher,this);
[e2e035e]67 }
68}
[1c291d]69
70void Notification::subjectKilled(Observable * const publisher)
71{
[454bc54]72 boost::recursive_mutex::scoped_lock guard(TargetsLock);
73 // copy such that signOff() within receiving subjectKilled() does not affect iterating
74 // this is because within the same thread and with the subjectKilled() signOff() may be
75 // called and when executed it modifies targets
76 for(targets_t::iterator it=targets.begin();
77 !targets.empty();it=targets.begin()){
78 Observer *target = (*it).second;
79 const size_t prior_size = targets.size();
80 target->subjectKilled(publisher);
81 if (prior_size == targets.size())
82 targets.erase(it);
[1c291d]83 }
84}
Note: See TracBrowser for help on using the repository browser.