|
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 |
|
27 using namespace std; |
|
28 |
|
29 namespace 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 |