Changeset b760ac5
- Timestamp:
- Dec 13, 2011, 12:02:21 PM (14 years ago)
- Children:
- 3324cf
- Parents:
- d85532
- git-author:
- Frederik Heber <heber@…> (12/02/11 13:13:44)
- git-committer:
- Frederik Heber <heber@…> (12/13/11 12:02:21)
- Location:
- src
- Files:
-
- 7 edited
-
Patterns/Observer/Relay.cpp (modified) (4 diffs)
-
Patterns/Observer/Relay.hpp (modified) (2 diffs)
-
Patterns/Observer/unittests/ObserverUnitTest.cpp (modified) (3 diffs)
-
Patterns/Observer/unittests/ObserverUnitTest.hpp (modified) (4 diffs)
-
Patterns/Observer/unittests/stubs/ObserverStub.cpp (modified) (2 diffs)
-
Patterns/Observer/unittests/stubs/ObserverStub.hpp (modified) (1 diff)
-
documentation/patterns/observer.dox (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/Patterns/Observer/Relay.cpp
rd85532 rb760ac5 24 24 #include "Assert.hpp" 25 25 #include "Channels.hpp" 26 #include "defs.hpp"27 26 #include "Notification.hpp" 28 27 … … 48 47 observerLog().addMessage() << "-- Destroying Relay " << observerLog().getName(this); 49 48 #endif 50 } 51 49 // killing subjects is done by Observables' dstor 50 } 51 52 53 54 /** Sign on an Observer to this Observable. 55 * Puts \a *target into Observable::callTable list. 56 * \param *target Observer 57 * \param priority number in [-20,20] 58 */ 59 void Relay::signOn(Observer *target, PriorityLevel priority) const 60 { 61 #ifdef LOG_OBSERVER 62 observerLog().addMessage() << "@@ Signing on " << observerLog().getName(target) 63 << " to " 64 << observerLog().getName(const_cast<Observable *>(static_cast<const Observable * const>(this))); 65 #endif 66 bool res = false; 67 callees_t &callees = callTable[const_cast<Observable *>(static_cast<const Observable * const>(this))]; 68 69 callees_t::iterator iter; 70 for(iter=callees.begin();iter!=callees.end();++iter){ 71 res |= ((*iter).second == target); 72 } 73 if(!res) 74 callees.insert(std::pair<int,Observer*>(priority.level,target)); 75 } 76 77 /** Sign off an Observer from this Observable. 78 * Removes \a *target from Observable::callTable list. 79 * \param *target Observer 80 */ 81 void Relay::signOff(Observer *target) const 82 { 83 ASSERT(callTable.count(const_cast<Observable *>(static_cast<const Observable * const>(this))), 84 "Relay::signOff() - called for an Observable without Observers."); 85 #ifdef LOG_OBSERVER 86 observerLog().addMessage() << "** Signing off " << observerLog().getName(target) 87 << " from " 88 << observerLog().getName(const_cast<Observable *>(static_cast<const Observable * const>(this))); 89 #endif 90 callees_t &callees = callTable[const_cast<Observable *>(static_cast<const Observable * const>(this))]; 91 92 callees_t::iterator iter; 93 callees_t::iterator deliter; 94 for(iter=callees.begin();iter!=callees.end();) { 95 if((*iter).second == target) { 96 callees.erase(iter++); 97 } 98 else { 99 ++iter; 100 } 101 } 102 if(callees.empty()){ 103 callTable.erase(const_cast<Observable *>(static_cast<const Observable * const>(this))); 104 } 105 } 106 107 void Relay::signOn(Observer *target, size_t channelno) const 108 { 109 Notification_ptr notification = getChannel(channelno); 110 notification->addObserver(target); 111 } 112 113 void Relay::signOff(Observer *target, size_t channelno) const 114 { 115 Notification_ptr notification = getChannel(channelno); 116 notification->removeObserver(target); 117 } 52 118 53 119 /** Notify all Observers of changes. … … 125 191 Updater = publisher; 126 192 notifyAll(); 193 Updater = NULL; 127 194 } 128 195 else{ … … 135 202 } 136 203 137 //Notification_ptr Relay::getChannel(size_t no) const 138 //{ 139 // ASSERT(NotificationChannels != NULL, 140 // "Relay::getChannel() - observable has no channels."); 141 // return NotificationChannels->getChannel(no); 142 //} 204 /** Method for receiving specialized notifications. 205 * 206 * \param *publisher The \a *this we observe. 207 * \param notification type of notification 208 */ 209 void Relay::recieveNotification(Observable *publisher, Notification_ptr notification) 210 { 211 Updater = publisher; 212 const Channels *myChannels = NotificationChannels[const_cast<Observable *>(static_cast<const Observable * const>(this))]; 213 ASSERT(myChannels != NULL, 214 "Relay::recieveNotification() - this relay does not have any channels."); 215 const size_t channelno = notification->getChannelNo(); 216 Notification_ptr mynotification = myChannels->getChannel(channelno); 217 ASSERT(mynotification != NULL, 218 "Relay::recieveNotification() - this relay does not have a notification no "+toString(channelno)+"."); 219 mynotification->notifyAll(Updater); 220 Updater = NULL; 221 } 143 222 144 223 /** Handles sub-observables that just got killed -
src/Patterns/Observer/Relay.hpp
rd85532 rb760ac5 36 36 virtual ~Relay(); 37 37 38 // Notification_ptr getChannel(size_t no) const; 38 virtual void signOn(Observer *target, PriorityLevel priority = Observable::PriorityDefault) const; 39 40 virtual void signOff(Observer *target) const; 41 42 virtual void signOn(Observer *target, size_t channelno) const; 43 44 virtual void signOff(Observer *target, size_t channelno) const; 39 45 40 46 protected: 41 47 virtual void update(Observable *publisher); 48 virtual void recieveNotification(Observable *publisher, Notification_ptr notification); 42 49 virtual void subjectKilled(Observable *publisher); 43 50 … … 47 54 //!> Current peer that called last update on us, to be passed on to Observers 48 55 Observable *Updater; 49 //protected:50 //51 // Channels *NotificationChannels;52 //53 56 }; 54 57 -
src/Patterns/Observer/unittests/ObserverUnitTest.cpp
rd85532 rb760ac5 71 71 RelayObservable = new RelayTest; 72 72 RelayObserver = new RelayCountObserver(RelayObservable); 73 74 RelayNotifier = new RelayNotification; 75 RelayNotified = new RelayNotificationObserver(RelayObservable); 73 76 } 74 77 … … 84 87 delete RelayObservable; 85 88 delete RelayObserver; 89 delete RelayNotifier; 90 delete RelayNotified; 86 91 87 92 delete observer1; … … 276 281 } 277 282 283 void ObserverTest::relayNotificationTest() 284 { 285 observerLog().enableLogging(); 286 287 // sign on some observables to the relay 288 notificationObservable->signOn(RelayNotifier, NotificationObservable::Operation1Notify); 289 notificationObservable->signOn(RelayNotifier, NotificationObservable::Operation2Notify); 290 notificationObservable->signOn(notificationObserver1, NotificationObservable::Operation1Notify); 291 292 RelayNotifier->signOn(RelayNotified, NotificationObservable::Operation1Notify); 293 294 // operation1 295 notificationObservable->operation1(); 296 CPPUNIT_ASSERT(RelayNotified->wasNotified); 297 CPPUNIT_ASSERT(notificationObserver1->wasNotified); 298 299 RelayNotified->wasNotified=false; 300 301 // operation2 302 notificationObservable->operation2(); 303 CPPUNIT_ASSERT(!RelayNotified->wasNotified); 304 CPPUNIT_ASSERT(notificationObserver1->wasNotified); 305 306 // signOff relay from 1 and operation1 307 notificationObserver1->wasNotified=false; 308 notificationObservable->signOff(RelayNotifier, NotificationObservable::Operation1Notify); 309 310 notificationObservable->operation1(); 311 CPPUNIT_ASSERT(!RelayNotified->wasNotified); 312 CPPUNIT_ASSERT(notificationObserver1->wasNotified); 313 314 // test kill subject 315 delete RelayNotified; 316 RelayNotified = NULL; // delete in tearDown is allowed for NULL 317 notificationObservable->operation1(); 318 delete notificationObservable; 319 notificationObservable = NULL; // delete in tearDown is allowed for NULL 320 321 observerLog().disableLogging(); 322 } 323 278 324 void ObserverTest::CircleDetectionTest() { 279 325 std::cout << std::endl << "Warning: the next test involved methods that can produce infinite loops." << std::endl; -
src/Patterns/Observer/unittests/ObserverUnitTest.hpp
rd85532 rb760ac5 28 28 class NotificationObservable; 29 29 class RelayCountObserver; 30 class RelayNotification; 31 class RelayNotificationObserver; 30 32 31 33 class ObserverTest : public CppUnit::TestFixture … … 40 42 CPPUNIT_TEST ( iteratorTest ); 41 43 CPPUNIT_TEST ( relayTest ); 44 CPPUNIT_TEST ( relayNotificationTest ); 42 45 CPPUNIT_TEST ( CircleDetectionTest ); 43 46 CPPUNIT_TEST_SUITE_END(); … … 55 58 void iteratorTest(); 56 59 void relayTest(); 60 void relayNotificationTest(); 57 61 void CircleDetectionTest(); 58 62 … … 76 80 RelayTest *RelayObservable; 77 81 RelayCountObserver *RelayObserver; 82 RelayNotification *RelayNotifier; 83 RelayNotificationObserver *RelayNotified; 78 84 }; 79 85 -
src/Patterns/Observer/unittests/stubs/ObserverStub.cpp
rd85532 rb760ac5 239 239 {} 240 240 241 /************ RelayNotification ***************/ 242 243 RelayNotification::RelayNotification() : 244 Relay(std::string("RelayTest")) 245 { 246 Channels *OurChannel = new Channels(); 247 NotificationChannels.insert( std::make_pair(this, OurChannel) ); 248 OurChannel->addChannel(NotificationObservable::Operation1Notify); 249 OurChannel->addChannel(NotificationObservable::Operation2Notify); 250 } 251 252 RelayNotification::~RelayNotification() 253 {} 254 241 255 /************ RelayCountObserver ***************/ 242 256 … … 259 273 } 260 274 275 /********* RelayNotificationObserver ***********/ 276 277 RelayNotificationObserver::RelayNotificationObserver(const Observable * const _relay) : 278 Observer("RelayNotificationObserver"), 279 wasNotified(false), 280 relay(_relay) 281 {} 282 283 RelayNotificationObserver::~RelayNotificationObserver() 284 {} 285 286 void RelayNotificationObserver::update(Observable*){} 287 void RelayNotificationObserver::subjectKilled(Observable*){} 288 void RelayNotificationObserver::recieveNotification(Observable *publisher, Notification_ptr notification){ 289 // check that we are not called by the relay itself 290 CPPUNIT_ASSERT(publisher != relay); 291 wasNotified = true; 292 } 293 -
src/Patterns/Observer/unittests/stubs/ObserverStub.hpp
rd85532 rb760ac5 148 148 }; 149 149 150 class RelayNotification : public Relay 151 { 152 public: 153 RelayNotification(); 154 ~RelayNotification(); 155 private: 156 }; 157 158 class RelayNotificationObserver : public Observer { 159 public: 160 RelayNotificationObserver(const Observable * const _relay); 161 virtual ~RelayNotificationObserver(); 162 163 void update(Observable*); 164 void subjectKilled(Observable*); 165 void recieveNotification(Observable *publisher, Notification_ptr notification); 166 167 bool wasNotified; 168 private: 169 const Observable * const relay; 170 }; 171 150 172 #endif /* OBSERVERSTUB_HPP_ */ -
src/documentation/patterns/observer.dox
rd85532 rb760ac5 28 28 * updating many of its internal sub-observables. This means the update is not passed, if 29 29 * it is produced while the main-observable itself is within any Observation block. 30 * 31 * \section pattern-observer-howtos Howto 32 * 33 * Below you find various howtos to guide you through how to use the various 34 * observer patterns. 35 * 36 * \section pattern-observer-howtos-observer Observers 37 * 38 * \todo write howto for using an Observer 39 * 40 * \section pattern-observer-howtos-observables Observables 41 * 42 * \todo write howto for using an Observable 43 * 44 * \section pattern-observer-howtos-relay Relays 45 * 46 * Lets us assume that you want to observe all instances of class "foo". 47 * In order to create a Relay you have to do the following: 48 * -# Create a new class "bar" that inherits the Relay pattern. 49 * \code 50 * #include "CodePatterns/Relay.hpp" 51 * class bar : public Relay { 52 * ... 53 * }; 54 * \endcode 55 * -# In the constructor bar::bar() create a Channels object for your Relay and 56 * add a channel for each of foo's channels, use foo's enum for this: 57 * \code 58 * bar::bar() { 59 * Channels *OurChannel = new Channels(); 60 * NotificationChannels.insert( std::make_pair(this, OurChannel) ); 61 * OurChannel->addChannel(foo::Notification1); 62 * OurChannel->addChannel(foo::Notification2); 63 * ... 64 * } 65 * \endcode 66 * -# Someplace else you have add all Observers that need to check on all 67 * instances of "foo" to be signed on. 68 * \code 69 * bar barInstance; 70 * ... someObserverInstance; 71 * barInstance.signOn(someObserverInstance); 72 * \endcode 73 * -# ... or maybe just for a specific channel of foo. 74 * \code 75 * bar barInstance; 76 * ... someObserverInstance; 77 * barInstance.signOn(someObserverInstance, foo::Notification1); 78 * \endcode 79 * 80 * 81 * \date 2011-12-01 30 82 */ 31 83
Note:
See TracChangeset
for help on using the changeset viewer.
