DART 6.10.1
Loading...
Searching...
No Matches
Signal.hpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2021, 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>(*this, _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 = std::make_shared<ConnectionBodyType>(
70 *this, 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>::disconnect(
87 const std::shared_ptr<Signal::ConnectionBodyType>& connectionBody)
88{
89 mConnectionBodies.erase(connectionBody);
90}
91
92//==============================================================================
93template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
94void Signal<_Res(_ArgTypes...), Combiner>::disconnectAll()
95{
96 mConnectionBodies.clear();
97}
98
99//==============================================================================
100template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
101void Signal<_Res(_ArgTypes...), Combiner>::cleanupConnections()
102{
103 // Do nothing
104}
105
106//==============================================================================
107template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
108std::size_t Signal<_Res(_ArgTypes...), Combiner>::getNumConnections() const
109{
110 return mConnectionBodies.size();
111}
112
113//==============================================================================
114template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
115template <typename... ArgTypes>
116_Res Signal<_Res(_ArgTypes...), Combiner>::raise(ArgTypes&&... _args)
117{
118 std::vector<ResultType> res(mConnectionBodies.size());
119 auto resIt = res.begin();
120
121 for (const auto& connectionBody : mConnectionBodies)
122 {
123 *(resIt++) = connectionBody->getSlot()(std::forward<ArgTypes>(_args)...);
124 }
125
126 return Combiner<ResultType>::process(res.begin(), resIt);
127}
128
129//==============================================================================
130template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
131template <typename... ArgTypes>
132_Res Signal<_Res(_ArgTypes...), Combiner>::operator()(ArgTypes&&... _args)
133{
134 return raise(std::forward<ArgTypes>(_args)...);
135}
136
137//==============================================================================
138template <typename... _ArgTypes>
139Signal<void(_ArgTypes...)>::Signal()
140{
141 // Do nothing
142}
143
144//==============================================================================
145template <typename... _ArgTypes>
146Signal<void(_ArgTypes...)>::~Signal()
147{
148 disconnectAll();
149}
150
151//==============================================================================
152template <typename... _ArgTypes>
153Connection Signal<void(_ArgTypes...)>::connect(const SlotType& _slot)
154{
155 auto newConnectionBody = std::make_shared<ConnectionBodyType>(*this, _slot);
156 mConnectionBodies.insert(newConnectionBody);
157
158 return Connection(std::move(newConnectionBody));
159}
160
161//==============================================================================
162template <typename... _ArgTypes>
163Connection Signal<void(_ArgTypes...)>::connect(SlotType&& _slot)
164{
165 auto newConnectionBody = std::make_shared<ConnectionBodyType>(
166 *this, std::forward<SlotType>(_slot));
167 mConnectionBodies.insert(newConnectionBody);
168
169 return Connection(std::move(newConnectionBody));
170}
171
172//==============================================================================
173template <typename... _ArgTypes>
174void Signal<void(_ArgTypes...)>::disconnect(const Connection& _connection) const
175{
176 _connection.disconnect();
177}
178
179//==============================================================================
180template <typename... _ArgTypes>
181void Signal<void(_ArgTypes...)>::disconnect(
182 const std::shared_ptr<Signal::ConnectionBodyType>& connectionBody)
183{
184 mConnectionBodies.erase(connectionBody);
185}
186
187//==============================================================================
188template <typename... _ArgTypes>
189void Signal<void(_ArgTypes...)>::disconnectAll()
190{
191 mConnectionBodies.clear();
192}
193
194//==============================================================================
195template <typename... _ArgTypes>
196void Signal<void(_ArgTypes...)>::cleanupConnections()
197{
198 // Do nothing
199}
200
201//==============================================================================
202template <typename... _ArgTypes>
203std::size_t Signal<void(_ArgTypes...)>::getNumConnections() const
204{
205 return mConnectionBodies.size();
206}
207
208//==============================================================================
209template <typename... _ArgTypes>
210template <typename... ArgTypes>
211void Signal<void(_ArgTypes...)>::raise(ArgTypes&&... _args)
212{
213 for (const auto& connectionBody : mConnectionBodies)
214 {
215 connectionBody->getSlot()(std::forward<ArgTypes>(_args)...);
216 }
217}
218
219//==============================================================================
220template <typename... _ArgTypes>
221template <typename... ArgTypes>
222void Signal<void(_ArgTypes...)>::operator()(ArgTypes&&... _args)
223{
224 raise(std::forward<ArgTypes>(_args)...);
225}
226
227//==============================================================================
228template <typename T>
229SlotRegister<T>::SlotRegister(typename T::SignalType& _signal)
230 : mSignal(_signal)
231{
232 // Do nothing
233}
234
235//==============================================================================
236template <typename T>
239 return mSignal.connect(_slot);
240}
241
242} // namespace common
243} // namespace dart
244
245#endif // DART_COMMON_DETAIL_SIGNAL_HPP_
class Connection
Definition Signal.hpp:48
void disconnect() const
Disconnect the connection.
Definition Signal.cpp:101
std::function< ResultType(_ArgTypes...)> SlotType
Definition Signal.hpp:117
std::function< void(_ArgTypes...)> SlotType
Definition Signal.hpp:173
Definition Signal.hpp:109
SlotRegister(typename T::SignalType &_signal)
Constructor given signal.
Definition Signal.hpp:229
typename T::SlotType SlotType
Definition Signal.hpp:231
Connection connect(const SlotType &_slot)
Connect a slot to the signal.
Definition Signal.hpp:237
Definition BulletCollisionDetector.cpp:65