# HG changeset patch # User deba # Date 1129286689 0 # Node ID 6a958ab38386e953039c92bdf2ca74b57b816e41 # Parent 75fe24093ded8253beeafada591efdfd7ff36d48 Extending observer interface It will be used in the indegmap, outdegmap types diff -r 75fe24093ded -r 6a958ab38386 lemon/bits/alteration_notifier.h --- a/lemon/bits/alteration_notifier.h Fri Oct 14 10:40:00 2005 +0000 +++ b/lemon/bits/alteration_notifier.h Fri Oct 14 10:44:49 2005 +0000 @@ -139,9 +139,9 @@ virtual void add(const Item&) = 0; /// \brief The member function to notificate the observer about - /// simulitem is added to the container. + /// more item is added to the container. /// - /// The add() member function notificates the observer about an item + /// The add() member function notificates the observer about more item /// is added to the container. It have to be overrided in the /// subclasses. @@ -160,12 +160,34 @@ virtual void erase(const Item&) = 0; + /// \brief The member function to notificate the observer about + /// more item is erased from the container. + /// + /// The erase() member function notificates the observer about more item + /// is erased from the container. It have to be overrided in the + /// subclasses. virtual void erase(const std::vector& items) { for (int i = 0; i < (int)items.size(); ++i) { erase(items[i]); } } + /// \brief Signal a property change on the given item. + /// + /// Signal a property change on the given item. It should + /// be used always with the commitChange() function. + /// This function is called always the property change. + /// The commitChange() is called always after the change. + virtual void signalChange(const Item&) {} + + /// \brief Commit the property change on the given item. + /// + /// Commit the property change on the given item. It should + /// be used always with the signalChange() function. + /// This function is called always the property change. + /// The commitChange() is called always after the change. + virtual void commitChange(const Item&) {} + /// \brief The member function to notificate the observer about the /// container is built. /// @@ -303,6 +325,31 @@ } } + /// \brief Signal a property change on the given item. + /// + /// Signal a property change on the given item. It should + /// be used always with the commitChange() function. + /// This function is called always the property change. + /// The commitChange() is called always after the change. + void signalChange(const Item& item) { + typename Container::iterator it; + for (it = container.begin(); it != container.end(); ++it) { + (*it)->signalChange(item); + } + } + + /// \brief Commit the property change on the given item. + /// + /// Commit the property change on the given item. It should + /// be used always with the signalChange() function. + /// This function is called always the property change. + /// The commitChange() is called always after the change. + void commitChange(const Item& item) { + typename Container::iterator it; + for (it = container.begin(); it != container.end(); ++it) { + (*it)->commitChange(item); + } + } /// \brief Notifies all the registered observers about the container is /// built. diff -r 75fe24093ded -r 6a958ab38386 lemon/list_graph.h --- a/lemon/list_graph.h Fri Oct 14 10:40:00 2005 +0000 +++ b/lemon/list_graph.h Fri Oct 14 10:44:49 2005 +0000 @@ -308,11 +308,6 @@ }; - typedef AlterableGraphExtender AlterableListGraphBase; - typedef IterableGraphExtender IterableListGraphBase; - typedef MappableGraphExtender MappableListGraphBase; - typedef ExtendableGraphExtender ExtendableListGraphBase; - typedef ClearableGraphExtender ClearableListGraphBase; typedef ErasableGraphExtender< ClearableGraphExtender< ExtendableGraphExtender< @@ -320,8 +315,8 @@ IterableGraphExtender< AlterableGraphExtender > > > > > ExtendedListGraphBase; -/// \addtogroup graphs -/// @{ + /// \addtogroup graphs + /// @{ ///A list graph class. @@ -342,7 +337,11 @@ ///\note The Edge's and OutEdge's ///referencing the changed edge remain ///valid. However InEdge's are invalidated. - void changeTarget(Edge e, Node n) { _changeTarget(e,n); } + void changeTarget(Edge e, Node n) { + getNotifier(Edge()).signalChange(e); + _changeTarget(e,n); + getNotifier(Edge()).commitChange(e); + } /// Changes the source of \c e to \c n /// Changes the source of \c e to \c n @@ -350,7 +349,11 @@ ///\note The Edge's and InEdge's ///referencing the changed edge remain ///valid. However OutEdge's are invalidated. - void changeSource(Edge e, Node n) { _changeSource(e,n); } + void changeSource(Edge e, Node n) { + getNotifier(Edge()).signalChange(e); + _changeSource(e,n); + getNotifier(Edge()).commitChange(e); + } /// Invert the direction of an edge. @@ -359,8 +362,10 @@ ///valid. However OutEdge's and InEdge's are invalidated. void reverseEdge(Edge e) { Node t=target(e); + getNotifier(Edge()).signalChange(e); _changeTarget(e,source(e)); _changeSource(e,t); + getNotifier(Edge()).commitChange(e); } ///Using this it possible to avoid the superfluous memory allocation. @@ -382,7 +387,7 @@ ///referencing a moved edge remain ///valid. However InEdge's and OutEdge's ///may be invalidated. - void contract(Node a,Node b,bool r=true) + void contract(Node a, Node b, bool r = true) { for(OutEdgeIt e(*this,b);e!=INVALID;) { OutEdgeIt f=e; @@ -562,8 +567,8 @@ AlterableUndirGraphExtender< UndirGraphExtender > > > > > > ExtendedUndirListGraphBase; -/// \addtogroup graphs -/// @{ + /// \addtogroup graphs + /// @{ ///An undirected list graph class. @@ -578,6 +583,66 @@ ///haven't been implemented yet. /// class UndirListGraph : public ExtendedUndirListGraphBase { + public: + typedef ExtendedUndirListGraphBase Parent; + /// \brief Changes the target of \c e to \c n + /// + /// Changes the target of \c e to \c n + /// + /// \note The Edge's and OutEdge's + /// referencing the changed edge remain + /// valid. However InEdge's are invalidated. + void changeTarget(UndirEdge e, Node n) { + getNotifier(UndirEdge()).signalChange(e); + getNotifier(Edge()).signalChange(direct(e, true)); + getNotifier(Edge()).signalChange(direct(e, false)); + _changeTarget(e,n); + getNotifier(UndirEdge()).commitChange(e); + getNotifier(Edge()).commitChange(direct(e, true)); + getNotifier(Edge()).commitChange(direct(e, false)); + } + /// Changes the source of \c e to \c n + /// + /// Changes the source of \c e to \c n + /// + ///\note The Edge's and InEdge's + ///referencing the changed edge remain + ///valid. However OutEdge's are invalidated. + void changeSource(UndirEdge e, Node n) { + getNotifier(UndirEdge()).signalChange(e); + getNotifier(Edge()).signalChange(direct(e, true)); + getNotifier(Edge()).signalChange(direct(e, false)); + _changeSource(e,n); + getNotifier(UndirEdge()).commitChange(e); + getNotifier(Edge()).commitChange(direct(e, true)); + getNotifier(Edge()).commitChange(direct(e, false)); + } + /// \brief Contract two nodes. + /// + /// This function contracts two nodes. + /// + /// Node \p b will be removed but instead of deleting + /// its neighboring edges, they will be joined to \p a. + /// The last parameter \p r controls whether to remove loops. \c true + /// means that loops will be removed. + /// + /// \note The Edges + /// referencing a moved edge remain + /// valid. + void contract(Node a, Node b, bool r = true) { + for(IncEdgeIt e(*this, b); e!=INVALID;) { + IncEdgeIt f = e; ++f; + if (r && runningNode(e) == a) { + erase(e); + } else if (source(e) == b) { + changeSource(e, a); + } else { + changeTarget(e, a); + } + e = f; + } + erase(b); + } }; diff -r 75fe24093ded -r 6a958ab38386 lemon/smart_graph.h --- a/lemon/smart_graph.h Fri Oct 14 10:40:00 2005 +0000 +++ b/lemon/smart_graph.h Fri Oct 14 10:44:49 2005 +0000 @@ -75,7 +75,8 @@ public: SmartGraphBase() : nodes(), edges() { } - SmartGraphBase(const SmartGraphBase &_g) : nodes(_g.nodes), edges(_g.edges) { } + SmartGraphBase(const SmartGraphBase &_g) + : nodes(_g.nodes), edges(_g.edges) { } typedef True NodeNumTag; typedef True EdgeNumTag; @@ -314,7 +315,14 @@ ///\todo It could be implemented in a bit faster way. Node split(Node n, bool connect = true) { - return _split(n,connect); + for (OutEdgeIt it(*this, n); it != INVALID; ++it) { + getNotifier(Edge()).signalChange(it); + } + Node b = _split(n,connect); + for (OutEdgeIt it(*this, b); it != INVALID; ++it) { + getNotifier(Edge()).commitChange(it); + } + return b; }