- Timestamp:
- Mar 18, 2013, 6:29:41 PM (13 years ago)
- Children:
- 3f30cc
- Parents:
- b9273a
- git-author:
- Frederik Heber <heber@…> (03/18/13 18:22:47)
- git-committer:
- Frederik Heber <heber@…> (03/18/13 18:29:41)
- Location:
- src
- Files:
-
- 7 edited
-
CodePatterns/Observer/Channels.hpp (modified) (3 diffs)
-
CodePatterns/Observer/Notification.hpp (modified) (3 diffs)
-
CodePatterns/Observer/Observable.hpp (modified) (1 diff)
-
Observer/Channels.cpp (modified) (3 diffs)
-
Observer/Notification.cpp (modified) (1 diff)
-
Observer/Observable.cpp (modified) (5 diffs)
-
Observer/unittests/ObserverUnitTest.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/CodePatterns/Observer/Channels.hpp
rb9273a r1c291d 18 18 #include "CodePatterns/Observer/defs.hpp" 19 19 20 class Observable; 21 class Relay; 22 20 23 /** Channels aggregate all possible Notifications of an Observable. 21 24 * … … 23 26 * visible to the outside only. 24 27 * 28 * \note Channels::subjectKilled() needs to be called by owning Observable. 29 * It is passed on to Notification such that Observer that have only signed 30 * on to single channel still know when their observable has died. 25 31 */ 26 32 class Channels { … … 38 44 39 45 private: 46 //! grant Observable access to notifyAll() and subjectKilled() 47 friend class Observable; 48 //!> grant Relay access to notifyAll() 49 friend class Relay; 50 51 /** Informs channel subscribers about imminent dstor call. 52 * 53 * This is meant to be called from Observable only. 54 * Channels and Notifications are strictly attached to an Observable. Hence, 55 * it makes no sense to inform them on their own. Especially, neither has 56 * any knowledge on the publisher. 57 * 58 * \param *publisher Observable about to be destroyed 59 */ 60 void subjectKilled(Observable * const publisher); 61 62 private: 40 63 typedef std::map< size_t, Notification_ptr> NotificationTypetoRefMap; 41 64 -
src/CodePatterns/Observer/Notification.hpp
rb9273a r1c291d 16 16 #include <set> 17 17 18 class Channels; 18 19 class Observable; 19 20 class Observer; … … 26 27 * with the usual OBSERVE() macro to generate both the specific and 27 28 * the global message of change. 29 * 30 * \note Notification::subjectKilled() needs to be called by owning Channels. 31 * We use the passed on Observable instance to let Observers that have only 32 * signed on to single channel know when their observable has died. 28 33 */ 29 34 class Notification { 30 //!> grant Observable access to notifyAll()31 friend class Observable;32 //!> grant Relay access to notifyAll()33 friend class Relay;34 35 public: 35 36 Notification(size_t _channelno); … … 43 44 void removeObserver(Observer *target); 44 45 46 private: 47 //!> grant Observable access to notifyAll() and subjectKilled() 48 friend class Observable; 49 //!> grant Channels access to notifyAll() and subjectKilled() 50 friend class Channels; 51 //!> grant Relay access to notifyAll() 52 friend class Relay; 53 45 54 void notifyAll(Observable * const publisher); 55 56 /** Informs channel subscribers about dstor call. 57 * 58 * This is meant to be called from Observable only. 59 * Channels and Notifications are strictly attached to an Observable. Hence, 60 * it makes no sense to inform them on their own. Especially, neither has 61 * any knowledge on the publisher. 62 * 63 * \param *publisher Observable about to be destroyed 64 */ 65 void subjectKilled(Observable * const publisher); 66 46 67 private: 47 std::set<Observer*> targets; 68 typedef std::set<Observer*> targets_t; 69 targets_t targets; 48 70 const size_t channelno; 49 71 }; -
src/CodePatterns/Observer/Observable.hpp
rb9273a r1c291d 30 30 * to avoid memory issues when many observable are around but only few 31 31 * are actually observed. 32 * 33 * \note We have to clean our Channels from static NotificationChannels and 34 * we call Channels::subjectKilled() to let Observers that have only signed 35 * on to single channel still know when their observable has died. 32 36 */ 33 37 class Observable : public Observer { -
src/Observer/Channels.cpp
rb9273a r1c291d 34 34 for(NotificationTypetoRefMap::iterator iter = ChannelMap.begin(); 35 35 !ChannelMap.empty(); iter = ChannelMap.begin()) { 36 delete iter->second; 37 ChannelMap.erase(iter); 36 removeChannel(iter->first); 38 37 } 39 38 } … … 41 40 void Channels::addChannel(size_t no) 42 41 { 42 #ifdef NDEBUG 43 43 NotificationTypetoRefMap::const_iterator iter = ChannelMap.find(no); 44 44 ASSERT(iter == ChannelMap.end(), 45 45 "Channels::addChannel() - channel "+toString(int(no))+" is already present in ChannelMap."); 46 #endif 46 47 ChannelMap.insert( std::make_pair(no, new Notification(no)) ); 47 48 } … … 54 55 delete iter->second; 55 56 ChannelMap.erase(iter); 57 } 58 59 void Channels::subjectKilled(Observable * const publisher) 60 { 61 for(NotificationTypetoRefMap::iterator iter = ChannelMap.begin(); 62 iter != ChannelMap.end();++iter) { 63 iter->second->subjectKilled(publisher); 64 } 56 65 } 57 66 -
src/Observer/Notification.cpp
rb9273a r1c291d 47 47 } 48 48 } 49 50 void Notification::subjectKilled(Observable * const publisher) 51 { 52 for(std::set<Observer*>::iterator it=targets.begin(); 53 it!=targets.end();++it){ 54 (*it)->subjectKilled(publisher); 55 } 56 } -
src/Observer/Observable.cpp
rb9273a r1c291d 276 276 { 277 277 Notification_ptr notification = getChannel(channelno); 278 #ifdef LOG_OBSERVER 279 observerLog().addMessage() << "@@ Signing on " << observerLog().getName(target) 280 << " to " << observerLog().getName(const_cast<Observable *>(this)) 281 << "'s channel no." << channelno << "."; 282 #endif 278 283 notification->addObserver(target); 279 284 } … … 282 287 { 283 288 Notification_ptr notification = getChannel(channelno); 289 #ifdef LOG_OBSERVER 290 observerLog().addMessage() << "** Signing off " << observerLog().getName(target) 291 << " from " << observerLog().getName(const_cast<Observable *>(this)) 292 << "'s channel no." << channelno << "."; 293 #endif 284 294 notification->removeObserver(target); 285 295 } … … 315 325 #ifdef LOG_OBSERVER 316 326 observerLog().addName(this,name); 317 observerLog().addMessage() << "++ Creating Observable " << observerLog().getName(this); 327 observerLog().addMessage() << "++ Creating Observable " 328 << observerLog().getName(static_cast<Observable *>(this)); 318 329 #endif 319 330 } … … 325 336 { 326 337 #ifdef LOG_OBSERVER 327 observerLog().addMessage() << "-- Destroying Observable " << observerLog().getName(this); 338 observerLog().addMessage() << "-- Destroying Observable " 339 << observerLog().getName(static_cast<Observable *>(this)); 328 340 #endif 329 341 if(callTable.count(this)) { … … 331 343 callees_t callees = callTable[this]; 332 344 callees_t::iterator iter; 333 for(iter=callees.begin();iter!=callees.end();++iter) {345 for(iter=callees.begin();iter!=callees.end();++iter) 334 346 (*iter).second->subjectKilled(this); 335 }336 347 callTable.erase(this); 337 348 } 338 349 339 350 // also kill instance in static Channels map if present 340 ChannelMap::iterator iter = NotificationChannels.find( this);351 ChannelMap::iterator iter = NotificationChannels.find(static_cast<Observable *>(this)); 341 352 if (iter != NotificationChannels.end()) { 353 iter->second->subjectKilled(static_cast<Observable *>(this)); 342 354 delete iter->second; 343 355 NotificationChannels.erase(iter); -
src/Observer/unittests/ObserverUnitTest.cpp
rb9273a r1c291d 298 298 299 299 RelayNotified->wasNotified=false; 300 notificationObserver1->wasNotified=false; 300 301 301 302 // operation2 302 303 notificationObservable->operation2(); 303 304 CPPUNIT_ASSERT(!RelayNotified->wasNotified); 304 CPPUNIT_ASSERT( notificationObserver1->wasNotified);305 CPPUNIT_ASSERT(!notificationObserver1->wasNotified); 305 306 306 307 // signOff relay from 1 and operation1 … … 313 314 314 315 // test kill subject 316 RelayNotifier->signOff(RelayNotified, NotificationObservable::Operation1Notify); 315 317 delete RelayNotified; 316 318 RelayNotified = NULL; // delete in tearDown is allowed for NULL 317 319 notificationObservable->operation1(); 320 notificationObservable->signOff(RelayNotifier, NotificationObservable::Operation2Notify); 318 321 delete notificationObservable; 319 322 notificationObservable = NULL; // delete in tearDown is allowed for NULL
Note:
See TracChangeset
for help on using the changeset viewer.
