22 #ifndef NDN_CXX_UTIL_SIGNAL_SIGNAL_HPP 
   23 #define NDN_CXX_UTIL_SIGNAL_SIGNAL_HPP 
   51 template<
typename Owner, 
typename ...TArgs>
 
   57   typedef function<void(
const TArgs&...)> 
Handler;
 
   91   operator()(
const TArgs&... args);
 
  123     shared_ptr<DisconnectFunction> disconnect;
 
  130   typedef std::list<Slot> SlotList;
 
  140   typename SlotList::iterator m_currentSlot;
 
  145   disconnect(
typename SlotList::iterator it);
 
  148 template<
typename Owner, 
typename ...TArgs>
 
  150   : m_isExecuting(false)
 
  154 template<
typename Owner, 
typename ...TArgs>
 
  157   BOOST_ASSERT(!m_isExecuting);
 
  160 template<
typename Owner, 
typename ...TArgs>
 
  164   auto it = m_slots.insert(m_slots.end(), {std::move(handler), nullptr});
 
  165   it->
disconnect = make_shared<DisconnectFunction>([=] { disconnect(it); });
 
  170 template<
typename Owner, 
typename ...TArgs>
 
  174   auto it = m_slots.insert(m_slots.end(), {nullptr, nullptr});
 
  175   it->
disconnect = make_shared<DisconnectFunction>([=] { disconnect(it); });
 
  178   it->handler = [conn, handler = std::move(handler)] (
const TArgs&... args) 
mutable {
 
  186 template<
typename Owner, 
typename ...TArgs>
 
  192     BOOST_ASSERT_MSG(it == m_currentSlot, 
"cannot disconnect another handler from a handler");
 
  196     m_currentSlot = m_slots.end();
 
  199     it->disconnect.reset();
 
  206 template<
typename Owner, 
typename ...TArgs>
 
  208 Signal<Owner, TArgs...>::isEmpty()
 const 
  210   return !m_isExecuting && m_slots.empty();
 
  213 template<
typename Owner, 
typename ...TArgs>
 
  215 Signal<Owner, TArgs...>::operator()(
const TArgs&... args)
 
  217   BOOST_ASSERT_MSG(!m_isExecuting, 
"cannot emit signal from a handler");
 
  219   if (m_slots.empty()) {
 
  223   auto guard = make_scope_exit([
this] { m_isExecuting = 
false; });
 
  224   m_isExecuting = 
true;
 
  226   auto it = m_slots.begin();
 
  227   auto last = std::prev(m_slots.end());
 
  233     m_currentSlot->handler(args...);
 
  235     if (m_currentSlot == m_slots.end())
 
  236       it = m_slots.erase(it);
 
  242 template<
typename Owner, 
typename ...TArgs>
 
  244 Signal<Owner, TArgs...>::operator()(
const TArgs&... args, 
const DummyExtraArg&)
 
  246   this->operator()(args...);
 
  252 using signal::Signal;
 
represents a connection to a signal
 
void disconnect()
disconnects from the signal
 
provides a lightweight signal / event system
 
function< void(const TArgs &...)> Handler
represents a function that can connect to the signal
 
Connection connect(Handler handler)
connects a handler to the signal
 
Connection connectSingleShot(Handler handler)
connects a single-shot handler to the signal