Ignore:
Timestamp:
Dec 13, 2011, 9:46:10 AM (14 years ago)
Author:
Frederik Heber <heber@…>
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)
Message:

Refactored all Observer stuff into own subfolder and split up into distinct modules.

  • Observer/all.hpp is all that's needed.
File:
1 moved

Legend:

Unmodified
Added
Removed
  • src/Patterns/Observer/Observable.cpp

    rbc2698 re2e035e  
    77
    88/*
    9  * Observer.cpp
    10  *
    11  *  Created on: Jan 19, 2010
    12  *      Author: crueger
     9 * Observable.cpp
     10 *
     11 *  Created on: Dec 1, 2011
     12 *      Author: heber
    1313 */
    1414
     
    2020#include "MemDebug.hpp"
    2121
    22 #include "Observer.hpp"
    23 
    24 #include <iostream>
    25 
    2622#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
    3227
    3328// All infrastructure for the observer-pattern is bundled at a central place
     
    3934// See [Gamma et al, 1995] p. 297
    4035
    41 map<Observable*, int> Observable::depth;  //!< Map of Observables to the depth of the DAG of Observers
    42 map<Observable*,multimap<int,Observer*> > Observable::callTable; //!< Table for each Observable of all its Observers
     36std::map<Observable*, int> Observable::depth;  //!< Map of Observables to the depth of the DAG of Observers
     37std::map<Observable*,std::multimap<int,Observer*> > Observable::callTable; //!< Table for each Observable of all its Observers
    4338std::map<Observable*,std::set<Notification*> > Observable::notifications;
    44 set<Observable*> Observable::busyObservables; //!< Set of Observables that are currently busy notifying their sign-on'ed Observers
     39std::set<Observable*> Observable::busyObservables; //!< Set of Observables that are currently busy notifying their sign-on'ed Observers
    4540Observable::ChannelMap Observable::NotificationChannels; //!< Map of Observables to their Channels.
    4641
     
    5954  // by the STL and initialized to 0 (see STL documentation)
    6055#ifdef LOG_OBSERVER
    61   observerLog().addMessage(depth[publisher]) << ">> Locking " << observerLog().getName(publisher) << endl;
     56  observerLog().addMessage(depth[publisher]) << ">> Locking " << observerLog().getName(publisher) << std::endl;
    6257#endif
    6358  depth[publisher]++;
     
    8075  --depth[publisher];
    8176#ifdef LOG_OBSERVER
    82   observerLog().addMessage(depth[publisher]) << "<< Unlocking " << observerLog().getName(publisher) << endl;
     77  observerLog().addMessage(depth[publisher]) << "<< Unlocking " << observerLog().getName(publisher) << std::endl;
    8378#endif
    8479  if(depth[publisher]){}
     
    9287
    9388void 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");
    9589  notifications[publisher].insert(notification);
    9690}
     
    148142        observerLog().addMessage() << "-> Sending update from " << observerLog().getName(this)
    149143                                   << " to " << observerLog().getName((*iter).second)
    150                                    << " (priority=" << (*iter).first << ")"<< endl;
     144                                   << " (priority=" << (*iter).first << ")"<< std::endl;
    151145#endif
    152146        (*iter).second->update(this);
     
    161155  for(notificationSet::iterator it = currentNotifications.begin();
    162156      it != currentNotifications.end();++it){
    163     (*it)->notifyAll();
     157    (*it)->notifyAll(this);
    164158  }
    165159
     
    194188#ifdef LOG_OBSERVER
    195189      observerLog().addMessage() << "-* Update from " << observerLog().getName(publisher)
    196                                  << " propagated by " << observerLog().getName(this) << endl;
     190                                 << " propagated by " << observerLog().getName(this) << std::endl;
    197191#endif
    198192      notifyAll();
     
    201195#ifdef LOG_OBSERVER
    202196      observerLog().addMessage() << "-| Update from " <<  observerLog().getName(publisher)
    203                                  << " not propagated by " << observerLog().getName(this) << endl;
     197                                 << " not propagated by " << observerLog().getName(this) << std::endl;
    204198#endif
    205199    }
     
    214208void Observable::signOn(Observer *target,int priority) const
    215209{
    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;
    219214#endif
    220215  bool res = false;
     
    226221  }
    227222  if(!res)
    228     callees.insert(pair<int,Observer*>(priority,target));
     223    callees.insert(std::pair<int,Observer*>(priority,target));
    229224}
    230225
     
    235230void Observable::signOff(Observer *target) const
    236231{
    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;
    240236#endif
    241237  callees_t &callees = callTable[const_cast<Observable *>(this)];
     
    258254void Observable::signOn(Observer *target, Notification_ptr notification) const
    259255{
    260   ASSERT(notification->owner==this,
    261          "Trying to sign on for a notification that is not provided by this object");
    262 
    263256  notification->addObserver(target);
    264257}
     
    266259void Observable::signOff(Observer *target, Notification_ptr notification) const
    267260{
    268   ASSERT(notification->owner==this,
    269          "Trying to sign off from a notification that is not provided by this object");
    270 
    271261  notification->removeObserver(target);
    272262}
     
    279269Notification_ptr Observable::getChannel(size_t no) const
    280270{
    281   ChannelMap::iterator iter = NotificationChannels.find(const_cast<Observable *>(this));
     271  const ChannelMap::const_iterator iter = NotificationChannels.find(const_cast<Observable * const>(this));
    282272  ASSERT(iter != NotificationChannels.end(),
    283273      "Observable::getChannel() - we do not have a channel in NotificationChannels.");
     
    297287/** Constructor for class Observable.
    298288 */
    299 Observable::Observable(string name) :
     289Observable::Observable(std::string name) :
    300290  Observer(Observer::BaseConstructor())
    301291{
    302292#ifdef LOG_OBSERVER
    303293  observerLog().addName(this,name);
    304   observerLog().addMessage() << "++ Creating Observable " << observerLog().getName(this) << endl;
     294  observerLog().addMessage() << "++ Creating Observable " << observerLog().getName(this) << std::endl;
    305295#endif
    306296}
     
    312302{
    313303#ifdef LOG_OBSERVER
    314   observerLog().addMessage() << "-- Destroying Observable " << observerLog().getName(this) << endl;
     304  observerLog().addMessage() << "-- Destroying Observable " << observerLog().getName(this) << std::endl;
    315305#endif
    316306  if(callTable.count(this)) {
     
    324314  }
    325315}
    326 
    327 /** Constructor for class Observer.
    328  */
    329 Observer::Observer(string name)
    330 {
    331 #ifdef LOG_OBSERVER
    332   observerLog().addName(this,name);
    333   observerLog().addMessage() << "++ Creating Observer " << observerLog().getName(this) << endl;
    334 #endif
    335 }
    336 
    337 /**
    338  * Base Constructor for class Observer
    339  *
    340  * only called from Observable Constructor
    341  */
    342 Observer::Observer(Observer::BaseConstructor){
    343 #ifdef LOG_OBSERVER
    344   observerLog().addObservable(this);
    345 #endif
    346 }
    347 
    348 /** Destructor for class Observer.
    349  */
    350 Observer::~Observer()
    351 {
    352 #ifdef LOG_OBSERVER
    353   if(!observerLog().isObservable(this)){
    354     observerLog().addMessage() << "-- Destroying Observer " << observerLog().getName(this) << endl;
    355   }
    356 #endif
    357 }
    358 
    359 /**
    360  * Method for specialized notifications.
    361  * Most Observers wont need or use this, so it is implemented
    362  * 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 Notifications
    400   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) const
    425 {
    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) const
    433 {
    434   return channel->getChannelNo();
    435 }
    436 
    437 
    438 #ifdef LOG_OBSERVER
    439 
    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 it
    444 ObserverLog &observerLog(){
    445   // yes, this memory is never freed... we need it around for the whole programm,
    446   // so no freeing is possible
    447   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.