lemon/bits/alteration_notifier.h
changeset 2384 805c5a2a36dd
parent 2305 4a2236cc98a0
child 2386 81b47fc5c444
equal deleted inserted replaced
20:1d8a8f01f31e 21:650f8e4038eb
   141 
   141 
   142       /// \brief Default constructor.
   142       /// \brief Default constructor.
   143       ///
   143       ///
   144       /// Default constructor for ObserverBase.
   144       /// Default constructor for ObserverBase.
   145       /// 
   145       /// 
   146       ObserverBase() : notifier(0) {}
   146       ObserverBase() : _notifier(0) {}
   147 
   147 
   148       /// \brief Constructor which attach the observer into notifier.
   148       /// \brief Constructor which attach the observer into notifier.
   149       ///
   149       ///
   150       /// Constructor which attach the observer into notifier.
   150       /// Constructor which attach the observer into notifier.
   151       ObserverBase(AlterationNotifier& _notifier) {
   151       ObserverBase(AlterationNotifier& notifier) {
   152         attach(_notifier);
   152         attach(notifier);
   153       }
   153       }
   154 
   154 
   155       /// \brief Constructor which attach the obserever to the same notifier.
   155       /// \brief Constructor which attach the obserever to the same notifier.
   156       ///
   156       ///
   157       /// Constructor which attach the obserever to the same notifier as
   157       /// Constructor which attach the obserever to the same notifier as
   158       /// the other observer is attached to. 
   158       /// the other observer is attached to. 
   159       ObserverBase(const ObserverBase& copy) {
   159       ObserverBase(const ObserverBase& copy) {
   160 	if (copy.attached()) {
   160 	if (copy.attached()) {
   161           attach(*copy.getNotifier());
   161           attach(*copy._notifier());
   162 	}
   162 	}
   163       }
   163       }
   164 	
   164 	
   165       /// \brief Destructor
   165       /// \brief Destructor
   166       virtual ~ObserverBase() {
   166       virtual ~ObserverBase() {
   171 
   171 
   172       /// \brief Attaches the observer into an AlterationNotifier.
   172       /// \brief Attaches the observer into an AlterationNotifier.
   173       ///
   173       ///
   174       /// This member attaches the observer into an AlterationNotifier.
   174       /// This member attaches the observer into an AlterationNotifier.
   175       ///
   175       ///
   176       void attach(AlterationNotifier& _notifier) {
   176       void attach(AlterationNotifier& notifier) {
   177 	_notifier.attach(*this);
   177 	notifier.attach(*this);
   178       }
   178       }
   179       
   179       
   180       /// \brief Detaches the observer into an AlterationNotifier.
   180       /// \brief Detaches the observer into an AlterationNotifier.
   181       ///
   181       ///
   182       /// This member detaches the observer from an AlterationNotifier.
   182       /// This member detaches the observer from an AlterationNotifier.
   183       ///
   183       ///
   184       void detach() {
   184       void detach() {
   185         notifier->detach(*this);
   185         _notifier->detach(*this);
   186       }
   186       }
   187       
   187       
   188       /// \brief Gives back a pointer to the notifier which the map 
   188       /// \brief Gives back a pointer to the notifier which the map 
   189       /// attached into.
   189       /// attached into.
   190       ///
   190       ///
   191       /// This function gives back a pointer to the notifier which the map
   191       /// This function gives back a pointer to the notifier which the map
   192       /// attached into.
   192       /// attached into.
   193       ///
   193       ///
   194       Notifier* getNotifier() const { return const_cast<Notifier*>(notifier); }
   194       Notifier* notifier() const { return const_cast<Notifier*>(_notifier); }
   195       
   195       
   196       /// Gives back true when the observer is attached into a notifier.
   196       /// Gives back true when the observer is attached into a notifier.
   197       bool attached() const { return notifier != 0; }
   197       bool attached() const { return _notifier != 0; }
   198 
   198 
   199     private:
   199     private:
   200 
   200 
   201       ObserverBase& operator=(const ObserverBase& copy);
   201       ObserverBase& operator=(const ObserverBase& copy);
   202 
   202 
   203     protected:
   203     protected:
   204       
   204       
   205       Notifier* notifier;
   205       Notifier* _notifier;
   206       typename std::list<ObserverBase*>::iterator index;
   206       typename std::list<ObserverBase*>::iterator _index;
   207 
   207 
   208       /// \brief The member function to notificate the observer about an
   208       /// \brief The member function to notificate the observer about an
   209       /// item is added to the container.
   209       /// item is added to the container.
   210       ///
   210       ///
   211       /// The add() member function notificates the observer about an item
   211       /// The add() member function notificates the observer about an item
   259   protected:
   259   protected:
   260 
   260 
   261     const Container* container;
   261     const Container* container;
   262 
   262 
   263     typedef std::list<ObserverBase*> Observers; 
   263     typedef std::list<ObserverBase*> Observers; 
   264     Observers observers;
   264     Observers _observers;
   265 
   265 
   266 		
   266 		
   267   public:
   267   public:
   268 
   268 
   269     /// \brief Default constructor.
   269     /// \brief Default constructor.
   291     ///		
   291     ///		
   292     /// Destructor of the AlterationNotifier.
   292     /// Destructor of the AlterationNotifier.
   293     ///
   293     ///
   294     ~AlterationNotifier() {
   294     ~AlterationNotifier() {
   295       typename Observers::iterator it;
   295       typename Observers::iterator it;
   296       for (it = observers.begin(); it != observers.end(); ++it) {
   296       for (it = _observers.begin(); it != _observers.end(); ++it) {
   297 	(*it)->notifier = 0;
   297 	(*it)->_notifier = 0;
   298       }
   298       }
   299     }
   299     }
   300 
   300 
   301     /// \brief Sets the container.
   301     /// \brief Sets the container.
   302     ///
   302     ///
   344     }
   344     }
   345 		
   345 		
   346   protected:
   346   protected:
   347 
   347 
   348     void attach(ObserverBase& observer) {
   348     void attach(ObserverBase& observer) {
   349       observer.index = observers.insert(observers.begin(), &observer);
   349       observer._index = _observers.insert(_observers.begin(), &observer);
   350       observer.notifier = this;
   350       observer._notifier = this;
   351     } 
   351     } 
   352 
   352 
   353     void detach(ObserverBase& observer) {
   353     void detach(ObserverBase& observer) {
   354       observers.erase(observer.index);
   354       _observers.erase(observer._index);
   355       observer.index = observers.end();
   355       observer._index = _observers.end();
   356       observer.notifier = 0;
   356       observer._notifier = 0;
   357     }
   357     }
   358 
   358 
   359   public:
   359   public:
   360 	
   360 	
   361     /// \brief Notifies all the registed observers about an item added to 
   361     /// \brief Notifies all the registed observers about an item added to 
   365     /// the container.
   365     /// the container.
   366     /// 
   366     /// 
   367     void add(const Item& item) {
   367     void add(const Item& item) {
   368       typename Observers::reverse_iterator it;
   368       typename Observers::reverse_iterator it;
   369       try {
   369       try {
   370         for (it = observers.rbegin(); it != observers.rend(); ++it) {
   370         for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
   371           (*it)->add(item);
   371           (*it)->add(item);
   372         }
   372         }
   373       } catch (...) {
   373       } catch (...) {
   374         typename Observers::iterator jt;
   374         typename Observers::iterator jt;
   375         for (jt = it.base(); jt != observers.end(); ++jt) {
   375         for (jt = it.base(); jt != _observers.end(); ++jt) {
   376           (*jt)->erase(item);
   376           (*jt)->erase(item);
   377         }
   377         }
   378         throw;
   378         throw;
   379       }
   379       }
   380     }	
   380     }	
   386     /// the container.
   386     /// the container.
   387     /// 
   387     /// 
   388     void add(const std::vector<Item>& items) {
   388     void add(const std::vector<Item>& items) {
   389       typename Observers::reverse_iterator it;
   389       typename Observers::reverse_iterator it;
   390       try {
   390       try {
   391         for (it = observers.rbegin(); it != observers.rend(); ++it) {
   391         for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
   392           (*it)->add(items);
   392           (*it)->add(items);
   393         }
   393         }
   394       } catch (...) {
   394       } catch (...) {
   395         typename Observers::iterator jt;
   395         typename Observers::iterator jt;
   396         for (jt = it.base(); jt != observers.end(); ++jt) {
   396         for (jt = it.base(); jt != _observers.end(); ++jt) {
   397           (*jt)->erase(items);
   397           (*jt)->erase(items);
   398         }
   398         }
   399         throw;
   399         throw;
   400       }
   400       }
   401     }	
   401     }	
   405     ///	
   405     ///	
   406     /// It notifies all the registed observers about an item erased from 
   406     /// It notifies all the registed observers about an item erased from 
   407     /// the container.
   407     /// the container.
   408     /// 
   408     /// 
   409     void erase(const Item& item) throw() {
   409     void erase(const Item& item) throw() {
   410       typename Observers::iterator it = observers.begin();
   410       typename Observers::iterator it = _observers.begin();
   411       while (it != observers.end()) {
   411       while (it != _observers.end()) {
   412         try {
   412         try {
   413           (*it)->erase(item);
   413           (*it)->erase(item);
   414           ++it;
   414           ++it;
   415         } catch (const ImmediateDetach&) {
   415         } catch (const ImmediateDetach&) {
   416           it = observers.erase(it);
   416           it = _observers.erase(it);
   417           (*it)->index = observers.end();
   417           (*it)->_index = _observers.end();
   418           (*it)->notifier = 0;
   418           (*it)->_notifier = 0;
   419         }
   419         }
   420       }
   420       }
   421     }
   421     }
   422 
   422 
   423     /// \brief Notifies all the registed observers about more item erased  
   423     /// \brief Notifies all the registed observers about more item erased  
   425     ///	
   425     ///	
   426     /// It notifies all the registed observers about more item erased from 
   426     /// It notifies all the registed observers about more item erased from 
   427     /// the container.
   427     /// the container.
   428     /// 
   428     /// 
   429     void erase(const std::vector<Item>& items) {
   429     void erase(const std::vector<Item>& items) {
   430       typename Observers::iterator it = observers.begin();
   430       typename Observers::iterator it = _observers.begin();
   431       while (it != observers.end()) {
   431       while (it != _observers.end()) {
   432         try {
   432         try {
   433           (*it)->erase(items);
   433           (*it)->erase(items);
   434           ++it;
   434           ++it;
   435         } catch (const ImmediateDetach&) {
   435         } catch (const ImmediateDetach&) {
   436           it = observers.erase(it);
   436           it = _observers.erase(it);
   437           (*it)->index = observers.end();
   437           (*it)->_index = _observers.end();
   438           (*it)->notifier = 0;
   438           (*it)->_notifier = 0;
   439         }
   439         }
   440       }
   440       }
   441     }
   441     }
   442 
   442 
   443     /// \brief Notifies all the registed observers about the container is 
   443     /// \brief Notifies all the registed observers about the container is 
   446     /// Notifies all the registed observers about the container is built
   446     /// Notifies all the registed observers about the container is built
   447     /// from an empty container.
   447     /// from an empty container.
   448     void build() {
   448     void build() {
   449       typename Observers::reverse_iterator it;
   449       typename Observers::reverse_iterator it;
   450       try {
   450       try {
   451         for (it = observers.rbegin(); it != observers.rend(); ++it) {
   451         for (it = _observers.rbegin(); it != _observers.rend(); ++it) {
   452           (*it)->build();
   452           (*it)->build();
   453         }
   453         }
   454       } catch (...) {
   454       } catch (...) {
   455         typename Observers::iterator jt;
   455         typename Observers::iterator jt;
   456         for (jt = it.base(); jt != observers.end(); ++jt) {
   456         for (jt = it.base(); jt != _observers.end(); ++jt) {
   457           (*jt)->clear();
   457           (*jt)->clear();
   458         }
   458         }
   459         throw;
   459         throw;
   460       }
   460       }
   461     }
   461     }
   464     /// erased.
   464     /// erased.
   465     ///
   465     ///
   466     /// Notifies all the registed observers about all items are erased
   466     /// Notifies all the registed observers about all items are erased
   467     /// from the container.
   467     /// from the container.
   468     void clear() {
   468     void clear() {
   469       typename Observers::iterator it = observers.begin();
   469       typename Observers::iterator it = _observers.begin();
   470       while (it != observers.end()) {
   470       while (it != _observers.end()) {
   471         try {
   471         try {
   472           (*it)->clear();
   472           (*it)->clear();
   473           ++it;
   473           ++it;
   474         } catch (const ImmediateDetach&) {
   474         } catch (const ImmediateDetach&) {
   475           it = observers.erase(it);
   475           it = _observers.erase(it);
   476           (*it)->index = observers.end();
   476           (*it)->_index = _observers.end();
   477           (*it)->notifier = 0;
   477           (*it)->_notifier = 0;
   478         }
   478         }
   479       }
   479       }
   480     }
   480     }
   481   };
   481   };
   482 
   482