Ipopt 3.11.9
Loading...
Searching...
No Matches
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
24namespace Ipopt
25{
27 class Subject;
28
40 {
41 public:
42#ifdef IP_DEBUG_OBSERVER
43
44 static const Index dbg_verbosity;
45#endif
46
51 {}
52
54 inline
55 virtual ~Observer();
57
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:
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
130 {
131 public:
132#ifdef IP_DEBUG_OBSERVER
133
134 static const Index dbg_verbosity;
135#endif
136
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:
187
189 void operator=(const Subject&);
191
192 mutable std::vector<Observer*> observers_;
193
194 };
195
196 /* inline methods */
197 inline
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
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
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
#define DBG_ASSERT(test)
Definition IpDebug.hpp:38
#define DBG_PRINT(__printf_args)
Definition IpDebug.hpp:50
#define DBG_VERBOSITY()
Definition IpDebug.hpp:54
#define DBG_START_METH(__func_name, __verbose_level)
Definition IpDebug.hpp:49
Slight Variation of the Observer Design Pattern.
void ProcessNotification(NotifyType notify_type, const Subject *subject)
Private Method for Recieving Notification should only be called by the friend class Subject.
virtual void RecieveNotification(NotifyType notify_type, const Subject *subject)=0
Derived classes should overload this method to recieve the requested notification from attached Subje...
virtual ~Observer()
Default destructor.
void RequestDetach(NotifyType notify_type, const Subject *subject)
Derived classes should call this method to request a "Detach" to a Subject.
void operator=(const Observer &)
Overloaded Equals Operator.
NotifyType
Enumeration specifying the type of notification.
std::vector< const Subject * > subjects_
A list of the subjects currently being observed.
Observer()
Default Constructor.
void RequestAttach(NotifyType notify_type, const Subject *subject)
Derived classes should call this method to request an "Attach" to a Subject.
Observer(const Observer &)
Copy Constructor.
Slight Variation of the Observer Design Pattern (Subject part).
void Notify(Observer::NotifyType notify_type) const
Subject(const Subject &)
Copy Constructor.
Subject()
Default Constructor.
void AttachObserver(Observer::NotifyType notify_type, Observer *observer) const
Attach the specified observer (i.e., begin recieving notifications).
void DetachObserver(Observer::NotifyType notify_type, Observer *observer) const
Detach the specified observer (i.e., no longer recieve notifications).
virtual ~Subject()
Default destructor.
std::vector< Observer * > observers_
void operator=(const Subject &)
Overloaded Equals Operator.
int Int
Type of default integer.
Definition IpTypes.hpp:21
int Index
Type of all indices of vectors, matrices etc.
Definition IpTypes.hpp:19