COIN-OR::LEMON - Graph Library

source: lemon-0.x/src/lemon/alteration_observer_registry.h @ 948:bc86b64f958e

Last change on this file since 948:bc86b64f958e was 946:c94ef40a22ce, checked in by Mihaly Barasz, 16 years ago

The graph_factory branch (@ 1321) has been merged to trunk.

File size: 9.5 KB
Line 
1/* -*- C++ -*-
2 * src/lemon/observer_registry.h - Part of LEMON, a generic C++ optimization library
3 *
4 * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
6 *
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.
10 *
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
13 * purpose.
14 *
15 */
16
17#ifndef LEMON_ALTERATION_OBSERVER_REGISTRY_H
18#define LEMON_ALTERATION_OBSERVER_REGISTRY_H
19
20#include <vector>
21#include <algorithm>
22
23///\ingroup graphmaps
24///\file
25///\brief Observer registry for graph alteration observers.
26
27using namespace std;
28
29namespace lemon {
30
31  /// \addtogroup graphmaps
32  /// @{
33
34  /// Registry class to register objects observes alterations in the graph.
35
36  /// This class is a registry for the objects which observe the
37  /// alterations in a container. The alteration observers can be attached
38  /// to and detached from the registry. The observers have to inherit
39  /// from the \ref AlterationObserverRegistry::ObserverBase and override
40  /// the virtual functions in that.
41  ///
42  /// The most important application of the alteration observing is the
43  /// dynamic map implementation when the observers are observing the
44  /// alterations in the graph.
45  ///
46  /// \param _Item The item type what the observers are observing, usually
47  /// edge or node.
48  ///
49  /// \author Balazs Dezso
50
51  template <typename _Item>
52  class AlterationObserverRegistry {
53  public:
54    typedef _Item Item;
55
56    /// ObserverBase is the base class for the observers.
57       
58    /// ObserverBase is the abstract base class for the observers.
59    /// It will be notified about an item was inserted into or
60    /// erased from the graph.
61    ///
62    /// The observer interface contains some pure virtual functions
63    /// to override. The add() and erase() functions are
64    /// to notify the oberver when one item is added or
65    /// erased.
66    ///
67    /// The build() and clear() members are to notify the observer
68    /// about the container is builded from an empty container or
69    /// is cleared to an empty container.
70    ///
71    /// \author Balazs Dezso
72
73    class ObserverBase {
74    protected:
75      typedef AlterationObserverRegistry Registry;
76
77      friend class Registry;
78
79      /// Default constructor.
80
81      /// Default constructor for ObserverBase.
82      ///
83      ObserverBase() : registry(0) {}
84
85      virtual ~ObserverBase() {}
86
87      /// Attaches the observer into an AlterationObserverRegistry.
88
89      /// This member attaches the observer into an AlterationObserverRegistry.
90      ///
91      void attach(AlterationObserverRegistry& r) {
92        registry = &r;
93        registry->attach(*this);
94      }
95
96      /// Detaches the observer into an AlterationObserverRegistry.
97
98      /// This member detaches the observer from an AlterationObserverRegistry.
99      ///
100      void detach() {
101        if (registry) {
102          registry->detach(*this);
103        }
104      }
105       
106
107      /// Gives back a pointer to the registry what the map attached into.
108
109      /// This function gives back a pointer to the registry what the map
110      /// attached into.
111      ///
112      Registry* getRegistry() const { return const_cast<Registry*>(registry); }
113     
114      /// Gives back true when the observer is attached into a registry.
115      bool attached() const { return registry != 0; }
116       
117    private:
118
119      ObserverBase(const ObserverBase& copy);
120      ObserverBase& operator=(const ObserverBase& copy);
121
122    protected:
123     
124      Registry* registry;
125      int registry_index;
126
127    public:
128
129      /// \brief The member function to notificate the observer about an
130      /// item is added to the container.
131      ///
132      /// The add() member function notificates the observer about an item
133      /// is added to the container. It have to be overrided in the
134      /// subclasses.
135       
136      virtual void add(const Item&) = 0;       
137
138
139      /// \brief The member function to notificate the observer about an
140      /// item is erased from the container.
141      ///
142      /// The erase() member function notificates the observer about an
143      /// item is erased from the container. It have to be overrided in
144      /// the subclasses.
145       
146      virtual void erase(const Item&) = 0;
147
148      /// \brief The member function to notificate the observer about the
149      /// container is builded.
150      ///
151      /// The build() member function notificates the observer about the
152      /// container is builded from an empty container. It have to be
153      /// overrided in the subclasses.
154
155      virtual void build() = 0;
156
157      /// \brief The member function to notificate the observer about all
158      /// items are erased from the container.
159      ///
160      /// The clear() member function notificates the observer about all
161      /// items are erased from the container. It have to be overrided in
162      /// the subclasses.
163     
164      virtual void clear() = 0;
165
166    };
167       
168  protected:
169       
170
171    typedef std::vector<ObserverBase*> Container;
172
173    Container container;
174
175               
176  public:
177
178    /// Default constructor.
179       
180    ///
181    /// The default constructor of the AlterationObserverRegistry.
182    /// It creates an empty registry.
183    AlterationObserverRegistry() {}
184
185    /// Copy Constructor of the AlterationObserverRegistry.
186       
187    /// Copy constructor of the AlterationObserverRegistry.
188    /// It creates only an empty registry because the copiable
189    /// registry's observers have to be registered still into that registry.
190    AlterationObserverRegistry(const AlterationObserverRegistry&) {}
191
192    /// Assign operator.
193               
194    /// Assign operator for the AlterationObserverRegistry.
195    /// It makes the registry only empty because the copiable
196    /// registry's observers have to be registered still into that registry.
197    AlterationObserverRegistry& operator=(const AlterationObserverRegistry&) {
198      typename Container::iterator it;
199      for (it = container.begin(); it != container.end(); ++it) {
200        (*it)->registry = 0;
201      }
202    }
203
204    /// Destructor.
205                               
206    /// Destructor of the AlterationObserverRegistry.
207    ///
208    ~AlterationObserverRegistry() {
209      typename Container::iterator it;
210      for (it = container.begin(); it != container.end(); ++it) {
211        (*it)->registry = 0;
212      }
213    }
214       
215       
216  protected:
217
218    void attach(ObserverBase& observer) {
219      container.push_back(&observer);
220      observer.registry = this;
221      observer.registry_index = container.size()-1;
222    }
223
224    void detach(ObserverBase& base) {
225      container.back()->registry_index = base.registry_index;
226      container[base.registry_index] = container.back();
227      container.pop_back();
228      base.registry = 0;
229    }
230
231  public:
232       
233    /// Notifies all the registered observers about an Item added to the container.
234               
235    /// It notifies all the registered observers about an Item added to the container.
236    ///
237    void add(const Item& key) {
238      typename Container::iterator it;
239      for (it = container.begin(); it != container.end(); ++it) {
240        (*it)->add(key);
241      }
242    }   
243
244    /// Notifies all the registered observers about an Item erased from the container.
245               
246    /// It notifies all the registered observers about an Item erased from the container.
247    ///
248    void erase(const Item& key) {
249      typename Container::iterator it;
250      for (it = container.begin(); it != container.end(); ++it) {
251        (*it)->erase(key);
252      }
253    }
254   
255
256    /// Notifies all the registered observers about the container is builded.
257               
258    /// Notifies all the registered observers about the container is builded
259    /// from an empty container.
260    void build() {
261      typename Container::iterator it;
262      for (it = container.begin(); it != container.end(); ++it) {
263        (*it)->build();
264      }
265    }
266
267
268    /// Notifies all the registered observers about all Items are erased.
269
270    /// Notifies all the registered observers about all Items are erased
271    /// from the container.
272    void clear() {
273      typename Container::iterator it;
274      for (it = container.begin(); it != container.end(); ++it) {
275        (*it)->clear();
276      }
277    }
278  };
279
280
281  /// Class to extend a graph functionality with the possibility of alteration observing.
282
283  /// AlterableGraphExtender extends the _Base graphs functionality with the possibility of
284  /// alteration observing. It defines two observer registrys for the nodes and mapes.
285  ///
286  /// \param _Base is the base class to extend.
287  ///
288  /// \pre _Base is conform to the BaseGraphComponent concept.
289  ///
290  /// \post AlterableGraphExtender<_Base> is conform to the AlterableGraphComponent concept.
291  ///
292  /// \author Balazs Dezso
293
294  template <typename _Base>
295  class AlterableGraphExtender : public _Base {
296  public:
297
298    typedef AlterableGraphExtender Graph;
299    typedef _Base Parent;
300
301    typedef typename Parent::Node Node;
302    typedef typename Parent::Edge Edge;
303
304    /// The node observer registry.
305    typedef AlterationObserverRegistry<Edge> EdgeObserverRegistry;
306    /// The edge observer registry.
307    typedef AlterationObserverRegistry<Node> NodeObserverRegistry;
308
309
310  protected:
311
312    mutable EdgeObserverRegistry edge_observers;
313
314    mutable NodeObserverRegistry node_observers;
315
316  public:
317
318    EdgeObserverRegistry& getEdgeObserverRegistry() const {
319      return edge_observers;
320    }
321
322    NodeObserverRegistry& getNodeObserverRegistry() const {
323      return node_observers;
324    }
325
326    ~AlterableGraphExtender() {
327      node_observers.clear();
328      edge_observers.clear();
329    }
330   
331  };
332
333 
334/// @}
335 
336
337}
338
339#endif
Note: See TracBrowser for help on using the repository browser.