1//
2// Observer.h
3//
4// Library: Foundation
5// Package: Notifications
6// Module: NotificationCenter
7//
8// Definition of the Observer class template.
9//
10// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
11// and Contributors.
12//
13// SPDX-License-Identifier: BSL-1.0
14//
15
16
17#ifndef Foundation_Observer_INCLUDED
18#define Foundation_Observer_INCLUDED
19
20
21#include "Poco/Foundation.h"
22#include "Poco/AbstractObserver.h"
23#include "Poco/Mutex.h"
24
25
26namespace Poco {
27
28
29template <class C, class N>
30class Observer: public AbstractObserver
31 /// This template class implements an adapter that sits between
32 /// a NotificationCenter and an object receiving notifications
33 /// from it. It is quite similar in concept to the
34 /// RunnableAdapter, but provides some NotificationCenter
35 /// specific additional methods.
36 /// See the NotificationCenter class for information on how
37 /// to use this template class.
38 ///
39 /// Instead of the Observer class template, you might want to
40 /// use the NObserver class template, which uses an AutoPtr to
41 /// pass the Notification to the callback function, thus freeing
42 /// you from memory management issues.
43{
44public:
45 typedef void (C::*Callback)(N*);
46
47 Observer(C& object, Callback method):
48 _pObject(&object),
49 _method(method)
50 {
51 }
52
53 Observer(const Observer& observer):
54 AbstractObserver(observer),
55 _pObject(observer._pObject),
56 _method(observer._method)
57 {
58 }
59
60 ~Observer()
61 {
62 }
63
64 Observer& operator = (const Observer& observer)
65 {
66 if (&observer != this)
67 {
68 _pObject = observer._pObject;
69 _method = observer._method;
70 }
71 return *this;
72 }
73
74 void notify(Notification* pNf) const
75 {
76 Poco::Mutex::ScopedLock lock(_mutex);
77
78 if (_pObject)
79 {
80 N* pCastNf = dynamic_cast<N*>(pNf);
81 if (pCastNf)
82 {
83 pCastNf->duplicate();
84 (_pObject->*_method)(pCastNf);
85 }
86 }
87 }
88
89 bool equals(const AbstractObserver& abstractObserver) const
90 {
91 const Observer* pObs = dynamic_cast<const Observer*>(&abstractObserver);
92 return pObs && pObs->_pObject == _pObject && pObs->_method == _method;
93 }
94
95 bool accepts(Notification* pNf) const
96 {
97 return dynamic_cast<N*>(pNf) != 0;
98 }
99
100 AbstractObserver* clone() const
101 {
102 return new Observer(*this);
103 }
104
105 void disable()
106 {
107 Poco::Mutex::ScopedLock lock(_mutex);
108
109 _pObject = 0;
110 }
111
112private:
113 Observer();
114
115 C* _pObject;
116 Callback _method;
117 mutable Poco::Mutex _mutex;
118};
119
120
121} // namespace Poco
122
123
124#endif // Foundation_Observer_INCLUDED
125