Ipopt 3.12.10

- Main Page
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
IpObserver.hpp
Go to the documentation of this file.
1 // Copyright (C) 2004, 2006 International Business Machines and others.
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // $Id: IpObserver.hpp 2161 2013-01-01 20:39:05Z stefan $
6 //
7 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13
8
9 #ifndef __IPOBSERVER_HPP__
10 #define __IPOBSERVER_HPP__
11
12 #include "IpUtils.hpp"
13 #include <vector>
14 #include <algorithm>
15
16 //#define IP_DEBUG_OBSERVER
17 #if COIN_IPOPT_CHECKLEVEL > 2
18 # define IP_DEBUG_OBSERVER
19 #endif
20 #ifdef IP_DEBUG_OBSERVER
21 # include "IpDebug.hpp"
22 #endif
23
24 namespace Ipopt
25 {
27 class Subject;
28
39 class Observer
40 {
41 public:
42 #ifdef IP_DEBUG_OBSERVER
43
44 static const Index dbg_verbosity;
45 #endif
46
50 Observer()
51 {}
52
54 inline
55 virtual ~Observer();
57
59 enum NotifyType
60 {
61 NT_All,
62 NT_BeingDestroyed,
63 NT_Changed
64 };
65
66 protected:
72 inline
73 void RequestAttach(NotifyType notify_type, const Subject* subject);
74
80 inline
81 void RequestDetach(NotifyType notify_type, const Subject* subject);
82
87 virtual void RecieveNotification(NotifyType notify_type, const Subject* subject)=0;
88
89 private:
99 Observer(const Observer&);
100
102 void operator=(const Observer&);
104
107 std::vector<const Subject*> subjects_;
108
115 inline
116 void ProcessNotification(NotifyType notify_type, const Subject* subject);
117
118 friend class Subject;
119 };
120
129 class Subject
130 {
131 public:
132 #ifdef IP_DEBUG_OBSERVER
133
134 static const Index dbg_verbosity;
135 #endif
136
140 Subject()
141 {}
142
144 inline
145 virtual ~Subject();
147
159
162 inline
163 void AttachObserver(Observer::NotifyType notify_type, Observer* observer) const;
164
167 inline
168 void DetachObserver(Observer::NotifyType notify_type, Observer* observer) const;
170
171 protected:
172
173 inline
174 void Notify(Observer::NotifyType notify_type) const;
175
176 private:
186 Subject(const Subject&);
187
189 void operator=(const Subject&);
191
192 mutable std::vector<Observer*> observers_;
193
194 };
195
196 /* inline methods */
197 inline
198 Observer::~Observer()
199 {
200 #ifdef IP_DEBUG_OBSERVER
201 DBG_START_METH("Observer::~Observer", dbg_verbosity);
202 if (DBG_VERBOSITY()>=1) {
203 for (Index i=0; i<(Index)subjects_.size(); i++) {
204 DBG_PRINT((1,"subjects_[%d] = 0x%x\n", i, subjects_[i]));
205 }
206 }
207 #endif
208 // Detach all subjects
209 for (Int i=(Int)(subjects_.size()-1); i>=0; i--) {
210 #ifdef IP_DEBUG_OBSERVER
211 DBG_PRINT((1,"About to detach subjects_[%d] = 0x%x\n", i, subjects_[i]));
212 #endif
213
214 RequestDetach(NT_All, subjects_[i]);
215 }
216 }
217
218 inline
219 void Observer::RequestAttach(NotifyType notify_type, const Subject* subject)
220 {
221 #ifdef IP_DEBUG_OBSERVER
222 DBG_START_METH("Observer::RequestAttach", dbg_verbosity);
223
224 // Add the subject to the list if it does not already exist
225 std::vector<const Subject*>::iterator attached_subject;
226 attached_subject = std::find(subjects_.begin(), subjects_.end(), subject);
227 DBG_ASSERT(attached_subject == subjects_.end());
228 DBG_ASSERT(subject);
229 #endif
230
231 // add the subject to the list
232 subjects_.push_back(subject);
233 // Attach the observer to the subject
234 subject->AttachObserver(notify_type, this);
235 }
236
237 inline
238 void Observer::RequestDetach(NotifyType notify_type, const Subject* subject)
239 {
240 #ifdef IP_DEBUG_OBSERVER
241 DBG_START_METH("Observer::RequestDetach", dbg_verbosity);
242 DBG_PRINT((1, "Requesting detach of subject: 0x%x\n", subject));
243 DBG_ASSERT(subject);
244 #endif
245
246 if (subject) {
247 std::vector<const Subject*>::iterator attached_subject;
248 attached_subject = std::find(subjects_.begin(), subjects_.end(), subject);
249 #ifdef IP_DEBUG_OBSERVER
250
251 DBG_ASSERT(attached_subject != subjects_.end());
252 #endif
253
254 if (attached_subject != subjects_.end()) {
255 #ifdef IP_DEBUG_OBSERVER
256 DBG_PRINT((1, "Removing subject: 0x%x from the list\n", subject));
257 #endif
258
259 subjects_.erase(attached_subject);
260 }
261
262 // Detach the observer from the subject
263 subject->DetachObserver(notify_type, this);
264 }
265 }
266
267 inline
268 void Observer::ProcessNotification(NotifyType notify_type, const Subject* subject)
269 {
270 #ifdef IP_DEBUG_OBSERVER
271 DBG_START_METH("Observer::ProcessNotification", dbg_verbosity);
272 DBG_ASSERT(subject);
273 #endif
274
275 if (subject) {
276 std::vector<const Subject*>::iterator attached_subject;
277 attached_subject = std::find(subjects_.begin(), subjects_.end(), subject);
278
279 // We must be processing a notification for a
280 // subject that was previously attached.
281 #ifdef IP_DEBUG_OBSERVER
282
283 DBG_ASSERT(attached_subject != subjects_.end());
284 #endif
285
286 this->RecieveNotification(notify_type, subject);
287
288 if (notify_type == NT_BeingDestroyed) {
289 // the subject is going away, remove it from our list
290 subjects_.erase(attached_subject);
291 }
292 }
293 }
294
295 inline
296 Subject::~Subject()
297 {
298 #ifdef IP_DEBUG_OBSERVER
299 DBG_START_METH("Subject::~Subject", dbg_verbosity);
300 #endif
301
302 std::vector<Observer*>::iterator iter;
303 for (iter = observers_.begin(); iter != observers_.end(); iter++) {
304 (*iter)->ProcessNotification(Observer::NT_BeingDestroyed, this);
305 }
306 }
307
308 inline
309 void Subject::AttachObserver(Observer::NotifyType notify_type, Observer* observer) const
310 {
311 #ifdef IP_DEBUG_OBSERVER
312 DBG_START_METH("Subject::AttachObserver", dbg_verbosity);
313 // current implementation notifies all observers of everything
314 // they must filter the notifications that they are not interested
315 // in (i.e. a hub, not a router)
316 DBG_ASSERT(observer);
317
318 std::vector<Observer*>::iterator attached_observer;
319 attached_observer = std::find(observers_.begin(), observers_.end(), observer);
320 DBG_ASSERT(attached_observer == observers_.end());
321
322 DBG_ASSERT(observer);
323 #endif
324
325 observers_.push_back(observer);
326 }
327
328 inline
329 void Subject::DetachObserver(Observer::NotifyType notify_type, Observer* observer) const
330 {
331 #ifdef IP_DEBUG_OBSERVER
332 DBG_START_METH("Subject::DetachObserver", dbg_verbosity);
333 DBG_ASSERT(observer);
334 #endif
335
336 if (observer) {
337 std::vector<Observer*>::iterator attached_observer;
338 attached_observer = std::find(observers_.begin(), observers_.end(), observer);
339 #ifdef IP_DEBUG_OBSERVER
340
341 DBG_ASSERT(attached_observer != observers_.end());
342 #endif
343
344 if (attached_observer != observers_.end()) {
345 observers_.erase(attached_observer);
346 }
347 }
348 }
349
350 inline
351 void Subject::Notify(Observer::NotifyType notify_type) const
352 {
353 #ifdef IP_DEBUG_OBSERVER
354 DBG_START_METH("Subject::Notify", dbg_verbosity);
355 #endif
356
357 std::vector<Observer*>::iterator iter;
358 for (iter = observers_.begin(); iter != observers_.end(); iter++) {
359 (*iter)->ProcessNotification(notify_type, this);
360 }
361 }
362
363
364 } // namespace Ipopt
365
366 #endif
Ipopt::Subject::DetachObserver
void DetachObserver(Observer::NotifyType notify_type, Observer *observer) const
Detach the specified observer (i.e., no longer recieve notifications).
Definition: IpObserver.hpp:329
Ipopt::Observer::operator=
void operator=(const Observer &)
Overloaded Equals Operator.
Ipopt::Subject::observers_
std::vector< Observer * > observers_
Definition: IpObserver.hpp:192
Ipopt::Observer::NotifyType
NotifyType
Enumeration specifying the type of notification.
Definition: IpObserver.hpp:59
IpUtils.hpp
Ipopt::Subject::operator=
void operator=(const Subject &)
Overloaded Equals Operator.
Ipopt::Int
int Int
Type of default integer.
Definition: IpTypes.hpp:21
Ipopt::Subject::Notify
void Notify(Observer::NotifyType notify_type) const
Definition: IpObserver.hpp:351
DBG_START_METH
#define DBG_START_METH(__func_name, __verbose_level)
Definition: IpDebug.hpp:49
Ipopt::Observer::NT_Changed
Definition: IpObserver.hpp:63
Ipopt::Observer::RequestAttach
void RequestAttach(NotifyType notify_type, const Subject *subject)
Derived classes should call this method to request an &quot;Attach&quot; to a Subject.
Definition: IpObserver.hpp:219
Ipopt::Observer::~Observer
virtual ~Observer()
Default destructor.
Definition: IpObserver.hpp:198
Ipopt::Observer::NT_BeingDestroyed
Definition: IpObserver.hpp:62
Ipopt::Subject::~Subject
virtual ~Subject()
Default destructor.
Definition: IpObserver.hpp:296
Ipopt::Subject
Slight Variation of the Observer Design Pattern (Subject part).
Definition: IpObserver.hpp:129
Ipopt::Subject::AttachObserver
void AttachObserver(Observer::NotifyType notify_type, Observer *observer) const
Attach the specified observer (i.e., begin recieving notifications).
Definition: IpObserver.hpp:309
Ipopt::Observer
Slight Variation of the Observer Design Pattern.
Definition: IpObserver.hpp:39
Ipopt::Observer::NT_All
Definition: IpObserver.hpp:61
Ipopt::Subject::Subject
Subject()
Default Constructor.
Definition: IpObserver.hpp:140
IpDebug.hpp
Ipopt::Observer::ProcessNotification
void ProcessNotification(NotifyType notify_type, const Subject *subject)
Private Method for Recieving Notification should only be called by the friend class Subject...
Definition: IpObserver.hpp:268
Ipopt::Index
int Index
Type of all indices of vectors, matrices etc.
Definition: IpTypes.hpp:19
DBG_ASSERT
#define DBG_ASSERT(test)
Definition: IpDebug.hpp:38
Ipopt::Observer::Observer
Observer()
Default Constructor.
Definition: IpObserver.hpp:50
DBG_PRINT
#define DBG_PRINT(__printf_args)
Definition: IpDebug.hpp:50
Ipopt::Observer::RequestDetach
void RequestDetach(NotifyType notify_type, const Subject *subject)
Derived classes should call this method to request a &quot;Detach&quot; to a Subject.
Definition: IpObserver.hpp:238
Ipopt::Observer::RecieveNotification
virtual void RecieveNotification(NotifyType notify_type, const Subject *subject)=0
Derived classes should overload this method to recieve the requested notification from attached Subje...
Ipopt::Observer::subjects_
std::vector< const Subject * > subjects_
A list of the subjects currently being observed.
Definition: IpObserver.hpp:107
DBG_VERBOSITY
#define DBG_VERBOSITY()
Definition: IpDebug.hpp:54