Ignore:
Timestamp:
Feb 25, 2010, 2:32:35 PM (16 years ago)
Author:
Frederik Heber <heber@…>
Children:
d06198
Parents:
44becc
Message:

MEMLEAK: Observable::signOff() erases its own iterator, some more documentation added

  • Observable::signOff() erases a given Observer from the Observer list, but it had no backup iterator to go on afterwards.
Location:
molecuilder/src/Patterns
Files:
2 edited

Legend:

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

    r44becc r36c5cf  
    2424// See [Gamma et al, 1995] p. 297
    2525
    26 map<Observable*, int> Observable::depth;
    27 map<Observable*,multimap<int,Observer*>*> Observable::callTable;
    28 set<Observable*> Observable::busyObservables;
    29 
    30 // The two functions start_observer_internal and finish_observer_internal
    31 // have to be used together at all time. Never use these functions directly
    32 // START_OBSERVER and FINISH_OBSERVER also construct a bogus while(0) loop
    33 // thus producing compiler-errors whenever only one is used
    34 
     26map<Observable*, int> Observable::depth;  //!< Map of Observables to the depth of the DAG of Observers
     27map<Observable*,multimap<int,Observer*>*> Observable::callTable; //!< Table for each Observable of all its Observers
     28set<Observable*> Observable::busyObservables; //!< Set of Observables that are currently busy notifying their sign-on'ed Observers
     29
     30/** Attaching Sub-observables to Observables.
     31 * Increases entry in Observable::depth for this \a *publisher by one.
     32 *
     33 * The two functions \sa start_observer_internal() and \sa finish_observer_internal()
     34 * have to be used together at all time. Never use these functions directly
     35 * START_OBSERVER and FINISH_OBSERVER also construct a bogus while(0) loop
     36 * thus producing compiler-errors whenever only one is used.
     37 * \param *publisher reference of sub-observable
     38 */
    3539void Observable::start_observer_internal(Observable *publisher){
    3640  // increase the count for this observable by one
     
    4044}
    4145
     46/** Detaching Sub-observables from Observables.
     47 * Decreases entry in Observable::depth for this \a *publisher by one. If zero, we
     48 * start notifying all our Observers.
     49 *
     50 * The two functions start_observer_internal() and finish_observer_internal()
     51 * have to be used together at all time. Never use these functions directly
     52 * START_OBSERVER and FINISH_OBSERVER also construct a bogus while(0) loop
     53 * thus producing compiler-errors whenever only one is used.
     54 * \param *publisher reference of sub-observable
     55 */
    4256void Observable::finish_observer_internal(Observable *publisher){
    4357  // decrease the count for this observable
     
    5367}
    5468
     69/** Constructor for Observable Protector.
     70 * Basically, calls start_observer_internal(). Hence use this class instead of
     71 * calling the function directly.
     72 *
     73 * \param *protege Observable to be protected.
     74 */
    5575Observable::_Observable_protector::_Observable_protector(Observable *_protege) :
    5676  protege(_protege)
     
    5979}
    6080
     81/** Destructor for Observable Protector.
     82 * Basically, calls finish_observer_internal(). Hence use this class instead of
     83 * calling the function directly.
     84 *
     85 * \param *protege Observable to be protected.
     86 */
    6187Observable::_Observable_protector::~_Observable_protector()
    6288{
     
    6692/************* Notification mechanism for observables **************/
    6793
    68 
     94/** Notify all Observers of changes.
     95 * Puts \a *this into Observable::busyObservables, calls Observer::update() for all in callee_t
     96 * and removes from busy list.
     97 */
    6998void Observable::notifyAll() {
    7099  // we are busy notifying others right now
     
    87116}
    88117
    89 // this handles passing on updates from sub-Observables
     118/** Handles passing on updates from sub-Observables.
     119 * Mimicks basically the Observer::update() function.
     120 *
     121 * \param *publisher The \a *this we observe.
     122 */
    90123void Observable::update(Observable *publisher) {
    91124  // circle detection
     
    109142}
    110143
    111 // methods to sign-on and off
     144/** Sign on an Observer to this Observable.
     145 * Puts \a *target into Observable::callTable list.
     146 * \param *target Observer
     147 * \param priority number in [-20,20]
     148 */
    112149void Observable::signOn(Observer *target,int priority) {
    113150  assert(priority>=-20 && priority<=+20 && "Priority out of range [-20:+20]");
     
    130167}
    131168
     169/** Sign off an Observer from this Observable.
     170 * Removes \a *target from Observable::callTable list.
     171 * \param *target Observer
     172 */
    132173void Observable::signOff(Observer *target) {
    133174  assert(callTable.count(this) && "SignOff called for an Observable without Observers.");
    134175  callees_t *callees = callTable[this];
    135176  callees_t::iterator iter;
    136   for(iter=callees->begin();iter!=callees->end();iter++) {
    137     if((*iter).second == target)
    138       callees->erase(iter);
     177  callees_t::iterator deliter;
     178  for(iter=callees->begin();iter!=callees->end();) {
     179    deliter=iter++;
     180    if((*deliter).second == target)
     181      callees->erase(deliter);
    139182  }
    140183  if(callees->empty()){
     
    144187}
    145188
    146 // when an sub-observerable dies we usually don't need to do anything
     189/** Handles sub-observables that just got killed
     190 *  when an sub-observerable dies we usually don't need to do anything
     191 *  \param *publisher Sub-Observable.
     192 */
    147193void Observable::subjectKilled(Observable *publisher){
    148194}
    149195
     196/** Constructor for class Observable.
     197 */
    150198Observable::Observable()
    151199{}
    152200
    153 // when an observable is deleted, we let all our observers know
     201/** Destructor for class Observable.
     202 * When an observable is deleted, we let all our observers know. \sa Observable::subjectKilled().
     203 */
    154204Observable::~Observable()
    155205{
     
    166216}
    167217
     218/** Constructor for class Observer.
     219 */
    168220Observer::Observer()
    169221{}
    170222
     223/** Destructor for class Observer.
     224 */
    171225Observer::~Observer()
    172226{}
  • molecuilder/src/Patterns/Observer.hpp

    r44becc r36c5cf  
    1616 *
    1717 * Observers register themselves with the observables to be notified when something changes.
    18  * In the Observable code that changes attributes should be started with OBSERVE;. This macro
     18 * In the Observable code that changes, attributes should be started with OBSERVE;. This macro
    1919 * locks the observer mechanism while changes are done. At the end of the scope in which the
    2020 * macro was placed the lock is released. When the last lock is released all changes are
Note: See TracChangeset for help on using the changeset viewer.