Changeset e2e035e for src/Patterns/Observer/Observable.cpp
- Timestamp:
- Dec 13, 2011, 9:46:10 AM (14 years ago)
- Children:
- 549b62
- Parents:
- bc2698
- git-author:
- Frederik Heber <heber@…> (12/01/11 10:20:57)
- git-committer:
- Frederik Heber <heber@…> (12/13/11 09:46:10)
- File:
-
- 1 moved
-
src/Patterns/Observer/Observable.cpp (moved) (moved from src/Patterns/Observer.cpp ) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Patterns/Observer/Observable.cpp
rbc2698 re2e035e 7 7 8 8 /* 9 * Observ er.cpp10 * 11 * Created on: Jan 19, 201012 * Author: crueger9 * Observable.cpp 10 * 11 * Created on: Dec 1, 2011 12 * Author: heber 13 13 */ 14 14 … … 20 20 #include "MemDebug.hpp" 21 21 22 #include "Observer.hpp"23 24 #include <iostream>25 26 22 #include "Assert.hpp" 27 #include "MemDebug.hpp" 28 29 using namespace std; 30 31 /****************** Static stuff for the observer mechanism ************/ 23 #include "Channels.hpp" 24 #include "Notification.hpp" 25 #include "Observable.hpp" 26 32 27 33 28 // All infrastructure for the observer-pattern is bundled at a central place … … 39 34 // See [Gamma et al, 1995] p. 297 40 35 41 map<Observable*, int> Observable::depth; //!< Map of Observables to the depth of the DAG of Observers42 map<Observable*,multimap<int,Observer*> > Observable::callTable; //!< Table for each Observable of all its Observers36 std::map<Observable*, int> Observable::depth; //!< Map of Observables to the depth of the DAG of Observers 37 std::map<Observable*,std::multimap<int,Observer*> > Observable::callTable; //!< Table for each Observable of all its Observers 43 38 std::map<Observable*,std::set<Notification*> > Observable::notifications; 44 s et<Observable*> Observable::busyObservables; //!< Set of Observables that are currently busy notifying their sign-on'ed Observers39 std::set<Observable*> Observable::busyObservables; //!< Set of Observables that are currently busy notifying their sign-on'ed Observers 45 40 Observable::ChannelMap Observable::NotificationChannels; //!< Map of Observables to their Channels. 46 41 … … 59 54 // by the STL and initialized to 0 (see STL documentation) 60 55 #ifdef LOG_OBSERVER 61 observerLog().addMessage(depth[publisher]) << ">> Locking " << observerLog().getName(publisher) << endl;56 observerLog().addMessage(depth[publisher]) << ">> Locking " << observerLog().getName(publisher) << std::endl; 62 57 #endif 63 58 depth[publisher]++; … … 80 75 --depth[publisher]; 81 76 #ifdef LOG_OBSERVER 82 observerLog().addMessage(depth[publisher]) << "<< Unlocking " << observerLog().getName(publisher) << endl;77 observerLog().addMessage(depth[publisher]) << "<< Unlocking " << observerLog().getName(publisher) << std::endl; 83 78 #endif 84 79 if(depth[publisher]){} … … 92 87 93 88 void Observable::enque_notification_internal(Observable *publisher, Notification_ptr notification){ 94 ASSERT(notification->owner==publisher,"Some object tried to send a notification it does not own");95 89 notifications[publisher].insert(notification); 96 90 } … … 148 142 observerLog().addMessage() << "-> Sending update from " << observerLog().getName(this) 149 143 << " to " << observerLog().getName((*iter).second) 150 << " (priority=" << (*iter).first << ")"<< endl;144 << " (priority=" << (*iter).first << ")"<< std::endl; 151 145 #endif 152 146 (*iter).second->update(this); … … 161 155 for(notificationSet::iterator it = currentNotifications.begin(); 162 156 it != currentNotifications.end();++it){ 163 (*it)->notifyAll( );157 (*it)->notifyAll(this); 164 158 } 165 159 … … 194 188 #ifdef LOG_OBSERVER 195 189 observerLog().addMessage() << "-* Update from " << observerLog().getName(publisher) 196 << " propagated by " << observerLog().getName(this) << endl;190 << " propagated by " << observerLog().getName(this) << std::endl; 197 191 #endif 198 192 notifyAll(); … … 201 195 #ifdef LOG_OBSERVER 202 196 observerLog().addMessage() << "-| Update from " << observerLog().getName(publisher) 203 << " not propagated by " << observerLog().getName(this) << endl;197 << " not propagated by " << observerLog().getName(this) << std::endl; 204 198 #endif 205 199 } … … 214 208 void Observable::signOn(Observer *target,int priority) const 215 209 { 216 ASSERT(priority>=-20 && priority<=+20, "Priority out of range [-20:+20] when signing on Observer"); 217 #ifdef LOG_OBSERVER 218 observerLog().addMessage() << "@@ Signing on " << observerLog().getName(target) << " to " << observerLog().getName(const_cast<Observable *>(this)) << endl; 210 ASSERT(priority>=-20 && priority<=+20, 211 "Priority out of range [-20:+20] when signing on Observer"); 212 #ifdef LOG_OBSERVER 213 observerLog().addMessage() << "@@ Signing on " << observerLog().getName(target) << " to " << observerLog().getName(const_cast<Observable *>(this)) << std::endl; 219 214 #endif 220 215 bool res = false; … … 226 221 } 227 222 if(!res) 228 callees.insert( pair<int,Observer*>(priority,target));223 callees.insert(std::pair<int,Observer*>(priority,target)); 229 224 } 230 225 … … 235 230 void Observable::signOff(Observer *target) const 236 231 { 237 ASSERT(callTable.count(const_cast<Observable *>(this)),"SignOff called for an Observable without Observers."); 238 #ifdef LOG_OBSERVER 239 observerLog().addMessage() << "** Signing off " << observerLog().getName(target) << " from " << observerLog().getName(const_cast<Observable *>(this)) << endl; 232 ASSERT(callTable.count(const_cast<Observable *>(this)), 233 "SignOff called for an Observable without Observers."); 234 #ifdef LOG_OBSERVER 235 observerLog().addMessage() << "** Signing off " << observerLog().getName(target) << " from " << observerLog().getName(const_cast<Observable *>(this)) << std::endl; 240 236 #endif 241 237 callees_t &callees = callTable[const_cast<Observable *>(this)]; … … 258 254 void Observable::signOn(Observer *target, Notification_ptr notification) const 259 255 { 260 ASSERT(notification->owner==this,261 "Trying to sign on for a notification that is not provided by this object");262 263 256 notification->addObserver(target); 264 257 } … … 266 259 void Observable::signOff(Observer *target, Notification_ptr notification) const 267 260 { 268 ASSERT(notification->owner==this,269 "Trying to sign off from a notification that is not provided by this object");270 271 261 notification->removeObserver(target); 272 262 } … … 279 269 Notification_ptr Observable::getChannel(size_t no) const 280 270 { 281 ChannelMap::iterator iter = NotificationChannels.find(const_cast<Observable *>(this));271 const ChannelMap::const_iterator iter = NotificationChannels.find(const_cast<Observable * const>(this)); 282 272 ASSERT(iter != NotificationChannels.end(), 283 273 "Observable::getChannel() - we do not have a channel in NotificationChannels."); … … 297 287 /** Constructor for class Observable. 298 288 */ 299 Observable::Observable(st ring name) :289 Observable::Observable(std::string name) : 300 290 Observer(Observer::BaseConstructor()) 301 291 { 302 292 #ifdef LOG_OBSERVER 303 293 observerLog().addName(this,name); 304 observerLog().addMessage() << "++ Creating Observable " << observerLog().getName(this) << endl;294 observerLog().addMessage() << "++ Creating Observable " << observerLog().getName(this) << std::endl; 305 295 #endif 306 296 } … … 312 302 { 313 303 #ifdef LOG_OBSERVER 314 observerLog().addMessage() << "-- Destroying Observable " << observerLog().getName(this) << endl;304 observerLog().addMessage() << "-- Destroying Observable " << observerLog().getName(this) << std::endl; 315 305 #endif 316 306 if(callTable.count(this)) { … … 324 314 } 325 315 } 326 327 /** Constructor for class Observer.328 */329 Observer::Observer(string name)330 {331 #ifdef LOG_OBSERVER332 observerLog().addName(this,name);333 observerLog().addMessage() << "++ Creating Observer " << observerLog().getName(this) << endl;334 #endif335 }336 337 /**338 * Base Constructor for class Observer339 *340 * only called from Observable Constructor341 */342 Observer::Observer(Observer::BaseConstructor){343 #ifdef LOG_OBSERVER344 observerLog().addObservable(this);345 #endif346 }347 348 /** Destructor for class Observer.349 */350 Observer::~Observer()351 {352 #ifdef LOG_OBSERVER353 if(!observerLog().isObservable(this)){354 observerLog().addMessage() << "-- Destroying Observer " << observerLog().getName(this) << endl;355 }356 #endif357 }358 359 /**360 * Method for specialized notifications.361 * Most Observers wont need or use this, so it is implemented362 * empty in the base case;363 */364 void Observer::recieveNotification(Observable *publisher, Notification_ptr notification){365 ASSERT(0,"Notification received by object that did not sign on for it.");366 }367 368 Notification::Notification(Observable *_owner) :369 owner(_owner), channelno(-1)370 {}371 372 Notification::Notification(Observable *_owner, size_t _channelno) :373 owner(_owner), channelno(_channelno)374 {}375 376 Notification::~Notification(){}377 378 void Notification::addObserver(Observer *target){379 targets.insert(target);380 }381 382 void Notification::removeObserver(Observer *target){383 targets.erase(target);384 }385 386 void Notification::notifyAll(){387 for(std::set<Observer*>::iterator it=targets.begin();388 it!=targets.end();++it){389 (*it)->recieveNotification(owner,this);390 }391 }392 393 Channels::Channels(Observable *_owner) :394 owner(_owner)395 {}396 397 Channels::~Channels()398 {399 // free all present Notifications400 for(NotificationTypetoRefMap::iterator iter = ChannelMap.begin();401 !ChannelMap.empty(); iter = ChannelMap.begin()) {402 delete iter->second;403 ChannelMap.erase(iter);404 }405 }406 407 void Channels::addChannel(size_t no)408 {409 NotificationTypetoRefMap::const_iterator iter = ChannelMap.find(no);410 ASSERT(iter == ChannelMap.end(),411 "Channels::addChannel() - channel "+toString(int(no))+" is already present in ChannelMap.");412 ChannelMap.insert( std::make_pair(no, new Notification(owner, no)) );413 }414 415 void Channels::removeChannel(size_t no)416 {417 NotificationTypetoRefMap::iterator iter = ChannelMap.find(no);418 ASSERT(iter != ChannelMap.end(),419 "Channels::removeChannel() - channel "+toString(int(no))+" not present in ChannelMap.");420 delete iter->second;421 ChannelMap.erase(iter);422 }423 424 Notification_ptr Channels::getChannel(size_t no) const425 {426 NotificationTypetoRefMap::const_iterator iter = ChannelMap.find(no);427 ASSERT(iter != ChannelMap.end(),428 "Channels::getChannel() - channel "+toString(int(no))+" not present in ChannelMap.");429 return iter->second;430 }431 432 size_t Channels::getType(Notification_ptr channel) const433 {434 return channel->getChannelNo();435 }436 437 438 #ifdef LOG_OBSERVER439 440 /************************* Methods to do logging of the Observer Mechanism *********/441 442 // The log needs to exist fairly early, so we make it construct on first use,443 // and never destroy it444 ObserverLog &observerLog(){445 // yes, this memory is never freed... we need it around for the whole programm,446 // so no freeing is possible447 static ObserverLog *theLog = Memory::ignore(new ObserverLog());448 return *theLog;449 }450 451 452 ObserverLog::ObserverLog() :453 count (0)454 {}455 456 ObserverLog::~ObserverLog(){}457 458 string ObserverLog::getLog(){return log.str();}459 460 std::string ObserverLog::getName(void* obj){461 return names[obj];462 }463 464 bool ObserverLog::isObservable(void* obj){465 return observables.count(obj);466 }467 468 void ObserverLog::addName(void* obj , string name){469 stringstream sstr;470 sstr << name << "_" << count++;471 names[obj] = sstr.str();472 }473 474 void ObserverLog::addObservable(void* obj){475 observables.insert(obj);476 }477 478 void ObserverLog::deleteName(void* obj){479 names.erase(obj);480 }481 482 void ObserverLog::deleteObservable(void* obj){483 observables.erase(obj);484 }485 486 stringstream &ObserverLog::addMessage(int depth){487 for(int i=depth;i--;)488 log << " ";489 return log;490 }491 492 #endif
Note:
See TracChangeset
for help on using the changeset viewer.
