blob: d43bd24c50936cdac875992d2b0c2b1d5acfa9a8 [file] [log] [blame]
Yingdi Yufe140152014-07-24 10:02:40 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2013-2014 Regents of the University of California.
4 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 *
21 * This code is actually copied from NFD project (NDN Forwarding Daemon).
22 * We acknowledge the permission of the authors of NFD.
23 */
24/**
25 * Copyright (c) 2014 Regents of the University of California,
26 * Arizona Board of Regents,
27 * Colorado State University,
28 * University Pierre & Marie Curie, Sorbonne University,
29 * Washington University in St. Louis,
30 * Beijing Institute of Technology
31 *
32 * This file is part of NFD (Named Data Networking Forwarding Daemon).
33 * See AUTHORS.md for complete list of NFD authors and contributors.
34 *
35 * NFD is free software: you can redistribute it and/or modify it under the terms
36 * of the GNU General Public License as published by the Free Software Foundation,
37 * either version 3 of the License, or (at your option) any later version.
38 *
39 * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
40 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
41 * PURPOSE. See the GNU General Public License for more details.
42 *
43 * You should have received a copy of the GNU General Public License along with
44 * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
45 **/
46
47
48#ifndef NDN_UTIL_EVENT_EMITTER_HPP
49#define NDN_UTIL_EVENT_EMITTER_HPP
50
Alexander Afanasyevd51cd582014-08-12 11:34:24 -070051#include "../common.hpp"
Yingdi Yufe140152014-07-24 10:02:40 -070052#include <vector>
53
54namespace ndn {
55namespace util {
56
57struct empty
58{
59};
60
61/** \class EventEmitter
62 * \brief provides a lightweight event system
63 *
64 * To declare an event:
65 * EventEmitter<TArgs> onEventName;
66 * To subscribe to an event:
67 * eventSource->onEventName += eventHandler;
68 * Multiple functions can subscribe to the same event.
69 * To trigger an event:
70 * onEventName(args);
71 * To clear event subscriptions:
72 * onEventName.clear();
73 */
74
75// four arguments
76template<typename T1 = empty, typename T2 = empty,
77 typename T3 = empty, typename T4 = empty>
78class EventEmitter : noncopyable
79{
80public:
81 /// represents a handler that can subscribe to the event
82 typedef function<void(const T1&, const T2&,
83 const T3&, const T4&)> Handler;
84
85 /// adds an subscription
86 void
87 operator+=(Handler handler);
88
89 /// returns true if there is no subscription,
90 /// otherwise returns false
91 bool
92 isEmpty() const;
93
94 /// clears all subscriptions
95 void
96 clear();
97
98 /// triggers the event
99 void
100 operator()(const T1& a1, const T2& a2, const T3& a3, const T4& a4);
101
102private:
103 /// stores all subscribed handlers
104 std::vector<Handler> m_handlers;
105};
106
107// zero argument
108template<>
109class EventEmitter<empty, empty, empty, empty> : noncopyable
110{
111public:
112 typedef function<void()> Handler;
113
114 void
115 operator+=(Handler handler);
116
117 bool
118 isEmpty() const;
119
120 void
121 clear();
122
123 void
124 operator()();
125
126private:
127 std::vector<Handler> m_handlers;
128};
129
130
131// one argument
132template<typename T1>
133class EventEmitter<T1, empty, empty, empty> : noncopyable
134{
135public:
136 typedef function<void(const T1&)> Handler;
137
138 void
139 operator+=(Handler handler);
140
141 bool
142 isEmpty() const;
143
144 void
145 clear();
146
147 void
148 operator()(const T1& a1);
149
150private:
151 std::vector<Handler> m_handlers;
152};
153
154
155// two arguments
156template<typename T1, typename T2>
157class EventEmitter<T1, T2, empty, empty> : noncopyable
158{
159public:
160 typedef function<void(const T1&, const T2&)> Handler;
161
162 void
163 operator+=(Handler handler);
164
165 bool
166 isEmpty() const;
167
168 void
169 clear();
170
171 void
172 operator()(const T1& a1, const T2& a2);
173
174private:
175 std::vector<Handler> m_handlers;
176};
177
178
179// three arguments
180template<typename T1, typename T2, typename T3>
181class EventEmitter<T1, T2, T3, empty> : noncopyable
182{
183public:
184 typedef function<void(const T1&, const T2&, const T3&)> Handler;
185
186 void
187 operator+=(Handler handler);
188
189 bool
190 isEmpty() const;
191
192 void
193 clear();
194
195 void
196 operator()(const T1& a1, const T2& a2, const T3& a3);
197
198private:
199 std::vector<Handler> m_handlers;
200};
201
202
203// zero argument
204
205inline void
206EventEmitter<empty, empty, empty, empty>::operator+=(Handler handler)
207{
208 m_handlers.push_back(handler);
209}
210
211inline bool
212EventEmitter<empty, empty, empty, empty>::isEmpty() const
213{
214 return m_handlers.empty();
215}
216
217inline void
218EventEmitter<empty, empty, empty, empty>::clear()
219{
220 return m_handlers.clear();
221}
222
223inline void
224EventEmitter<empty, empty, empty, empty>::operator()()
225{
226 std::vector<Handler>::iterator it;
227 for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
228 (*it)();
229 if (m_handlers.empty()) // .clear has been called
230 return;
231 }
232}
233
234// one argument
235
236template<typename T1>
237inline void
238EventEmitter<T1, empty, empty, empty>::operator+=(Handler handler)
239{
240 m_handlers.push_back(handler);
241}
242
243template<typename T1>
244inline bool
245EventEmitter<T1, empty, empty, empty>::isEmpty() const
246{
247 return m_handlers.empty();
248}
249
250template<typename T1>
251inline void
252EventEmitter<T1, empty, empty, empty>::clear()
253{
254 return m_handlers.clear();
255}
256
257template<typename T1>
258inline void
259EventEmitter<T1, empty, empty, empty>::operator()(const T1& a1)
260{
261 typename std::vector<Handler>::iterator it;
262 for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
263 (*it)(a1);
264 if (m_handlers.empty()) // .clear has been called
265 return;
266 }
267}
268
269// two arguments
270
271template<typename T1, typename T2>
272inline void
273EventEmitter<T1, T2, empty, empty>::operator+=(Handler handler)
274{
275 m_handlers.push_back(handler);
276}
277
278template<typename T1, typename T2>
279inline bool
280EventEmitter<T1, T2, empty, empty>::isEmpty() const
281{
282 return m_handlers.empty();
283}
284
285template<typename T1, typename T2>
286inline void
287EventEmitter<T1, T2, empty, empty>::clear()
288{
289 return m_handlers.clear();
290}
291
292template<typename T1, typename T2>
293inline void
294EventEmitter<T1, T2, empty, empty>::operator()
295 (const T1& a1, const T2& a2)
296{
297 typename std::vector<Handler>::iterator it;
298 for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
299 (*it)(a1, a2);
300 if (m_handlers.empty()) // .clear has been called
301 return;
302 }
303}
304
305// three arguments
306
307template<typename T1, typename T2, typename T3>
308inline void
309EventEmitter<T1, T2, T3, empty>::operator+=(Handler handler)
310{
311 m_handlers.push_back(handler);
312}
313
314template<typename T1, typename T2, typename T3>
315inline bool
316EventEmitter<T1, T2, T3, empty>::isEmpty() const
317{
318 return m_handlers.empty();
319}
320
321template<typename T1, typename T2, typename T3>
322inline void
323EventEmitter<T1, T2, T3, empty>::clear()
324{
325 return m_handlers.clear();
326}
327
328template<typename T1, typename T2, typename T3>
329inline void
330EventEmitter<T1, T2, T3, empty>::operator()
331 (const T1& a1, const T2& a2, const T3& a3)
332{
333 typename std::vector<Handler>::iterator it;
334 for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
335 (*it)(a1, a2, a3);
336 if (m_handlers.empty()) // .clear has been called
337 return;
338 }
339}
340
341// four arguments
342
343template<typename T1, typename T2, typename T3, typename T4>
344inline void
345EventEmitter<T1, T2, T3, T4>::operator+=(Handler handler)
346{
347 m_handlers.push_back(handler);
348}
349
350template<typename T1, typename T2, typename T3, typename T4>
351inline bool
352EventEmitter<T1, T2, T3, T4>::isEmpty() const
353{
354 return m_handlers.empty();
355}
356
357template<typename T1, typename T2, typename T3, typename T4>
358inline void
359EventEmitter<T1, T2, T3, T4>::clear()
360{
361 return m_handlers.clear();
362}
363
364template<typename T1, typename T2, typename T3, typename T4>
365inline void
366EventEmitter<T1, T2, T3, T4>::operator()
367 (const T1& a1, const T2& a2, const T3& a3, const T4& a4)
368{
369 typename std::vector<Handler>::iterator it;
370 for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
371 (*it)(a1, a2, a3, a4);
372 if (m_handlers.empty()) // .clear has been called
373 return;
374 }
375}
376
377
378} // namespace util
379} // namespace ndn
380
381#endif // NDN_UTIL_EVENT_EMITTER_HPP