Extending observer interface
authordeba
Fri, 14 Oct 2005 10:44:49 +0000
changeset 17186a958ab38386
parent 1717 75fe24093ded
child 1719 674182524bd9
Extending observer interface
It will be used in the indegmap, outdegmap types
lemon/bits/alteration_notifier.h
lemon/list_graph.h
lemon/smart_graph.h
     1.1 --- a/lemon/bits/alteration_notifier.h	Fri Oct 14 10:40:00 2005 +0000
     1.2 +++ b/lemon/bits/alteration_notifier.h	Fri Oct 14 10:44:49 2005 +0000
     1.3 @@ -139,9 +139,9 @@
     1.4        virtual void add(const Item&) = 0;
     1.5  
     1.6        /// \brief The member function to notificate the observer about 
     1.7 -      /// simulitem is added to the container.
     1.8 +      /// more item is added to the container.
     1.9        ///
    1.10 -      /// The add() member function notificates the observer about an item
    1.11 +      /// The add() member function notificates the observer about more item
    1.12        /// is added to the container. It have to be overrided in the
    1.13        /// subclasses.
    1.14  
    1.15 @@ -160,12 +160,34 @@
    1.16  	
    1.17        virtual void erase(const Item&) = 0;
    1.18  
    1.19 +      /// \brief The member function to notificate the observer about 
    1.20 +      /// more item is erased from the container.
    1.21 +      ///
    1.22 +      /// The erase() member function notificates the observer about more item
    1.23 +      /// is erased from the container. It have to be overrided in the
    1.24 +      /// subclasses.
    1.25        virtual void erase(const std::vector<Item>& items) {
    1.26  	for (int i = 0; i < (int)items.size(); ++i) {
    1.27  	  erase(items[i]);
    1.28  	}
    1.29        }
    1.30  
    1.31 +      /// \brief Signal a property change on the given item.
    1.32 +      ///
    1.33 +      /// Signal a property change on the given item. It should
    1.34 +      /// be used always with the commitChange() function.
    1.35 +      /// This function is called always the property change.
    1.36 +      /// The commitChange() is called always after the change.
    1.37 +      virtual void signalChange(const Item&) {}
    1.38 +
    1.39 +      /// \brief Commit the property change on the given item.
    1.40 +      ///
    1.41 +      /// Commit the property change on the given item. It should
    1.42 +      /// be used always with the signalChange() function.
    1.43 +      /// This function is called always the property change.
    1.44 +      /// The commitChange() is called always after the change.
    1.45 +      virtual void commitChange(const Item&) {}
    1.46 +
    1.47        /// \brief The member function to notificate the observer about the
    1.48        /// container is built.
    1.49        ///
    1.50 @@ -303,6 +325,31 @@
    1.51        }
    1.52      }
    1.53      
    1.54 +    /// \brief Signal a property change on the given item.
    1.55 +    ///
    1.56 +    /// Signal a property change on the given item. It should
    1.57 +    /// be used always with the commitChange() function.
    1.58 +    /// This function is called always the property change.
    1.59 +    /// The commitChange() is called always after the change.
    1.60 +    void signalChange(const Item& item) {
    1.61 +      typename Container::iterator it;
    1.62 +      for (it = container.begin(); it != container.end(); ++it) {
    1.63 +	(*it)->signalChange(item);
    1.64 +      }
    1.65 +    }
    1.66 +    
    1.67 +    /// \brief Commit the property change on the given item.
    1.68 +    ///
    1.69 +    /// Commit the property change on the given item. It should
    1.70 +    /// be used always with the signalChange() function.
    1.71 +    /// This function is called always the property change.
    1.72 +    /// The commitChange() is called always after the change.
    1.73 +    void commitChange(const Item& item) {
    1.74 +      typename Container::iterator it;
    1.75 +      for (it = container.begin(); it != container.end(); ++it) {
    1.76 +	(*it)->commitChange(item);
    1.77 +      }
    1.78 +    }
    1.79  
    1.80      /// \brief Notifies all the registered observers about the container is 
    1.81      /// built.
     2.1 --- a/lemon/list_graph.h	Fri Oct 14 10:40:00 2005 +0000
     2.2 +++ b/lemon/list_graph.h	Fri Oct 14 10:44:49 2005 +0000
     2.3 @@ -308,11 +308,6 @@
     2.4  
     2.5    };
     2.6  
     2.7 -  typedef AlterableGraphExtender<ListGraphBase> AlterableListGraphBase;
     2.8 -  typedef IterableGraphExtender<AlterableListGraphBase> IterableListGraphBase;
     2.9 -  typedef MappableGraphExtender<IterableListGraphBase> MappableListGraphBase;
    2.10 -  typedef ExtendableGraphExtender<MappableListGraphBase> ExtendableListGraphBase;
    2.11 -  typedef ClearableGraphExtender<ExtendableListGraphBase> ClearableListGraphBase;
    2.12    typedef ErasableGraphExtender<
    2.13      ClearableGraphExtender<
    2.14      ExtendableGraphExtender<
    2.15 @@ -320,8 +315,8 @@
    2.16      IterableGraphExtender<
    2.17      AlterableGraphExtender<ListGraphBase> > > > > > ExtendedListGraphBase;
    2.18  
    2.19 -/// \addtogroup graphs
    2.20 -/// @{
    2.21 +  /// \addtogroup graphs
    2.22 +  /// @{
    2.23  
    2.24    ///A list graph class.
    2.25  
    2.26 @@ -342,7 +337,11 @@
    2.27      ///\note The <tt>Edge</tt>'s and <tt>OutEdge</tt>'s
    2.28      ///referencing the changed edge remain
    2.29      ///valid. However <tt>InEdge</tt>'s are invalidated.
    2.30 -    void changeTarget(Edge e, Node n) { _changeTarget(e,n); }
    2.31 +    void changeTarget(Edge e, Node n) { 
    2.32 +      getNotifier(Edge()).signalChange(e); 
    2.33 +      _changeTarget(e,n); 
    2.34 +      getNotifier(Edge()).commitChange(e); 
    2.35 +    }
    2.36      /// Changes the source of \c e to \c n
    2.37  
    2.38      /// Changes the source of \c e to \c n
    2.39 @@ -350,7 +349,11 @@
    2.40      ///\note The <tt>Edge</tt>'s and <tt>InEdge</tt>'s
    2.41      ///referencing the changed edge remain
    2.42      ///valid. However <tt>OutEdge</tt>'s are invalidated.
    2.43 -    void changeSource(Edge e, Node n) { _changeSource(e,n); }
    2.44 +    void changeSource(Edge e, Node n) { 
    2.45 +      getNotifier(Edge()).signalChange(e); 
    2.46 +      _changeSource(e,n);
    2.47 +      getNotifier(Edge()).commitChange(e); 
    2.48 +    }
    2.49  
    2.50      /// Invert the direction of an edge.
    2.51  
    2.52 @@ -359,8 +362,10 @@
    2.53      ///valid. However <tt>OutEdge</tt>'s  and <tt>InEdge</tt>'s are invalidated.
    2.54      void reverseEdge(Edge e) {
    2.55        Node t=target(e);
    2.56 +      getNotifier(Edge()).signalChange(e); 
    2.57        _changeTarget(e,source(e));
    2.58        _changeSource(e,t);
    2.59 +      getNotifier(Edge()).commitChange(e); 
    2.60      }
    2.61  
    2.62      ///Using this it possible to avoid the superfluous memory allocation.
    2.63 @@ -382,7 +387,7 @@
    2.64      ///referencing a moved edge remain
    2.65      ///valid. However <tt>InEdge</tt>'s and <tt>OutEdge</tt>'s
    2.66      ///may be invalidated.
    2.67 -    void contract(Node a,Node b,bool r=true) 
    2.68 +    void contract(Node a, Node b, bool r = true) 
    2.69      {
    2.70        for(OutEdgeIt e(*this,b);e!=INVALID;) {
    2.71  	OutEdgeIt f=e;
    2.72 @@ -562,8 +567,8 @@
    2.73      AlterableUndirGraphExtender<
    2.74      UndirGraphExtender<ListGraphBase> > > > > > > ExtendedUndirListGraphBase;
    2.75  
    2.76 -/// \addtogroup graphs
    2.77 -/// @{
    2.78 +  /// \addtogroup graphs
    2.79 +  /// @{
    2.80  
    2.81    ///An undirected list graph class.
    2.82  
    2.83 @@ -578,6 +583,66 @@
    2.84    ///haven't been implemented yet.
    2.85    ///
    2.86    class UndirListGraph : public ExtendedUndirListGraphBase {
    2.87 +  public:
    2.88 +    typedef ExtendedUndirListGraphBase Parent;
    2.89 +    /// \brief Changes the target of \c e to \c n
    2.90 +    ///
    2.91 +    /// Changes the target of \c e to \c n
    2.92 +    ///
    2.93 +    /// \note The <tt>Edge</tt>'s and <tt>OutEdge</tt>'s
    2.94 +    /// referencing the changed edge remain
    2.95 +    /// valid. However <tt>InEdge</tt>'s are invalidated.
    2.96 +    void changeTarget(UndirEdge e, Node n) { 
    2.97 +      getNotifier(UndirEdge()).signalChange(e); 
    2.98 +      getNotifier(Edge()).signalChange(direct(e, true)); 
    2.99 +      getNotifier(Edge()).signalChange(direct(e, false)); 
   2.100 +      _changeTarget(e,n); 
   2.101 +      getNotifier(UndirEdge()).commitChange(e);
   2.102 +      getNotifier(Edge()).commitChange(direct(e, true)); 
   2.103 +      getNotifier(Edge()).commitChange(direct(e, false)); 
   2.104 +    }
   2.105 +    /// Changes the source of \c e to \c n
   2.106 +    ///
   2.107 +    /// Changes the source of \c e to \c n
   2.108 +    ///
   2.109 +    ///\note The <tt>Edge</tt>'s and <tt>InEdge</tt>'s
   2.110 +    ///referencing the changed edge remain
   2.111 +    ///valid. However <tt>OutEdge</tt>'s are invalidated.
   2.112 +    void changeSource(UndirEdge e, Node n) { 
   2.113 +      getNotifier(UndirEdge()).signalChange(e); 
   2.114 +      getNotifier(Edge()).signalChange(direct(e, true)); 
   2.115 +      getNotifier(Edge()).signalChange(direct(e, false)); 
   2.116 +      _changeSource(e,n); 
   2.117 +      getNotifier(UndirEdge()).commitChange(e);
   2.118 +      getNotifier(Edge()).commitChange(direct(e, true)); 
   2.119 +      getNotifier(Edge()).commitChange(direct(e, false)); 
   2.120 +    }
   2.121 +    /// \brief Contract two nodes.
   2.122 +    ///
   2.123 +    /// This function contracts two nodes.
   2.124 +    ///
   2.125 +    /// Node \p b will be removed but instead of deleting
   2.126 +    /// its neighboring edges, they will be joined to \p a.
   2.127 +    /// The last parameter \p r controls whether to remove loops. \c true
   2.128 +    /// means that loops will be removed.
   2.129 +    ///
   2.130 +    /// \note The <tt>Edge</tt>s
   2.131 +    /// referencing a moved edge remain
   2.132 +    /// valid.
   2.133 +    void contract(Node a, Node b, bool r = true) {
   2.134 +      for(IncEdgeIt e(*this, b); e!=INVALID;) {
   2.135 +	IncEdgeIt f = e; ++f;
   2.136 +	if (r && runningNode(e) == a) {
   2.137 +	  erase(e);
   2.138 +	} else if (source(e) == b) {
   2.139 +	  changeSource(e, a);
   2.140 +	} else {
   2.141 +	  changeTarget(e, a);
   2.142 +	}
   2.143 +	e = f;
   2.144 +      }
   2.145 +      erase(b);
   2.146 +    }
   2.147    };
   2.148  
   2.149    
     3.1 --- a/lemon/smart_graph.h	Fri Oct 14 10:40:00 2005 +0000
     3.2 +++ b/lemon/smart_graph.h	Fri Oct 14 10:44:49 2005 +0000
     3.3 @@ -75,7 +75,8 @@
     3.4    public:
     3.5  
     3.6      SmartGraphBase() : nodes(), edges() { }
     3.7 -    SmartGraphBase(const SmartGraphBase &_g) : nodes(_g.nodes), edges(_g.edges) { }
     3.8 +    SmartGraphBase(const SmartGraphBase &_g) 
     3.9 +      : nodes(_g.nodes), edges(_g.edges) { }
    3.10      
    3.11      typedef True NodeNumTag;
    3.12      typedef True EdgeNumTag;
    3.13 @@ -314,7 +315,14 @@
    3.14      ///\todo It could be implemented in a bit faster way.
    3.15      Node split(Node n, bool connect = true) 
    3.16      {
    3.17 -      return _split(n,connect);
    3.18 +      for (OutEdgeIt it(*this, n); it != INVALID; ++it) {
    3.19 +	getNotifier(Edge()).signalChange(it);
    3.20 +      }
    3.21 +      Node b = _split(n,connect);
    3.22 +      for (OutEdgeIt it(*this, b); it != INVALID; ++it) {
    3.23 +	getNotifier(Edge()).commitChange(it);
    3.24 +      }
    3.25 +      return b;
    3.26      }
    3.27    
    3.28