Several changes. \n If new map is added to mapstorage it emits signal with the name of the new map. This was important, because from now on not only tha mapwin should be updated. \n Furthermore algobox gets a pointer to mapstorage instead of only the mapnames from it. This is important because without it it would be complicated to pass all of the required maps to algobox.
2 * lemon/notifier.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
18 #define LEMON_ALTERATION_OBSERVER_REGISTRY_H
23 ///\ingroup graphmapfactory
25 ///\brief Observer registry for graph alteration observers.
29 /// \addtogroup graphmapfactory
32 /// \brief Registry class to register objects observes alterations in
35 /// This class is a registry for the objects which observe the
36 /// alterations in a container. The alteration observers can be attached
37 /// to and detached from the registry. The observers have to inherit
38 /// from the \ref AlterationNotifier::ObserverBase and override
39 /// the virtual functions in that.
41 /// The most important application of the alteration observing is the
42 /// dynamic map implementation.
44 /// \param _Item The item type what the observers are observing, usually
47 /// \author Balazs Dezso
49 template <typename _Item>
50 class AlterationNotifier {
54 /// ObserverBase is the base class for the observers.
56 /// ObserverBase is the abstract base class for the observers.
57 /// It will be notified about an item was inserted into or
58 /// erased from the graph.
60 /// The observer interface contains some pure virtual functions
61 /// to override. The add() and erase() functions are
62 /// to notify the oberver when one item is added or
65 /// The build() and clear() members are to notify the observer
66 /// about the container is built from an empty container or
67 /// is cleared to an empty container.
69 /// \author Balazs Dezso
73 typedef AlterationNotifier Registry;
75 friend class AlterationNotifier;
77 /// \brief Default constructor.
79 /// Default constructor for ObserverBase.
81 ObserverBase() : registry(0) {}
83 ObserverBase(const ObserverBase& copy) {
84 if (copy.attached()) {
85 copy.getRegistry()->attach(*this);
89 virtual ~ObserverBase() {}
91 /// \brief Attaches the observer into an AlterationNotifier.
93 /// This member attaches the observer into an AlterationNotifier.
95 void attach(AlterationNotifier& r) {
97 registry->attach(*this);
100 /// \brief Detaches the observer into an AlterationNotifier.
102 /// This member detaches the observer from an AlterationNotifier.
106 registry->detach(*this);
111 /// Gives back a pointer to the registry what the map attached into.
113 /// This function gives back a pointer to the registry what the map
116 Registry* getRegistry() const { return const_cast<Registry*>(registry); }
118 /// Gives back true when the observer is attached into a registry.
119 bool attached() const { return registry != 0; }
123 ObserverBase& operator=(const ObserverBase& copy);
130 /// \brief The member function to notificate the observer about an
131 /// item is added to the container.
133 /// The add() member function notificates the observer about an item
134 /// is added to the container. It have to be overrided in the
137 virtual void add(const Item&) = 0;
139 /// \brief The member function to notificate the observer about
140 /// more item is added to the container.
142 /// The add() member function notificates the observer about more item
143 /// is added to the container. It have to be overrided in the
146 virtual void add(const std::vector<Item>& items) {
147 for (int i = 0; i < (int)items.size(); ++i) {
152 /// \brief The member function to notificate the observer about an
153 /// item is erased from the container.
155 /// The erase() member function notificates the observer about an
156 /// item is erased from the container. It have to be overrided in
159 virtual void erase(const Item&) = 0;
161 /// \brief The member function to notificate the observer about
162 /// more item is erased from the container.
164 /// The erase() member function notificates the observer about more item
165 /// is erased from the container. It have to be overrided in the
167 virtual void erase(const std::vector<Item>& items) {
168 for (int i = 0; i < (int)items.size(); ++i) {
173 /// \brief The member function to notificate the observer about the
174 /// container is built.
176 /// The build() member function notificates the observer about the
177 /// container is built from an empty container. It have to be
178 /// overrided in the subclasses.
180 virtual void build() = 0;
182 /// \brief The member function to notificate the observer about all
183 /// items are erased from the container.
185 /// The clear() member function notificates the observer about all
186 /// items are erased from the container. It have to be overrided in
189 virtual void clear() = 0;
196 typedef std::vector<ObserverBase*> Container;
203 /// Default constructor.
206 /// The default constructor of the AlterationNotifier.
207 /// It creates an empty registry.
208 AlterationNotifier() {}
210 /// Copy Constructor of the AlterationNotifier.
212 /// Copy constructor of the AlterationNotifier.
213 /// It creates only an empty registry because the copiable
214 /// registry's observers have to be registered still into that registry.
215 AlterationNotifier(const AlterationNotifier&) {}
219 /// Assign operator for the AlterationNotifier.
220 /// It makes the notifier only empty because the copiable
221 /// notifier's observers have to be registered still into that registry.
222 AlterationNotifier& operator=(const AlterationNotifier&) {
223 typename Container::iterator it;
224 for (it = container.begin(); it != container.end(); ++it) {
231 /// Destructor of the AlterationNotifier.
233 ~AlterationNotifier() {
234 typename Container::iterator it;
235 for (it = container.begin(); it != container.end(); ++it) {
243 void attach(ObserverBase& observer) {
244 container.push_back(&observer);
245 observer.registry = this;
246 observer.registry_index = container.size()-1;
249 void detach(ObserverBase& base) {
250 container.back()->registry_index = base.registry_index;
251 container[base.registry_index] = container.back();
252 container.pop_back();
258 /// \brief Notifies all the registered observers about an Item added to
261 /// It notifies all the registered observers about an Item added to
264 void add(const Item& item) {
265 typename Container::iterator it;
266 for (it = container.begin(); it != container.end(); ++it) {
271 /// \brief Notifies all the registered observers about more Item added to
274 /// It notifies all the registered observers about more Item added to
277 void add(const std::vector<Item>& items) {
278 typename Container::iterator it;
279 for (it = container.begin(); it != container.end(); ++it) {
284 /// \brief Notifies all the registered observers about an Item erased from
287 /// It notifies all the registered observers about an Item erased from
290 void erase(const Item& key) {
291 typename Container::iterator it;
292 for (it = container.begin(); it != container.end(); ++it) {
297 /// \brief Notifies all the registered observers about more Item erased
298 /// from the container.
300 /// It notifies all the registered observers about more Item erased from
303 void erase(const std::vector<Item>& items) {
304 typename Container::iterator it;
305 for (it = container.begin(); it != container.end(); ++it) {
310 /// \brief Notifies all the registered observers about the container is
313 /// Notifies all the registered observers about the container is built
314 /// from an empty container.
316 typename Container::iterator it;
317 for (it = container.begin(); it != container.end(); ++it) {
323 /// \brief Notifies all the registered observers about all Items are
326 /// Notifies all the registered observers about all Items are erased
327 /// from the container.
329 typename Container::iterator it;
330 for (it = container.begin(); it != container.end(); ++it) {
337 /// \brief Class to extend a graph with the functionality of alteration
340 /// AlterableGraphExtender extends the _Base graphs functionality with
341 /// the possibility of alteration observing. It defines two observer
342 /// registrys for the nodes and mapes.
344 /// \todo Document what "alteration observing" is. And probably find a
345 /// better (shorter) name.
347 /// \param _Base is the base class to extend.
349 /// \pre _Base is conform to the BaseGraphComponent concept.
351 /// \post AlterableGraphExtender<_Base> is conform to the
352 /// AlterableGraphComponent concept.
354 /// \author Balazs Dezso
356 template <typename _Base>
357 class AlterableGraphExtender : public _Base {
360 typedef AlterableGraphExtender Graph;
361 typedef _Base Parent;
363 typedef typename Parent::Node Node;
364 typedef typename Parent::Edge Edge;
366 /// The edge observer registry.
367 typedef AlterationNotifier<Edge> EdgeNotifier;
368 /// The node observer registry.
369 typedef AlterationNotifier<Node> NodeNotifier;
374 mutable EdgeNotifier edge_notifier;
376 mutable NodeNotifier node_notifier;
380 /// \brief Gives back the edge alteration notifier.
382 /// Gives back the edge alteration notifier.
383 EdgeNotifier& getNotifier(Edge) const {
384 return edge_notifier;
387 /// \brief Gives back the node alteration notifier.
389 /// Gives back the node alteration notifier.
390 NodeNotifier& getNotifier(Node) const {
391 return node_notifier;
394 ~AlterableGraphExtender() {
395 node_notifier.clear();
396 edge_notifier.clear();
402 template <typename _Base>
403 class AlterableEdgeSetExtender : public _Base {
406 typedef AlterableEdgeSetExtender Graph;
407 typedef _Base Parent;
409 typedef typename Parent::Edge Edge;
411 /// The edge observer registry.
412 typedef AlterationNotifier<Edge> EdgeNotifier;
416 mutable EdgeNotifier edge_notifier;
420 /// \brief Gives back the edge alteration notifier.
422 /// Gives back the edge alteration notifier.
423 EdgeNotifier& getNotifier(Edge) const {
424 return edge_notifier;
427 ~AlterableEdgeSetExtender() {
428 edge_notifier.clear();
433 /// \brief Class to extend an undirected graph with the functionality of
434 /// alteration observing.
438 /// \sa AlterableGraphExtender
440 /// \bug This should be done some other way. Possibilities: template
441 /// specialization (not very easy, if at all possible); some kind of
442 /// enable_if boost technique?
444 template <typename _Base>
445 class AlterableUndirGraphExtender
446 : public AlterableGraphExtender<_Base> {
449 typedef AlterableUndirGraphExtender Graph;
450 typedef AlterableGraphExtender<_Base> Parent;
452 typedef typename Parent::UndirEdge UndirEdge;
454 /// The edge observer registry.
455 typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
459 mutable UndirEdgeNotifier undir_edge_notifier;
463 using Parent::getNotifier;
464 UndirEdgeNotifier& getNotifier(UndirEdge) const {
465 return undir_edge_notifier;
468 ~AlterableUndirGraphExtender() {
469 undir_edge_notifier.clear();
473 template <typename _Base>
474 class AlterableUndirEdgeSetExtender
475 : public AlterableEdgeSetExtender<_Base> {
478 typedef AlterableUndirEdgeSetExtender Graph;
479 typedef AlterableEdgeSetExtender<_Base> Parent;
481 typedef typename Parent::UndirEdge UndirEdge;
483 typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
487 mutable UndirEdgeNotifier undir_edge_notifier;
491 using Parent::getNotifier;
492 UndirEdgeNotifier& getNotifier(UndirEdge) const {
493 return undir_edge_notifier;
496 ~AlterableUndirEdgeSetExtender() {
497 undir_edge_notifier.clear();
503 template <typename _Base>
504 class AlterableUndirBipartiteGraphExtender : public _Base {
507 typedef _Base Parent;
508 typedef AlterableUndirBipartiteGraphExtender Graph;
510 typedef typename Parent::Node Node;
511 typedef typename Parent::LowerNode LowerNode;
512 typedef typename Parent::UpperNode UpperNode;
513 typedef typename Parent::Edge Edge;
514 typedef typename Parent::UndirEdge UndirEdge;
517 typedef AlterationNotifier<Node> NodeNotifier;
518 typedef AlterationNotifier<LowerNode> LowerNodeNotifier;
519 typedef AlterationNotifier<UpperNode> UpperNodeNotifier;
520 typedef AlterationNotifier<Edge> EdgeNotifier;
521 typedef AlterationNotifier<UndirEdge> UndirEdgeNotifier;
525 mutable NodeNotifier nodeNotifier;
526 mutable LowerNodeNotifier lowerNodeNotifier;
527 mutable UpperNodeNotifier upperNodeNotifier;
528 mutable EdgeNotifier edgeNotifier;
529 mutable UndirEdgeNotifier undirEdgeNotifier;
533 NodeNotifier& getNotifier(Node) const {
537 LowerNodeNotifier& getNotifier(LowerNode) const {
538 return lowerNodeNotifier;
541 UpperNodeNotifier& getNotifier(UpperNode) const {
542 return upperNodeNotifier;
545 EdgeNotifier& getNotifier(Edge) const {
549 UndirEdgeNotifier& getNotifier(UndirEdge) const {
550 return undirEdgeNotifier;
553 ~AlterableUndirBipartiteGraphExtender() {
554 nodeNotifier.clear();
555 lowerNodeNotifier.clear();
556 upperNodeNotifier.clear();
557 edgeNotifier.clear();
558 undirEdgeNotifier.clear();