blob: fa7de00f5f7a9bba15cfeebdbfa2973e7437f80e [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (C) 2014 Named Data Networking Project
* See COPYING for copyright and distribution information.
*/
#ifndef NFD_UTIL_EVENT_EMITTER_H
#define NFD_UTIL_EVENT_EMITTER_H
#include <vector>
#include <boost/utility.hpp>
#include <boost/function.hpp>
namespace ndn {
struct empty {};
/** \class EventEmitter
* \brief provides a lightweight event system
*
* To declare an event:
* EventEmitter<TArgs> m_eventName;
* To subscribe to an event:
* eventSource->m_eventName += eventHandler;
* Multiple functions can subscribe to the same event.
* To trigger an event:
* m_eventName(args);
* To clear event subscriptions:
* m_eventName.clear();
*/
// four arguments
template<typename T1 = empty, typename T2 = empty,
typename T3 = empty, typename T4 = empty>
class EventEmitter : boost::noncopyable
{
public:
/// represents a handler that can subscribe to the event
typedef boost::function<void(const T1&, const T2&,
const T3&, const T4&)> Handler;
/// adds an subscription
void
operator+=(Handler handler);
/// returns true if there is no subscription,
/// otherwise returns false
bool
isEmpty();
/// clears all subscriptions
void
clear();
/// triggers the event
void
operator()(const T1& a1, const T2& a2, const T3& a3, const T4& a4);
private:
/// stores all subscribed handlers
std::vector<Handler> m_handlers;
};
// zero argument
template<>
class EventEmitter<empty, empty, empty, empty> : boost::noncopyable
{
public:
typedef boost::function<void()> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()();
private:
std::vector<Handler> m_handlers;
};
// one argument
template<typename T1>
class EventEmitter<T1, empty, empty, empty> : boost::noncopyable
{
public:
typedef boost::function<void(const T1&)> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()(const T1& a1);
private:
std::vector<Handler> m_handlers;
};
// two arguments
template<typename T1, typename T2>
class EventEmitter<T1, T2, empty, empty> : boost::noncopyable
{
public:
typedef boost::function<void(const T1&, const T2&)> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()(const T1& a1, const T2& a2);
private:
std::vector<Handler> m_handlers;
};
// three arguments
template<typename T1, typename T2, typename T3>
class EventEmitter<T1, T2, T3, empty> : boost::noncopyable
{
public:
typedef boost::function<void(const T1&, const T2&,
const T3&)> Handler;
void
operator+=(Handler handler);
bool
isEmpty();
void
clear();
void
operator()(const T1& a1, const T2& a2, const T3& a3);
private:
std::vector<Handler> m_handlers;
};
// zero argument
inline void
EventEmitter<empty, empty, empty, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
inline bool
EventEmitter<empty, empty, empty, empty>::isEmpty()
{
return m_handlers.empty();
}
inline void
EventEmitter<empty, empty, empty, empty>::clear()
{
return m_handlers.clear();
}
inline void
EventEmitter<empty, empty, empty, empty>::operator()()
{
std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)();
}
}
// one argument
template<typename T1>
inline void
EventEmitter<T1, empty, empty, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1>
inline bool
EventEmitter<T1, empty, empty, empty>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1>
inline void
EventEmitter<T1, empty, empty, empty>::clear()
{
return m_handlers.clear();
}
template<typename T1>
inline void
EventEmitter<T1, empty, empty, empty>::operator()(const T1& a1)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1);
}
}
// two arguments
template<typename T1, typename T2>
inline void
EventEmitter<T1, T2, empty, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1, typename T2>
inline bool
EventEmitter<T1, T2, empty, empty>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1, typename T2>
inline void
EventEmitter<T1, T2, empty, empty>::clear()
{
return m_handlers.clear();
}
template<typename T1, typename T2>
inline void
EventEmitter<T1, T2, empty, empty>::operator()
(const T1& a1, const T2& a2)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1, a2);
}
}
// three arguments
template<typename T1, typename T2, typename T3>
inline void
EventEmitter<T1, T2, T3, empty>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1, typename T2, typename T3>
inline bool
EventEmitter<T1, T2, T3, empty>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1, typename T2, typename T3>
inline void
EventEmitter<T1, T2, T3, empty>::clear()
{
return m_handlers.clear();
}
template<typename T1, typename T2, typename T3>
inline void
EventEmitter<T1, T2, T3, empty>::operator()
(const T1& a1, const T2& a2, const T3& a3)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1, a2, a3);
}
}
// four arguments
template<typename T1, typename T2, typename T3, typename T4>
inline void
EventEmitter<T1, T2, T3, T4>::operator+=(Handler handler)
{
m_handlers.push_back(handler);
}
template<typename T1, typename T2, typename T3, typename T4>
inline bool
EventEmitter<T1, T2, T3, T4>::isEmpty()
{
return m_handlers.empty();
}
template<typename T1, typename T2, typename T3, typename T4>
inline void
EventEmitter<T1, T2, T3, T4>::clear()
{
return m_handlers.clear();
}
template<typename T1, typename T2, typename T3, typename T4>
inline void
EventEmitter<T1, T2, T3, T4>::operator()
(const T1& a1, const T2& a2, const T3& a3, const T4& a4)
{
typename std::vector<Handler>::iterator it;
for (it = m_handlers.begin(); it != m_handlers.end(); ++it) {
(*it)(a1, a2, a3, a4);
}
}
};//namespace ndn
#endif//NFD_UTIL_EVENT_EMITTER_H