Changeset 74e0f7


Ignore:
Timestamp:
Sep 1, 2011, 11:07:47 AM (14 years ago)
Author:
Frederik Heber <heber@…>
Children:
9e776f
Parents:
451f17
git-author:
Frederik Heber <heber@…> (09/01/11 11:02:49)
git-committer:
Frederik Heber <heber@…> (09/01/11 11:07:47)
Message:

Extended Observables by NotificationChannels member variable.

  • new class Channels that aggregates Notifications.
  • NOTIFY now just takes a channel number.
  • may or may not be instantiated for a given Observable.
  • Observable just needs to add enum of all desired channels and addChannel on each of these.
  • ObserverUnitTest has been adapted.
Location:
src/Patterns
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/Patterns/Observer.cpp

    r451f17 r74e0f7  
    271271}
    272272
     273Notification_ptr Observable::getChannel(size_t no) const
     274{
     275  ASSERT(NotificationChannels != NULL,
     276      "Observable::getChannel() - observable has no channels.");
     277  return NotificationChannels->getChannel(no);
     278}
     279
    273280/** Handles sub-observables that just got killed
    274281 *  when an sub-observerable dies we usually don't need to do anything
     
    350357
    351358Notification::Notification(Observable *_owner) :
    352     owner(_owner)
     359    owner(_owner), channelno(-1)
     360{}
     361
     362Notification::Notification(Observable *_owner, size_t _channelno) :
     363    owner(_owner), channelno(_channelno)
    353364{}
    354365
     
    369380  }
    370381}
     382
     383Channels::Channels(Observable *_owner) :
     384  owner(_owner)
     385{}
     386
     387Channels::~Channels()
     388{
     389  // free all present Notifications
     390  for(NotificationTypetoRefMap::iterator iter = ChannelMap.begin();
     391      !ChannelMap.empty(); iter = ChannelMap.begin()) {
     392    delete iter->second;
     393    ChannelMap.erase(iter);
     394  }
     395}
     396
     397void Channels::addChannel(size_t no)
     398{
     399  NotificationTypetoRefMap::const_iterator iter = ChannelMap.find(no);
     400  ASSERT(iter == ChannelMap.end(),
     401      "Channels::addChannel() - channel "+toString(int(no))+" is already present in ChannelMap.");
     402  ChannelMap.insert( std::make_pair(no, new Notification(owner, no)) );
     403}
     404
     405void Channels::removeChannel(size_t no)
     406{
     407  NotificationTypetoRefMap::iterator iter = ChannelMap.find(no);
     408  ASSERT(iter != ChannelMap.end(),
     409      "Channels::removeChannel() - channel "+toString(int(no))+" not present in ChannelMap.");
     410  delete iter->second;
     411  ChannelMap.erase(iter);
     412}
     413
     414Notification_ptr Channels::getChannel(size_t no) const
     415{
     416  NotificationTypetoRefMap::const_iterator iter = ChannelMap.find(no);
     417  ASSERT(iter != ChannelMap.end(),
     418      "Channels::getChannel() - channel "+toString(int(no))+" not present in ChannelMap.");
     419  return iter->second;
     420}
     421
     422size_t Channels::getType(Notification_ptr channel) const
     423{
     424  return channel->getChannelNo();
     425}
     426
    371427
    372428#ifdef LOG_OBSERVER
  • src/Patterns/Observer.hpp

    r451f17 r74e0f7  
    4040#endif
    4141
     42class Channels;
     43class Notification;
    4244class Observable;
    43 class Notification;
    4445
    4546// Pointers to notifications are used for unique identification
     
    145146  virtual bool isBlocked();
    146147
     148  Notification_ptr getChannel(size_t no) const;
     149
    147150protected:
    148151  virtual void update(Observable *publisher);
     
    164167
    165168  static void enque_notification_internal(Observable *publisher, Notification_ptr notification);
     169
     170  Channels *NotificationChannels;
    166171
    167172private:
     
    192197};
    193198
     199/** Notifications are sort of new channels of an Observable.
     200 * Via the NOTIFY() macro updates can be transmitted in a specific channel.
     201 * Observers can subscribe to Notification in much the same way as they can to
     202 * the Observable itself. Usually, Notifications
     203 */
    194204class Notification {
    195205  friend class Observable;
     206  friend class Channels;
    196207public:
    197208  Notification(Observable *_owner);
     209  Notification(Observable *_owner, size_t _channelno);
    198210  virtual ~Notification();
     211
     212  size_t getChannelNo() const { return channelno; }
    199213protected:
    200214
     
    206220  Observable * const owner;
    207221  std::set<Observer*> targets;
     222  size_t channelno;
     223};
     224
     225/** Channels aggregate all possible Notifications of an Observable.
     226 *
     227 * Usually, one implements an enumeration of the channel number which is
     228 * visible to the outside only.
     229 *
     230 */
     231class Channels {
     232public:
     233  Channels(Observable *_owner);
     234  virtual ~Channels();
     235
     236  void addChannel(size_t no);
     237
     238  Notification_ptr getChannel(size_t no) const;
     239  size_t getType(Notification_ptr channel) const;
     240
     241protected:
     242  void removeChannel(size_t no);
     243
     244private:
     245  Observable * const owner;
     246
     247  typedef std::map< size_t, Notification_ptr> NotificationTypetoRefMap;
     248
     249  NotificationTypetoRefMap ChannelMap;
    208250};
    209251
     
    245287#define PASTE_HELPER(a,b) a ## b
    246288#define OBSERVE Observable::_Observable_protector PASTE(_scope_obs_protector_,__LINE__)(this)
    247 #define NOTIFY(notification) do{Observable::enque_notification_internal(this,notification);}while(0)
     289#define NOTIFY(channelno) do{Observable::enque_notification_internal(this,NotificationChannels->getChannel(channelno));}while(0)
    248290#define LOCK_OBSERVABLE(observable) Observable::_Observable_protector PASTE(_scope_obs_protector_,__LINE__)(&(observable))
    249291
  • src/Patterns/unittests/ObserverUnitTest.cpp

    r451f17 r74e0f7  
    6161  observer4 = new UpdateCountObserver();
    6262
    63   notificationObserver1 = new NotificationObserver(notificationObservable->notification1);
    64   notificationObserver2 = new NotificationObserver(notificationObservable->notification2);
     63  notificationObserver1 = new NotificationObserver(
     64      notificationObservable->getChannel(NotificationObservable::Operation1Notify));
     65  notificationObserver2 = new NotificationObserver(
     66      notificationObservable->getChannel(NotificationObservable::Operation2Notify));
    6567}
    6668
     
    157159
    158160void ObserverTest::doesNotifyTest(){
     161  CPPUNIT_ASSERT_EQUAL(
     162      (size_t)NotificationObservable::Operation1Notify,
     163      notificationObservable->getChannel(NotificationObservable::Operation1Notify)->getChannelNo());
     164  CPPUNIT_ASSERT_EQUAL(
     165      (size_t)NotificationObservable::Operation2Notify,
     166      notificationObservable->getChannel(NotificationObservable::Operation2Notify)->getChannelNo());
    159167  notificationObservable->signOn(notificationObserver1,
    160                                  notificationObservable->notification1);
     168                                 notificationObservable->getChannel(NotificationObservable::Operation1Notify));
    161169  notificationObservable->signOn(notificationObserver2,
    162                                  notificationObservable->notification2);
     170                                 notificationObservable->getChannel(NotificationObservable::Operation2Notify));
    163171
    164172  notificationObservable->operation1();
  • src/Patterns/unittests/stubs/ObserverStub.cpp

    r451f17 r74e0f7  
    3131{};
    3232
     33UpdateCountObserver::~UpdateCountObserver()
     34{}
     35
    3336void UpdateCountObserver::update(Observable *publisher){
    3437  updates++;
     
    127130
    128131NotificationObservable::NotificationObservable() :
    129   Observable("NotificationObservable"),
    130   notification1(new Notification(this)),
    131   notification2(new Notification(this))
    132 {}
    133 
    134 NotificationObservable::~NotificationObservable(){
    135   delete notification1;
    136   delete notification2;
     132  Observable("NotificationObservable")
     133{
     134  NotificationChannels = new Channels(this);
     135  NotificationChannels->addChannel(Operation1Notify);
     136  NotificationChannels->addChannel(Operation2Notify);
     137}
     138
     139NotificationObservable::~NotificationObservable()
     140{
     141  delete NotificationChannels;
    137142}
    138143
    139144void NotificationObservable::operation1(){
    140145  OBSERVE;
    141   NOTIFY(notification1);
     146  NOTIFY(Operation1Notify);
    142147}
    143148
    144149void NotificationObservable::operation2(){
    145150  OBSERVE;
    146   NOTIFY(notification2);
     151  NOTIFY(Operation2Notify);
    147152}
    148153
     
    153158  requestedNotification(notification),
    154159  wasNotified(false)
     160{}
     161
     162NotificationObserver::~NotificationObserver()
    155163{}
    156164
  • src/Patterns/unittests/stubs/ObserverStub.hpp

    r451f17 r74e0f7  
    1515public:
    1616  UpdateCountObserver();
     17  virtual ~UpdateCountObserver();
     18
    1719  void update(Observable *publisher);
    1820  void subjectKilled(Observable *publisher);
     
    5254public:
    5355  SuperObservable();
    54   ~SuperObservable();
     56  virtual ~SuperObservable();
    5557
    5658  void changeMethod();
     
    6264public:
    6365  NotificationObservable();
    64   ~NotificationObservable();
     66  virtual ~NotificationObservable();
     67
     68  enum NotificationType {
     69    Operation1Notify = 0,
     70    Operation2Notify = 1
     71  };
    6572
    6673  void operation1();
    6774  void operation2();
    68 
    69   Notification_ptr notification1;
    70   Notification_ptr notification2;
    7175};
    7276
     
    7478public:
    7579  NotificationObserver(Notification_ptr notification);
     80  virtual ~NotificationObserver();
    7681
    7782  void update(Observable*);
     
    9196
    9297  ObservableSet(int _num);
    93   ~ObservableSet();
     98  virtual ~ObservableSet();
    9499
    95100  iterator begin();
     
    109114
    110115  ObservableMap(int _num);
    111   ~ObservableMap();
     116  virtual ~ObservableMap();
    112117
    113118  iterator begin();
Note: See TracChangeset for help on using the changeset viewer.