NS-3 based Named Data Networking (NDN) simulator
ndnSIM 2.5: NDN, CCN, CCNx, content centric networks
API Documentation
signal.hpp
Go to the documentation of this file.
1
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2
/*
3
* Copyright (c) 2013-2019 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
22
#ifndef NDN_UTIL_SIGNAL_SIGNAL_HPP
23
#define NDN_UTIL_SIGNAL_SIGNAL_HPP
24
25
#include "
ndn-cxx/util/signal/connection.hpp
"
26
27
#include <list>
28
29
namespace
ndn
{
30
namespace
util {
31
namespace
signal
{
32
33
class
DummyExtraArg;
34
50
template
<
typename
Owner,
typename
...TArgs>
51
class
Signal
: noncopyable
52
{
53
public
:
// API for anyone
56
typedef
function
<void(
const
TArgs&...)>
Handler
;
57
58
Signal
();
59
60
~Signal
();
61
66
Connection
67
connect
(
Handler
handler);
68
73
Connection
74
connectSingleShot
(
Handler
handler);
75
76
private
:
// API for owner
79
bool
80
isEmpty()
const
;
81
89
void
90
operator()(
const
TArgs&... args);
91
95
void
96
operator()(
const
TArgs&... args,
const
DummyExtraArg
&);
97
98
// make Owner a friend of Signal<Owner, ...> so that API for owner can be called
99
friend
Owner;
100
101
private
:
// internal implementation
102
typedef
Signal
<Owner, TArgs...>
Self
;
103
106
struct
Slot
107
{
110
Handler
handler;
111
122
shared_ptr<DisconnectFunction> disconnect;
123
};
124
129
typedef
std::list<Slot> SlotList;
130
SlotList m_slots;
131
134
bool
m_isExecuting;
135
139
typename
SlotList::iterator m_currentSlot;
140
143
void
144
disconnect(
typename
SlotList::iterator it);
145
};
146
147
template
<
typename
Owner,
typename
...TArgs>
148
Signal<Owner, TArgs...>::Signal
()
149
: m_isExecuting(false)
150
{
151
}
152
153
template
<
typename
Owner,
typename
...TArgs>
154
Signal<Owner, TArgs...>::~Signal
()
155
{
156
BOOST_ASSERT(!m_isExecuting);
157
}
158
159
template
<
typename
Owner,
typename
...TArgs>
160
Connection
161
Signal<Owner, TArgs...>::connect
(
Handler
handler)
162
{
163
auto
it = m_slots.insert(m_slots.end(), {std::move(handler), nullptr});
164
it->
disconnect
= make_shared<DisconnectFunction>([=] { disconnect(it); });
165
166
return
signal::Connection
(it->disconnect);
167
}
168
169
template
<
typename
Owner,
typename
...TArgs>
170
Connection
171
Signal<Owner, TArgs...>::connectSingleShot
(
Handler
handler)
172
{
173
auto
it = m_slots.insert(m_slots.end(), {nullptr, nullptr});
174
it->
disconnect
= make_shared<DisconnectFunction>([=] { disconnect(it); });
175
signal::Connection
conn(it->disconnect);
176
177
it->handler = [conn, handler =
std::move
(handler)] (
const
TArgs&... args)
mutable
{
178
handler(args...);
179
conn.disconnect();
180
};
181
182
return
conn;
183
}
184
185
template
<
typename
Owner,
typename
...TArgs>
186
void
187
Signal<Owner, TArgs...>::disconnect
(
typename
SlotList::iterator it)
188
{
189
if
(m_isExecuting) {
190
// during signal emission, only the currently executing handler can be disconnected
191
BOOST_ASSERT_MSG(it == m_currentSlot,
"cannot disconnect another handler from a handler"
);
192
193
// this serves to indicate that the current slot needs to be erased from the list
194
// after it finishes executing; we cannot do it here because of bug #2333
195
m_currentSlot = m_slots.end();
196
197
// expire all weak_ptrs, to prevent double disconnections
198
it->disconnect.reset();
199
}
200
else
{
201
m_slots.erase(it);
202
}
203
}
204
205
template
<
typename
Owner,
typename
...TArgs>
206
bool
207
Signal<Owner, TArgs...>::isEmpty()
const
208
{
209
return
!m_isExecuting && m_slots.empty();
210
}
211
212
template
<
typename
Owner,
typename
...TArgs>
213
void
214
Signal<Owner, TArgs...>::operator()(
const
TArgs&... args)
215
{
216
BOOST_ASSERT_MSG(!m_isExecuting,
"cannot emit signal from a handler"
);
217
218
if
(m_slots.empty()) {
219
return
;
220
}
221
222
auto
it = m_slots.begin();
223
auto
last = std::prev(m_slots.end());
224
m_isExecuting =
true
;
225
226
try
{
227
bool
isLast =
false
;
228
while
(!isLast) {
229
m_currentSlot = it;
230
isLast = it == last;
231
232
m_currentSlot->handler(args...);
233
234
if
(m_currentSlot == m_slots.end())
235
it = m_slots.erase(it);
236
else
237
++it;
238
}
239
}
240
catch
(...) {
241
m_isExecuting =
false
;
242
throw
;
243
}
244
245
m_isExecuting =
false
;
246
}
247
248
template
<
typename
Owner,
typename
...TArgs>
249
void
250
Signal<Owner, TArgs...>::operator()(
const
TArgs&... args,
const
DummyExtraArg&)
251
{
252
this->operator()(args...);
253
}
254
255
}
// namespace signal
256
257
// expose as ndn::util::Signal
258
using
signal::Signal
;
259
260
}
// namespace util
261
}
// namespace ndn
262
263
#endif // NDN_UTIL_SIGNAL_SIGNAL_HPP
nonstd::optional_lite::std11::move
T & move(T &t)
Definition:
optional.hpp:421
ndn::util::signal::Signal::connectSingleShot
Connection connectSingleShot(Handler handler)
connects a single-shot handler to the signal
Definition:
signal.hpp:171
ndn::util::signal::Signal::connect
Connection connect(Handler handler)
connects a handler to the signal
Definition:
signal.hpp:161
ndn::util::signal::Signal::Handler
function< void(const TArgs &...)> Handler
represents a function that can connect to the signal
Definition:
signal.hpp:56
ndn::util::signal::DummyExtraArg
(implementation detail) a filler for extra argument
Definition:
emit.hpp:43
ndn::util::signal
Definition:
connection.cpp:26
ndn::util::signal::Connection
represents a connection to a signal
Definition:
connection.hpp:37
ndn::util::signal::Signal
provides a lightweight signal / event system
Definition:
signal.hpp:52
connection.hpp
ndn::util::signal::Signal::Signal
Signal()
Definition:
signal.hpp:148
ndn::util::signal::Connection::disconnect
void disconnect()
disconnects from the signal
Definition:
connection.cpp:36
ndn::util::signal::Signal::~Signal
~Signal()
Definition:
signal.hpp:154
ndn
Copyright (c) 2011-2015 Regents of the University of California.
Definition:
ndn-strategy-choice-helper.hpp:34
ndnSIM
ndn-cxx
ndn-cxx
util
signal
signal.hpp
Generated on Mon Jun 1 2020 22:32:15 for ndnSIM by
1.8.18