Ipopt Documentation  
 
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// Authors: Carl Laird, Andreas Waechter IBM 2004-08-13
6
7#ifndef __IPOBSERVER_HPP__
8#define __IPOBSERVER_HPP__
9
10#include "IpUtils.hpp"
11#include <vector>
12#include <algorithm>
13
14//#define IP_DEBUG_OBSERVER
15#if IPOPT_CHECKLEVEL > 2
16# define IP_DEBUG_OBSERVER
17#endif
18#ifdef IP_DEBUG_OBSERVER
19# include "IpDebug.hpp"
20#endif
21
22namespace Ipopt
23{
24/* Forward declaration */
25class Subject;
26
39{
40public:
41#ifdef IP_DEBUG_OBSERVER
42 static const Index dbg_verbosity;
43#endif
44
47
49 { }
50
52 inline
53 virtual ~Observer();
55
58 {
61 NT_Changed
62 };
63
64protected:
71 inline
72 void RequestAttach(
73 NotifyType notify_type,
74 const Subject* subject
75 );
76
83 inline
84 void RequestDetach(
85 NotifyType notify_type,
86 const Subject* subject
87 );
88
93 virtual void ReceiveNotification(
95 const Subject* subject
96 ) = 0;
97
98private:
109
111 const Observer&
112 );
113
116 const Observer&
117 );
119
121 std::vector<const Subject*> subjects_;
122
131 inline
132 void ProcessNotification(
134 const Subject* subject
135 );
136
137 friend class Subject;
138};
139
150{
151public:
152#ifdef IP_DEBUG_OBSERVER
153 static const Index dbg_verbosity;
154#endif
155
158
160 { }
161
163 inline
164 virtual ~Subject();
166
180
182 inline
183 void AttachObserver(
186 ) const;
187
190 inline
191 void DetachObserver(
194 ) const;
196
197protected:
198
199 inline
200 void Notify(
202 ) const;
203
204private:
215
217 const Subject&
218 );
219
222 const Subject&
223 );
225
226 mutable std::vector<Observer*> observers_;
227};
228
229/* inline methods */
231{
232#ifdef IP_DEBUG_OBSERVER
233 DBG_START_METH("Observer::~Observer", dbg_verbosity);
234 if (DBG_VERBOSITY() >= 1)
235 {
236 for( size_t i = 0; i < subjects_.size(); ++i )
237 {
238 DBG_PRINT((1, "subjects_[%zd] = %p\n", i, (const void*)subjects_[i]));
239 }
240 }
241#endif
242 // Detach all subjects
243 for( size_t i = subjects_.size(); i > 0; --i )
244 {
245#ifdef IP_DEBUG_OBSERVER
246 DBG_PRINT((1, "About to detach subjects_[%zd] = %p\n", i, (const void*)subjects_[i - 1]));
247#endif
248
250 }
251}
252
253inline
256 const Subject* subject
257)
258{
259#ifdef IP_DEBUG_OBSERVER
260 DBG_START_METH("Observer::RequestAttach", dbg_verbosity);
261
262 // Add the subject to the list if it does not already exist
263 std::vector<const Subject*>::iterator attached_subject;
264 attached_subject = std::find(subjects_.begin(), subjects_.end(), subject);
267#endif
268
269 // add the subject to the list
270 subjects_.push_back(subject);
271 // Attach the observer to the subject
272 subject->AttachObserver(notify_type, this);
273}
274
275inline
278 const Subject* subject
279)
280{
281#ifdef IP_DEBUG_OBSERVER
282 DBG_START_METH("Observer::RequestDetach", dbg_verbosity);
283 DBG_PRINT((1, "Requesting detach of subject: %p\n", (const void*)subject));
285#endif
286
287 if( subject )
288 {
289 std::vector<const Subject*>::iterator attached_subject;
290 attached_subject = std::find(subjects_.begin(), subjects_.end(), subject);
291#ifdef IP_DEBUG_OBSERVER
292
294#endif
295
296 if( attached_subject != subjects_.end() )
297 {
298#ifdef IP_DEBUG_OBSERVER
299 DBG_PRINT((1, "Removing subject: %p from the list\n", (const void*)subject));
300#endif
301
303 }
304
305 // Detach the observer from the subject
306 subject->DetachObserver(notify_type, this);
307 }
308}
309
310inline
313 const Subject* subject
314)
315{
316#ifdef IP_DEBUG_OBSERVER
317 DBG_START_METH("Observer::ProcessNotification", dbg_verbosity);
319#endif
320
321 if( subject )
322 {
323 std::vector<const Subject*>::iterator attached_subject;
324 attached_subject = std::find(subjects_.begin(), subjects_.end(), subject);
325
326 // We must be processing a notification for a
327 // subject that was previously attached.
328#ifdef IP_DEBUG_OBSERVER
329
331#endif
332
333 this->ReceiveNotification(notify_type, subject);
334
336 {
337 // the subject is going away, remove it from our list
339 }
340 }
341}
342
344{
345#ifdef IP_DEBUG_OBSERVER
346 DBG_START_METH("Subject::~Subject", dbg_verbosity);
347#endif
348
349 for( std::vector<Observer*>::iterator iter = observers_.begin(); iter != observers_.end(); ++iter )
350 {
351 (*iter)->ProcessNotification(Observer::NT_BeingDestroyed, this);
352 }
353}
354
355inline
357 Observer::NotifyType /*notify_type*/,
359) const
360{
361#ifdef IP_DEBUG_OBSERVER
362 DBG_START_METH("Subject::AttachObserver", dbg_verbosity);
363 // current implementation notifies all observers of everything
364 // they must filter the notifications that they are not interested
365 // in (i.e. a hub, not a router)
367
368 std::vector<Observer*>::iterator attached_observer;
369 attached_observer = std::find(observers_.begin(), observers_.end(), observer);
371
373#endif
374
375 observers_.push_back(observer);
376}
377
378inline
380 Observer::NotifyType /*notify_type*/,
382) const
383{
384#ifdef IP_DEBUG_OBSERVER
385 DBG_START_METH("Subject::DetachObserver", dbg_verbosity);
387#endif
388
389 if( observer )
390 {
391 std::vector<Observer*>::iterator attached_observer;
392 attached_observer = std::find(observers_.begin(), observers_.end(), observer);
393#ifdef IP_DEBUG_OBSERVER
394
396#endif
397
398 if( attached_observer != observers_.end() )
399 {
401 }
402 }
403}
404
405inline
408) const
409{
410#ifdef IP_DEBUG_OBSERVER
411 DBG_START_METH("Subject::Notify", dbg_verbosity);
412#endif
413
414 for( std::vector<Observer*>::iterator iter = observers_.begin(); iter != observers_.end(); ++iter )
415 {
416 (*iter)->ProcessNotification(notify_type, this);
417 }
418}
419
420} // namespace Ipopt
421
422#endif
#define DBG_ASSERT(test)
Definition IpDebug.hpp:27
#define DBG_PRINT(__printf_args)
Definition IpDebug.hpp:39
#define DBG_VERBOSITY()
Definition IpDebug.hpp:43
#define DBG_START_METH(__func_name, __verbose_level)
Definition IpDebug.hpp:38
Templated class which stores one entry for the CachedResult class.
Slight Variation of the Observer Design Pattern.
void ProcessNotification(NotifyType notify_type, const Subject *subject)
Private Method for Receiving Notification should only be called by the friend class Subject.
virtual void ReceiveNotification(NotifyType notify_type, const Subject *subject)=0
Derived classes should overload this method to receive the requested notification from attached Subje...
virtual ~Observer()
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 &)
Default Assignment 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 receiving notifications).
void DetachObserver(Observer::NotifyType notify_type, Observer *observer) const
Detach the specified observer (i.e., no longer receive notifications).
virtual ~Subject()
Destructor.
std::vector< Observer * > observers_
void operator=(const Subject &)
Default Assignment Operator.
#define IPOPTLIB_EXPORT
This file contains a base class for all exceptions and a set of macros to help with exceptions.
ipindex Index
Type of all indices of vectors, matrices etc.
Definition IpTypes.hpp:20