blob: 261dabca3522759359ceae3eeee257d0a8425300 [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.
Yingdi Yufe140152014-07-24 10:02:40 -070020 */
Yingdi Yufe140152014-07-24 10:02:40 -070021
22#ifndef NDN_UTIL_EVENT_EMITTER_HPP
23#define NDN_UTIL_EVENT_EMITTER_HPP
24
Alexander Afanasyevd51cd582014-08-12 11:34:24 -070025#include "../common.hpp"
Yingdi Yufe140152014-07-24 10:02:40 -070026#include <vector>
27
28namespace ndn {
29namespace util {
30
Junxiao Shia93870d2014-11-05 22:35:31 -070031/** \brief provides a lightweight event system
Yingdi Yufe140152014-07-24 10:02:40 -070032 *
33 * To declare an event:
34 * EventEmitter<TArgs> onEventName;
35 * To subscribe to an event:
36 * eventSource->onEventName += eventHandler;
37 * Multiple functions can subscribe to the same event.
38 * To trigger an event:
39 * onEventName(args);
40 * To clear event subscriptions:
41 * onEventName.clear();
42 */
43
Junxiao Shia93870d2014-11-05 22:35:31 -070044template<typename ...TArgs>
Yingdi Yufe140152014-07-24 10:02:40 -070045class EventEmitter : noncopyable
46{
47public:
Junxiao Shia93870d2014-11-05 22:35:31 -070048 /** \brief represents a handler that can subscribe to the event
49 */
50 typedef function<void(const TArgs&...)> Handler;
Yingdi Yufe140152014-07-24 10:02:40 -070051
Junxiao Shia93870d2014-11-05 22:35:31 -070052 /** \brief subscribes to the event
53 */
Yingdi Yufe140152014-07-24 10:02:40 -070054 void
Junxiao Shia93870d2014-11-05 22:35:31 -070055 operator+=(const Handler& handler);
Yingdi Yufe140152014-07-24 10:02:40 -070056
Junxiao Shia93870d2014-11-05 22:35:31 -070057 /** \return true if there is no subscription, false otherwise
58 */
Yingdi Yufe140152014-07-24 10:02:40 -070059 bool
60 isEmpty() const;
61
Junxiao Shia93870d2014-11-05 22:35:31 -070062 /** \brief clears all subscriptions
63 */
Yingdi Yufe140152014-07-24 10:02:40 -070064 void
65 clear();
66
Junxiao Shia93870d2014-11-05 22:35:31 -070067 /** \brief triggers the event
68 */
Yingdi Yufe140152014-07-24 10:02:40 -070069 void
Junxiao Shia93870d2014-11-05 22:35:31 -070070 operator()(const TArgs&...args) const;
Yingdi Yufe140152014-07-24 10:02:40 -070071
72private:
73 std::vector<Handler> m_handlers;
74};
75
Junxiao Shia93870d2014-11-05 22:35:31 -070076template<typename ...TArgs>
Yingdi Yufe140152014-07-24 10:02:40 -070077inline void
Junxiao Shia93870d2014-11-05 22:35:31 -070078EventEmitter<TArgs...>::operator+=(const Handler& handler)
Yingdi Yufe140152014-07-24 10:02:40 -070079{
80 m_handlers.push_back(handler);
81}
82
Junxiao Shia93870d2014-11-05 22:35:31 -070083template<typename ...TArgs>
Yingdi Yufe140152014-07-24 10:02:40 -070084inline bool
Junxiao Shia93870d2014-11-05 22:35:31 -070085EventEmitter<TArgs...>::isEmpty() const
Yingdi Yufe140152014-07-24 10:02:40 -070086{
87 return m_handlers.empty();
88}
89
Junxiao Shia93870d2014-11-05 22:35:31 -070090template<typename ...TArgs>
Yingdi Yufe140152014-07-24 10:02:40 -070091inline void
Junxiao Shia93870d2014-11-05 22:35:31 -070092EventEmitter<TArgs...>::clear()
Yingdi Yufe140152014-07-24 10:02:40 -070093{
94 return m_handlers.clear();
95}
96
Junxiao Shia93870d2014-11-05 22:35:31 -070097template<typename ...TArgs>
Yingdi Yufe140152014-07-24 10:02:40 -070098inline void
Junxiao Shia93870d2014-11-05 22:35:31 -070099EventEmitter<TArgs...>::operator()(const TArgs&...args) const
Yingdi Yufe140152014-07-24 10:02:40 -0700100{
Junxiao Shia93870d2014-11-05 22:35:31 -0700101 for (const Handler& handler : m_handlers) {
102 handler(args...);
Yingdi Yufe140152014-07-24 10:02:40 -0700103 if (m_handlers.empty()) // .clear has been called
104 return;
105 }
106}
107
108
109} // namespace util
110} // namespace ndn
111
112#endif // NDN_UTIL_EVENT_EMITTER_HPP