DART 6.7.3
Loading...
Searching...
No Matches
Signal.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2019, The DART development contributors
3 * All rights reserved.
4 *
5 * The list of contributors can be found at:
6 * https://github.com/dartsim/dart/blob/master/LICENSE
7 *
8 * This file is provided under the following "BSD-style" License:
9 * Redistribution and use in source and binary forms, with or
10 * without modification, are permitted provided that the following
11 * conditions are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer in the documentation and/or other materials provided
17 * with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifndef DART_COMMON_DETAIL_SIGNAL_HPP_
34#define DART_COMMON_DETAIL_SIGNAL_HPP_
35
36#include <vector>
37
38namespace dart {
39namespace common {
40
41//==============================================================================
42template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
43Signal<_Res (_ArgTypes...), Combiner>::Signal()
44{
45 // Do nothing
46}
47
48//==============================================================================
49template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
50Signal<_Res (_ArgTypes...), Combiner>::~Signal()
51{
52 disconnectAll();
53}
54
55//==============================================================================
56template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
57Connection Signal<_Res (_ArgTypes...), Combiner>::connect(const SlotType& _slot)
58{
59 auto newConnectionBody = std::make_shared<ConnectionBodyType>(_slot);
60 mConnectionBodies.insert(newConnectionBody);
61
62 return Connection(std::move(newConnectionBody));
63}
64
65//==============================================================================
66template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
67Connection Signal<_Res (_ArgTypes...), Combiner>::connect(SlotType&& _slot)
68{
69 auto newConnectionBody
70 = std::make_shared<ConnectionBodyType>(std::forward<SlotType>(_slot));
71 mConnectionBodies.insert(newConnectionBody);
72
73 return Connection(std::move(newConnectionBody));
74}
75
76//==============================================================================
77template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
78void Signal<_Res (_ArgTypes...), Combiner>::disconnect(
79 const Connection& _connection) const
80{
81 _connection.disconnect();
82}
83
84//==============================================================================
85template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
86void Signal<_Res (_ArgTypes...), Combiner>::disconnectAll()
87{
88 mConnectionBodies.clear();
89}
90
91//==============================================================================
92template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
93void Signal<_Res (_ArgTypes...), Combiner>::cleanupConnections()
94{
95 // Counts all the connected conection bodies
96 for (const auto& connectionBody : mConnectionBodies)
97 {
98 if (!connectionBody->isConnected())
99 mConnectionBodies.erase(connectionBody);
100 }
101}
102
103//==============================================================================
104template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
105std::size_t Signal<_Res (_ArgTypes...), Combiner>::getNumConnections() const
106{
107 std::size_t numConnections = 0;
108
109 // Counts all the connected conection bodies
110 for (const auto& connectionBody : mConnectionBodies)
111 {
112 if (connectionBody->isConnected())
113 ++numConnections;
114 }
115
116 return numConnections;
117}
118
119//==============================================================================
120template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
121template <typename... ArgTypes>
122_Res Signal<_Res (_ArgTypes...), Combiner>::raise(ArgTypes&&... _args)
123{
124 std::vector<ResultType> res(mConnectionBodies.size());
125 auto resIt = res.begin();
126
127 for (auto itr = mConnectionBodies.begin(); itr != mConnectionBodies.end(); )
128 {
129 if ((*itr)->isConnected())
130 {
131 *(resIt++) = (*itr)->getSlot()(std::forward<ArgTypes>(_args)...);
132 ++itr;
133 }
134 else
135 {
136 mConnectionBodies.erase(itr++);
137 }
138 }
139
140 return Combiner<ResultType>::process(res.begin(), resIt);
141}
142
143//==============================================================================
144template <typename _Res, typename... _ArgTypes, template<class> class Combiner>
145template <typename... ArgTypes>
146_Res Signal<_Res (_ArgTypes...), Combiner>::operator()(ArgTypes&&... _args)
147{
148 return raise(std::forward<ArgTypes>(_args)...);
149}
150
151//==============================================================================
152template <typename... _ArgTypes>
153Signal<void (_ArgTypes...)>::Signal()
154{
155 // Do nothing
156}
157
158//==============================================================================
159template <typename... _ArgTypes>
160Signal<void (_ArgTypes...)>::~Signal()
161{
162 disconnectAll();
163}
164
165//==============================================================================
166template <typename... _ArgTypes>
167Connection Signal<void (_ArgTypes...)>::connect(const SlotType& _slot)
168{
169 auto newConnectionBody = std::make_shared<ConnectionBodyType>(_slot);
170 mConnectionBodies.insert(newConnectionBody);
171
172 return Connection(std::move(newConnectionBody));
173}
174
175//==============================================================================
176template <typename... _ArgTypes>
177Connection Signal<void (_ArgTypes...)>::connect(SlotType&& _slot)
178{
179 auto newConnectionBody
180 = std::make_shared<ConnectionBodyType>(std::forward<SlotType>(_slot));
181 mConnectionBodies.insert(newConnectionBody);
182
183 return Connection(std::move(newConnectionBody));
184}
185
186//==============================================================================
187template <typename... _ArgTypes>
188void Signal<void (_ArgTypes...)>::disconnect(
189 const Connection& _connection) const
190{
191 _connection.disconnect();
192}
193
194//==============================================================================
195template <typename... _ArgTypes>
196void Signal<void (_ArgTypes...)>::disconnectAll()
197{
198 mConnectionBodies.clear();
199}
200
201//==============================================================================
202template <typename... _ArgTypes>
203void Signal<void (_ArgTypes...)>::cleanupConnections()
204{
205 // Counts all the connected conection bodies
206 for (const auto& connectionBody : mConnectionBodies)
207 {
208 if (!connectionBody->isConnected())
209 mConnectionBodies.erase(connectionBody);
210 }
211}
212
213//==============================================================================
214template <typename... _ArgTypes>
215std::size_t Signal<void (_ArgTypes...)>::getNumConnections() const
216{
217 std::size_t numConnections = 0;
218
219 // Counts all the connected conection bodies
220 for (const auto& connectionBody : mConnectionBodies)
221 {
222 if (connectionBody->isConnected())
223 ++numConnections;
224 }
225
226 return numConnections;
227}
228
229//==============================================================================
230template <typename... _ArgTypes>
231template <typename... ArgTypes>
232void Signal<void (_ArgTypes...)>::raise(ArgTypes&&... _args)
233{
234 for (auto itr = mConnectionBodies.begin(); itr != mConnectionBodies.end(); )
235 {
236 if ((*itr)->isConnected())
237 {
238 (*itr)->getSlot()(std::forward<ArgTypes>(_args)...);
239 ++itr;
240 }
241 else
242 {
243 mConnectionBodies.erase(itr++);
244 }
245 }
246}
247
248//==============================================================================
249template <typename... _ArgTypes>
250template <typename... ArgTypes>
251void Signal<void (_ArgTypes...)>::operator()(ArgTypes&&... _args)
252{
253 raise(std::forward<ArgTypes>(_args)...);
254}
255
256//==============================================================================
257template <typename T>
258SlotRegister<T>::SlotRegister(typename T::SignalType& _signal)
259 : mSignal(_signal)
260{
261 // Do nothing
262}
263
264//==============================================================================
265template <typename T>
267{
268 return mSignal.connect(_slot);
269}
270
271} // namespace common
272} // namespace dart
273
274#endif // DART_COMMON_DETAIL_SIGNAL_HPP_
275
class Connection
Definition Signal.hpp:47
void disconnect() const
Disconnect the connection.
Definition Signal.cpp:107
std::function< ResultType(_ArgTypes...)> SlotType
Definition Signal.hpp:114
std::function< void(_ArgTypes...)> SlotType
Definition Signal.hpp:164
Definition Signal.hpp:106
SlotRegister(typename T::SignalType &_signal)
Constructor given signal.
Definition Signal.hpp:258
typename T::SlotType SlotType
Definition Signal.hpp:216
Connection connect(const SlotType &_slot)
Connect a slot to the signal.
Definition Signal.hpp:266
Definition BulletCollisionDetector.cpp:63