DART  6.10.1
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 
38 namespace dart {
39 namespace common {
40 
41 //==============================================================================
42 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
43 Signal<_Res(_ArgTypes...), Combiner>::Signal()
44 {
45  // Do nothing
46 }
47 
48 //==============================================================================
49 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
50 Signal<_Res(_ArgTypes...), Combiner>::~Signal()
51 {
52  disconnectAll();
53 }
54 
55 //==============================================================================
56 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
57 Connection 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 //==============================================================================
66 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
67 Connection 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 //==============================================================================
77 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
78 void Signal<_Res(_ArgTypes...), Combiner>::disconnect(
79  const Connection& _connection) const
80 {
81  _connection.disconnect();
82 }
83 
84 //==============================================================================
85 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
86 void Signal<_Res(_ArgTypes...), Combiner>::disconnect(
87  const std::shared_ptr<Signal::ConnectionBodyType>& connectionBody)
88 {
89  mConnectionBodies.erase(connectionBody);
90 }
91 
92 //==============================================================================
93 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
94 void Signal<_Res(_ArgTypes...), Combiner>::disconnectAll()
95 {
96  mConnectionBodies.clear();
97 }
98 
99 //==============================================================================
100 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
101 void Signal<_Res(_ArgTypes...), Combiner>::cleanupConnections()
102 {
103  // Do nothing
104 }
105 
106 //==============================================================================
107 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
108 std::size_t Signal<_Res(_ArgTypes...), Combiner>::getNumConnections() const
109 {
110  return mConnectionBodies.size();
111 }
112 
113 //==============================================================================
114 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
115 template <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 //==============================================================================
130 template <typename _Res, typename... _ArgTypes, template <class> class Combiner>
131 template <typename... ArgTypes>
132 _Res Signal<_Res(_ArgTypes...), Combiner>::operator()(ArgTypes&&... _args)
133 {
134  return raise(std::forward<ArgTypes>(_args)...);
135 }
136 
137 //==============================================================================
138 template <typename... _ArgTypes>
139 Signal<void(_ArgTypes...)>::Signal()
140 {
141  // Do nothing
142 }
143 
144 //==============================================================================
145 template <typename... _ArgTypes>
146 Signal<void(_ArgTypes...)>::~Signal()
147 {
148  disconnectAll();
149 }
150 
151 //==============================================================================
152 template <typename... _ArgTypes>
153 Connection 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 //==============================================================================
162 template <typename... _ArgTypes>
163 Connection 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 //==============================================================================
173 template <typename... _ArgTypes>
174 void Signal<void(_ArgTypes...)>::disconnect(const Connection& _connection) const
175 {
176  _connection.disconnect();
177 }
178 
179 //==============================================================================
180 template <typename... _ArgTypes>
181 void Signal<void(_ArgTypes...)>::disconnect(
182  const std::shared_ptr<Signal::ConnectionBodyType>& connectionBody)
183 {
184  mConnectionBodies.erase(connectionBody);
185 }
186 
187 //==============================================================================
188 template <typename... _ArgTypes>
189 void Signal<void(_ArgTypes...)>::disconnectAll()
190 {
191  mConnectionBodies.clear();
192 }
193 
194 //==============================================================================
195 template <typename... _ArgTypes>
196 void Signal<void(_ArgTypes...)>::cleanupConnections()
197 {
198  // Do nothing
199 }
200 
201 //==============================================================================
202 template <typename... _ArgTypes>
203 std::size_t Signal<void(_ArgTypes...)>::getNumConnections() const
204 {
205  return mConnectionBodies.size();
206 }
207 
208 //==============================================================================
209 template <typename... _ArgTypes>
210 template <typename... ArgTypes>
211 void 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 //==============================================================================
220 template <typename... _ArgTypes>
221 template <typename... ArgTypes>
222 void Signal<void(_ArgTypes...)>::operator()(ArgTypes&&... _args)
223 {
224  raise(std::forward<ArgTypes>(_args)...);
225 }
226 
227 //==============================================================================
228 template <typename T>
229 SlotRegister<T>::SlotRegister(typename T::SignalType& _signal)
230  : mSignal(_signal)
231 {
232  // Do nothing
233 }
234 
235 //==============================================================================
236 template <typename T>
238 {
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