Changeset b324a3 for src


Ignore:
Timestamp:
Sep 5, 2013, 2:14:06 PM (12 years ago)
Author:
Frederik Heber <heber@…>
Children:
44f368
Parents:
37d941
git-author:
Frederik Heber <heber@…> (09/05/13 14:09:44)
git-committer:
Frederik Heber <heber@…> (09/05/13 14:14:06)
Message:

Added Graveyard for to-be-destroyed Observables.

  • also added Zombie class that wraps an Observable.
  • Notification and Observable have new function getNumberOfObservers().
  • added unit test for Graveyard.
Location:
src
Files:
5 added
5 edited

Legend:

Unmodified
Added
Removed
  • src/CodePatterns/Observer/Notification.hpp

    r37d941 rb324a3  
    6565  void subjectKilled(Observable * const publisher);
    6666
     67  /** Getter for the number of Observer for this notification (channel).
     68   *
     69   * \return number of added observers
     70   */
     71  size_t getNumberOfObservers() const
     72  { return targets.size(); }
     73
    6774private:
    6875  typedef std::set<Observer*> targets_t;
  • src/CodePatterns/Observer/Observable.hpp

    r37d941 rb324a3  
    1717#include <set>
    1818#include <string>
     19#include <boost/function.hpp>
    1920
    2021#include "CodePatterns/Range.hpp"
    2122#include "CodePatterns/Observer/defs.hpp"
    2223#include "CodePatterns/Observer/Observer.hpp"
     24
     25class Graveyard;
    2326
    2427/**
     
    3437 * we call Channels::subjectKilled() to let Observers that have only signed
    3538 * on to single channel still know when their observable has died.
     39 *
     40 * Note that one may allow an Observable to live some over-time by using
     41 * the Graveyard. This allows any Observer to still access the instance
     42 * in order to properly sign off. It is destroyed when no Observer is left.
    3643 */
    3744class Observable : public Observer {
     
    93100  Notification_ptr getChannel(size_t no) const;
    94101
     102  size_t getNumberOfObservers() const;
     103
    95104protected:
    96105  virtual void update(Observable *publisher);
     
    126135  static std::set<Observable*> busyObservables;
    127136
     137private:
     138  friend class Zombie;
     139  friend class Graveyard;
     140
     141  typedef boost::function<void (const Observable*)> graveyard_informer_t;
     142
     143  //!> bound function to call when Observer are signing off
     144  graveyard_informer_t &graveyard_informer;
     145
     146  //!> default informer that does nothing
     147  static graveyard_informer_t noop_informer;
     148
     149  /** Sets the bound function for over-time life-time management.
     150   *
     151   * \param _graveyard Graveyard to inform of leaving Observers
     152   */
     153  void setGraveyardInformer(graveyard_informer_t &_graveyard_informer)
     154  {
     155    graveyard_informer = _graveyard_informer;
     156  }
     157
    128158  //! @cond
    129159  // Structure for RAII-Style notification
  • src/Observer/Makefile.am

    r37d941 rb324a3  
    1010OBSERVERSOURCE = \
    1111        Channels.cpp \
     12        Graveyard.cpp \
    1213        Notification.cpp \
    1314        Observable.cpp \
     
    2324        $(top_srcdir)/src/CodePatterns/Observer/Channels.hpp \
    2425        $(top_srcdir)/src/CodePatterns/Observer/defs.hpp \
     26        $(top_srcdir)/src/CodePatterns/Observer/Graveyard.hpp \
    2527        $(top_srcdir)/src/CodePatterns/Observer/Notification.hpp \
    2628        $(top_srcdir)/src/CodePatterns/Observer/Observable.hpp \
     
    3032        $(top_srcdir)/src/CodePatterns/Observer/ObservedIterator.hpp \
    3133        $(top_srcdir)/src/CodePatterns/Observer/ObservedContainer_impl.hpp \
    32         $(top_srcdir)/src/CodePatterns/Observer/Relay.hpp
     34        $(top_srcdir)/src/CodePatterns/Observer/Relay.hpp \
     35        $(top_srcdir)/src/CodePatterns/Observer/Zombie.hpp
    3336
    3437OBSERVERDEBUGHEADER =
  • src/Observer/Observable.cpp

    r37d941 rb324a3  
    2727#include "CodePatterns/Observer/Notification.hpp"
    2828
     29//!> This function does nothing with the given Observable
     30void NoOp_informer(const Observable *)
     31{}
     32
     33Observable::graveyard_informer_t Observable::noop_informer(&NoOp_informer);
    2934
    3035// All infrastructure for the observer-pattern is bundled at a central place
     
    271276    callTable.erase(const_cast<Observable *>(this));
    272277  }
     278  graveyard_informer(this);
    273279}
    274280
     
    293299#endif
    294300  notification->removeObserver(target);
     301  graveyard_informer(this);
    295302}
    296303
     
    311318}
    312319
     320size_t Observable::getNumberOfObservers() const
     321{
     322  size_t ObserverCount = 0;
     323  {
     324    std::map<Observable*,callees_t>::const_iterator callTableiter =
     325        callTable.find(const_cast<Observable *>(this));
     326    // if not present, then we have zero observers
     327    if (callTableiter != callTable.end())
     328      ObserverCount += callTableiter->second.size();
     329  }
     330  {
     331    const ChannelMap::const_iterator iter =
     332        NotificationChannels.find(const_cast<Observable * const>(this));
     333    // if not present, then we have zero observers
     334    if (iter != NotificationChannels.end())
     335      for (Channels::NotificationTypetoRefMap::const_iterator channeliter = iter->second->ChannelMap.begin();
     336          channeliter != iter->second->ChannelMap.end();
     337          ++channeliter)
     338        ObserverCount += (channeliter->second)->getNumberOfObservers();
     339  }
     340  return ObserverCount;
     341}
     342
    313343/** Handles sub-observables that just got killed
    314344 *  when an sub-observerable dies we usually don't need to do anything
     
    321351 */
    322352Observable::Observable(std::string name) :
    323   Observer(Observer::BaseConstructor())
     353  Observer(Observer::BaseConstructor()),
     354  graveyard_informer(noop_informer)
    324355{
    325356#ifdef LOG_OBSERVER
  • src/Observer/unittests/Makefile.am

    r37d941 rb324a3  
    55
    66TESTS += \
     7        GraveyardUnitTest \
    78        ObservedContainerUnitTest \
    89        ObserverUnitTest
    910
    1011TESTSOURCES += \
     12        ../Observer/unittests/GraveyardUnitTest.cpp \
    1113        ../Observer/unittests/ObserverUnitTest.cpp \
    1214        ../Observer/unittests/ObservedContainerUnitTest.cpp \
     
    1416
    1517TESTHEADERS += \
     18        ../Observer/unittests/GraveyardUnitTest.hpp \
    1619        ../Observer/unittests/ObserverUnitTest.hpp \
    1720        ../Observer/unittests/ObservedContainerUnitTest.hpp
     
    3841        ../Helpers/libCodePatterns-Helpers-debug.la
    3942
     43GraveyardUnitTest_SOURCES = UnitTestMain.cpp \
     44        ../Observer/unittests/GraveyardUnitTest.cpp \
     45        ../Observer/unittests/GraveyardUnitTest.hpp \
     46        ../Observer/unittests/stubs/ObserverStub.cpp \
     47        ../Observer/unittests/stubs/ObserverStub.hpp
     48nodist_GraveyardUnitTest_SOURCES = \
     49        $(top_srcdir)/src/CodePatterns/Observer/Channels.hpp \
     50        $(top_srcdir)/src/CodePatterns/Observer/defs.hpp \
     51        $(top_srcdir)/src/CodePatterns/Observer/Notification.hpp \
     52        $(top_srcdir)/src/CodePatterns/Observer/Observer.hpp \
     53        $(top_srcdir)/src/CodePatterns/Observer/ObserverLog.hpp \
     54        $(top_srcdir)/src/CodePatterns/Observer/ObserverContainer.hpp \
     55        $(top_srcdir)/src/CodePatterns/Observer/ObserverContainer_impl.hpp \
     56        $(top_srcdir)/src/CodePatterns/Observer/ObserverIterator.hpp
     57GraveyardUnitTest_LDADD = \
     58        ../Observer/libCodePatterns-Observer-debug.la \
     59        ../Helpers/libCodePatterns-Helpers-debug.la
     60
    4061ObservedContainerUnitTest_SOURCES = UnitTestMain.cpp \
    4162        ../Observer/unittests/ObservedContainerUnitTest.cpp \
Note: See TracChangeset for help on using the changeset viewer.