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