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 | |
26 | namespace Poco { |
27 | |
28 | |
29 | template <class C, class N> |
30 | class 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 | { |
44 | public: |
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 | |
112 | private: |
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 | |