1 | // |
2 | // NObserver.h |
3 | // |
4 | // Library: Foundation |
5 | // Package: Notifications |
6 | // Module: NotificationCenter |
7 | // |
8 | // Definition of the NObserver class template. |
9 | // |
10 | // Copyright (c) 2006, Applied Informatics Software Engineering GmbH. |
11 | // and Contributors. |
12 | // |
13 | // SPDX-License-Identifier: BSL-1.0 |
14 | // |
15 | |
16 | |
17 | #ifndef Foundation_NObserver_INCLUDED |
18 | #define Foundation_NObserver_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 NObserver: 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 | /// This class template is quite similar to the Observer class |
40 | /// template. The only difference is that the NObserver |
41 | /// expects the callback function to accept a const AutoPtr& |
42 | /// instead of a plain pointer as argument, thus simplifying memory |
43 | /// management. |
44 | { |
45 | public: |
46 | typedef AutoPtr<N> NotificationPtr; |
47 | typedef void (C::*Callback)(const NotificationPtr&); |
48 | |
49 | NObserver(C& object, Callback method): |
50 | _pObject(&object), |
51 | _method(method) |
52 | { |
53 | } |
54 | |
55 | NObserver(const NObserver& observer): |
56 | AbstractObserver(observer), |
57 | _pObject(observer._pObject), |
58 | _method(observer._method) |
59 | { |
60 | } |
61 | |
62 | ~NObserver() |
63 | { |
64 | } |
65 | |
66 | NObserver& operator = (const NObserver& observer) |
67 | { |
68 | if (&observer != this) |
69 | { |
70 | _pObject = observer._pObject; |
71 | _method = observer._method; |
72 | } |
73 | return *this; |
74 | } |
75 | |
76 | void notify(Notification* pNf) const |
77 | { |
78 | Poco::Mutex::ScopedLock lock(_mutex); |
79 | |
80 | if (_pObject) |
81 | { |
82 | N* pCastNf = dynamic_cast<N*>(pNf); |
83 | if (pCastNf) |
84 | { |
85 | NotificationPtr ptr(pCastNf, true); |
86 | (_pObject->*_method)(ptr); |
87 | } |
88 | } |
89 | } |
90 | |
91 | bool equals(const AbstractObserver& abstractObserver) const |
92 | { |
93 | const NObserver* pObs = dynamic_cast<const NObserver*>(&abstractObserver); |
94 | return pObs && pObs->_pObject == _pObject && pObs->_method == _method; |
95 | } |
96 | |
97 | bool accepts(Notification* pNf) const |
98 | { |
99 | return dynamic_cast<N*>(pNf) != 0; |
100 | } |
101 | |
102 | AbstractObserver* clone() const |
103 | { |
104 | return new NObserver(*this); |
105 | } |
106 | |
107 | void disable() |
108 | { |
109 | Poco::Mutex::ScopedLock lock(_mutex); |
110 | |
111 | _pObject = 0; |
112 | } |
113 | |
114 | private: |
115 | NObserver(); |
116 | |
117 | C* _pObject; |
118 | Callback _method; |
119 | mutable Poco::Mutex _mutex; |
120 | }; |
121 | |
122 | |
123 | } // namespace Poco |
124 | |
125 | |
126 | #endif // Foundation_NObserver_INCLUDED |
127 | |