aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/poco/Foundation/include/Poco/NotificationCenter.h
blob: 411bba8944f6daf3e94021601a2ea7587df7546e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
//
// NotificationCenter.h
//
// Library: Foundation
// Package: Notifications
// Module:  NotificationCenter
//
// Definition of the NotificationCenter class.
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:	BSL-1.0
//


#ifndef Foundation_NotificationCenter_INCLUDED
#define Foundation_NotificationCenter_INCLUDED


#include "Poco/Foundation.h"
#include "Poco/Notification.h"
#include "Poco/Mutex.h"
#include "Poco/SharedPtr.h"
#include <vector>
#include <cstddef>


namespace Poco {


class AbstractObserver;


class Foundation_API NotificationCenter
	/// A NotificationCenter is essentially a notification dispatcher. 
	/// It notifies all observers of notifications meeting specific criteria.
	/// This information is encapsulated in Notification objects.
	/// Client objects register themselves with the notification center as observers of 
	/// specific notifications posted by other objects. When an event occurs, an object 
	/// posts an appropriate notification to the notification center. The notification  
	/// center invokes the registered method on each matching observer, passing the notification 
	/// as argument.
	///
	/// The order in which observers receive notifications is undefined. 
	/// It is possible for the posting object and the observing object to be the same.
	/// The NotificationCenter delivers notifications to observers synchronously. 
	/// In other words the postNotification() method does not return until all observers have 
	/// received and processed the notification. 
	/// If an observer throws an exception while handling a notification, the NotificationCenter
	/// stops dispatching the notification and postNotification() rethrows the exception.
	///
	/// In a multithreaded scenario, notifications are always delivered in the thread in which the 
	/// notification was posted, which may not be the same thread in which an observer registered itself.
	///
	/// The NotificationCenter class is basically a C++ implementation of the NSNotificationCenter class
	/// found in Apple's Cocoa (or OpenStep).
	///
	/// While handling a notification, an observer can unregister itself from the notification center,
	/// or it can register or unregister other observers. Observers added during a dispatch cycle
	/// will not receive the current notification.
	///
	/// The method receiving the notification must be implemented as
	///     void handleNotification(MyNotification* pNf);
	/// The handler method gets co-ownership of the Notification object
	/// and must release it when done. This is best done with an AutoPtr:
	///     void MyClass::handleNotification(MyNotification* pNf)
	///     {
	///         AutoPtr<MyNotification> nf(pNf);
	///         ...
	///     }
	///
	/// Alternatively, the NObserver class template can be used to register a callback
	/// method. In this case, the callback method receives the Notification in an
	/// AutoPtr and thus does not have to deal with object ownership issues:
	///     void MyClass::handleNotification(const AutoPtr<MyNotification>& pNf)
	///     {
	///         ...
	///     }
{
public:
	NotificationCenter();
		/// Creates the NotificationCenter.

	~NotificationCenter();
		/// Destroys the NotificationCenter.

	void addObserver(const AbstractObserver& observer);
		/// Registers an observer with the NotificationCenter.
		/// Usage:
		///     Observer<MyClass, MyNotification> obs(*this, &MyClass::handleNotification);
		///     notificationCenter.addObserver(obs);
		///
		/// Alternatively, the NObserver template class can be used instead of Observer.

	void removeObserver(const AbstractObserver& observer);
		/// Unregisters an observer with the NotificationCenter.

	bool hasObserver(const AbstractObserver& observer) const;
		/// Returns true if the observer is registered with this NotificationCenter.

	void postNotification(Notification::Ptr pNotification);
		/// Posts a notification to the NotificationCenter.
		/// The NotificationCenter then delivers the notification
		/// to all interested observers.
		/// If an observer throws an exception, dispatching terminates
		/// and the exception is rethrown to the caller.
		/// Ownership of the notification object is claimed and the
		/// notification is released before returning. Therefore,
		/// a call like
		///    notificationCenter.postNotification(new MyNotification);
		/// does not result in a memory leak.

	bool hasObservers() const;
		/// Returns true iff there is at least one registered observer.
		///
		/// Can be used to improve performance if an expensive notification
		/// shall only be created and posted if there are any observers.
		
	std::size_t countObservers() const;
		/// Returns the number of registered observers.
		
	static NotificationCenter& defaultCenter();
		/// Returns a reference to the default
		/// NotificationCenter.

private:
	typedef SharedPtr<AbstractObserver> AbstractObserverPtr;
	typedef std::vector<AbstractObserverPtr> ObserverList;

	ObserverList  _observers;
	mutable Mutex _mutex;
};


} // namespace Poco


#endif // Foundation_NotificationCenter_INCLUDED