Event.hh
Go to the documentation of this file.
1/*
2 * Copyright (C) 2012 Open Source Robotics Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16*/
17#ifndef GAZEBO_COMMON_EVENT_HH_
18#define GAZEBO_COMMON_EVENT_HH_
19
20#include <atomic>
21#include <functional>
22#include <list>
23#include <map>
24#include <memory>
25#include <mutex>
26
27#include <gazebo/gazebo_config.h>
28#include <gazebo/common/Time.hh>
30#include "gazebo/util/system.hh"
31
32namespace gazebo
33{
36 namespace event
37 {
40
43 class GZ_COMMON_VISIBLE Event
44 {
46 public: Event();
47
49 public: virtual ~Event();
50
53 public: virtual void Disconnect(int _id) = 0;
54
57 public: bool Signaled() const;
58
61 public: void SetSignaled(const bool _sig);
62
64 private: bool signaled;
65 };
66
68 class GZ_COMMON_VISIBLE Connection
69 {
73 public: Connection(Event *_e, const int _i);
74
76 public: ~Connection();
77
80 public: int Id() const;
81
83 private: Event *event = nullptr;
84
86 private: int id = -1;
87
89 private: common::Time creationTime;
90
92 public: template<typename T> friend class EventT;
93 };
94
96 template<typename T>
97 class EventT : public Event
98 {
100 public: EventT();
101
103 public: virtual ~EventT();
104
109 public: ConnectionPtr Connect(const std::function<T> &_subscriber);
110
113 public: virtual void Disconnect(int _id);
114
117 public: unsigned int ConnectionCount() const;
118
120 public: void operator()()
121 {this->Signal();}
122
125 public: template< typename P >
126 void operator()(const P &_p)
127 {
128 this->Signal(_p);
129 }
130
134 public: template< typename P1, typename P2 >
135 void operator()(const P1 &_p1, const P2 &_p2)
136 {
137 this->Signal(_p1, _p2);
138 }
139
144 public: template< typename P1, typename P2, typename P3 >
145 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
146 {
147 this->Signal(_p1, _p2, _p3);
148 }
149
155 public: template< typename P1, typename P2, typename P3, typename P4 >
156 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
157 const P4 &_p4)
158 {
159 this->Signal(_p1, _p2, _p3, _p4);
160 }
161
168 public: template< typename P1, typename P2, typename P3, typename P4,
169 typename P5 >
170 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
171 const P4 &_p4, const P5 &_p5)
172 {
173 this->Signal(_p1, _p2, _p3, _p4, _p5);
174 }
175
183 public: template< typename P1, typename P2, typename P3, typename P4,
184 typename P5, typename P6 >
185 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
186 const P4 &_p4, const P5 &_p5, const P6 &_p6)
187 {
188 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6);
189 }
190
199 public: template< typename P1, typename P2, typename P3, typename P4,
200 typename P5, typename P6, typename P7 >
201 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
202 const P4 &_p4, const P5 &_p5, const P6 &_p6,
203 const P7 &_p7)
204 {
205 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
206 }
207
217 public: template< typename P1, typename P2, typename P3, typename P4,
218 typename P5, typename P6, typename P7, typename P8 >
219 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
220 const P4 &_p4, const P5 &_p5, const P6 &_p6,
221 const P7 &_p7, const P8 &_p8)
222 {
223 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
224 }
225
236 public: template< typename P1, typename P2, typename P3, typename P4,
237 typename P5, typename P6, typename P7, typename P8,
238 typename P9 >
239 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
240 const P4 &_p4, const P5 &_p5, const P6 &_p6,
241 const P7 &_p7, const P8 &_p8, const P9 &_p9)
242 {
243 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
244 }
245
257 public: template< typename P1, typename P2, typename P3, typename P4,
258 typename P5, typename P6, typename P7, typename P8,
259 typename P9, typename P10 >
260 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
261 const P4 &_p4, const P5 &_p5, const P6 &_p6,
262 const P7 &_p7, const P8 &_p8, const P9 &_p9,
263 const P10 &_p10)
264 {
265 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
266 }
267
269 public: void Signal()
270 {
271 this->Cleanup();
272
273 this->SetSignaled(true);
274 for (const auto &iter: this->connections)
275 {
276 if (iter.second->on)
277 iter.second->callback();
278 }
279 }
280
283 public: template< typename P >
284 void Signal(const P &_p)
285 {
286 this->Cleanup();
287
288 this->SetSignaled(true);
289 for (const auto &iter: this->connections)
290 {
291 if (iter.second->on)
292 iter.second->callback(_p);
293 }
294 }
295
299 public: template< typename P1, typename P2 >
300 void Signal(const P1 &_p1, const P2 &_p2)
301 {
302 this->Cleanup();
303
304 this->SetSignaled(true);
305 for (const auto &iter: this->connections)
306 {
307 if (iter.second->on)
308 iter.second->callback(_p1, _p2);
309 }
310 }
311
316 public: template< typename P1, typename P2, typename P3 >
317 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
318 {
319 this->Cleanup();
320
321 this->SetSignaled(true);
322 for (const auto &iter: this->connections)
323 {
324 if (iter.second->on)
325 iter.second->callback(_p1, _p2, _p3);
326 }
327 }
328
334 public: template<typename P1, typename P2, typename P3, typename P4>
335 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
336 const P4 &_p4)
337 {
338 this->Cleanup();
339
340 this->SetSignaled(true);
341 for (const auto &iter: this->connections)
342 {
343 if (iter.second->on)
344 iter.second->callback(_p1, _p2, _p3, _p4);
345 }
346 }
347
354 public: template<typename P1, typename P2, typename P3, typename P4,
355 typename P5>
356 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
357 const P4 &_p4, const P5 &_p5)
358 {
359 this->Cleanup();
360
361 this->SetSignaled(true);
362 for (const auto &iter: this->connections)
363 {
364 if (iter.second->on)
365 iter.second->callback(_p1, _p2, _p3, _p4, _p5);
366 }
367 }
368
376 public: template<typename P1, typename P2, typename P3, typename P4,
377 typename P5, typename P6>
378 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
379 const P4 &_p4, const P5 &_p5, const P6 &_p6)
380 {
381 this->Cleanup();
382
383 this->SetSignaled(true);
384 for (const auto &iter: this->connections)
385 {
386 if (iter.second->on)
387 iter.second->callback(_p1, _p2, _p3, _p4, _p5, _p6);
388 }
389 }
390
399 public: template<typename P1, typename P2, typename P3, typename P4,
400 typename P5, typename P6, typename P7>
401 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
402 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
403 {
404 this->Cleanup();
405
406 this->SetSignaled(true);
407 for (const auto &iter: this->connections)
408 {
409 if (iter.second->on)
410 iter.second->callback(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
411 }
412 }
413
423 public: template<typename P1, typename P2, typename P3, typename P4,
424 typename P5, typename P6, typename P7, typename P8>
425 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
426 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
427 const P8 &_p8)
428 {
429 this->Cleanup();
430
431 this->SetSignaled(true);
432 for (const auto &iter: this->connections)
433 {
434 if (iter.second->on)
435 {
436 iter.second->callback(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
437 }
438 }
439 }
440
451 public: template< typename P1, typename P2, typename P3, typename P4,
452 typename P5, typename P6, typename P7, typename P8,
453 typename P9 >
454 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
455 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
456 const P8 &_p8, const P9 &_p9)
457 {
458 this->Cleanup();
459
460 this->SetSignaled(true);
461 for (const auto &iter: this->connections)
462 {
463 if (iter.second->on)
464 {
465 iter.second->callback(
466 _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
467 }
468 }
469 }
470
482 public: template< typename P1, typename P2, typename P3, typename P4,
483 typename P5, typename P6, typename P7, typename P8,
484 typename P9, typename P10 >
485 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
486 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
487 const P8 &_p8, const P9 &_p9, const P10 &_p10)
488 {
489 this->Cleanup();
490
491 this->SetSignaled(true);
492 for (const auto &iter: this->connections)
493 {
494 if (iter.second->on)
495 {
496 iter.second->callback(
497 _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
498 }
499 }
500 }
501
505 private: void Cleanup();
506
508 private: class EventConnection
509 {
511 public: EventConnection(const bool _on, const std::function<T> &_cb)
512 : callback(_cb)
513 {
514 // Windows Visual Studio 2012 does not have atomic_bool constructor,
515 // so we have to set "on" using operator=
516 this->on = _on;
517 }
518
520 public: std::atomic_bool on;
521
523 public: std::function<T> callback;
524 };
525
528 typedef std::map<int, std::unique_ptr<EventConnection>> EvtConnectionMap;
529
531 private: EvtConnectionMap connections;
532
534 private: std::mutex mutex;
535
537 private: std::list<typename EvtConnectionMap::const_iterator>
538 connectionsToRemove;
539 };
540
542 template<typename T>
544 : Event()
545 {
546 }
547
549 template<typename T>
551 {
552 this->connections.clear();
553 }
554
557 template<typename T>
558 ConnectionPtr EventT<T>::Connect(const std::function<T> &_subscriber)
559 {
560 int index = 0;
561 if (!this->connections.empty())
562 {
563 auto const &iter = this->connections.rbegin();
564 index = iter->first + 1;
565 }
566 this->connections[index].reset(new EventConnection(true, _subscriber));
567 return ConnectionPtr(new Connection(this, index));
568 }
569
572 template<typename T>
573 unsigned int EventT<T>::ConnectionCount() const
574 {
575 return this->connections.size();
576 }
577
580 template<typename T>
582 {
583 // Find the connection
584 auto const &it = this->connections.find(_id);
585
586 if (it != this->connections.end())
587 {
588 it->second->on = false;
589 this->connectionsToRemove.push_back(it);
590 }
591 }
592
594 template<typename T>
595 void EventT<T>::Cleanup()
596 {
597 std::lock_guard<std::mutex> lock(this->mutex);
598 // Remove all queue connections.
599 for (auto &conn : this->connectionsToRemove)
600 this->connections.erase(conn);
601 this->connectionsToRemove.clear();
602 }
604 }
605}
606#endif
A Time class, can be used to hold wall- or sim-time.
Definition Time.hh:48
A class that encapsulates a connection.
Definition Event.hh:69
int Id() const
Get the id of this connection.
Connection(Event *_e, const int _i)
Constructor.
A class for event processing.
Definition Event.hh:98
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameter.
Definition Event.hh:335
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameter.
Definition Event.hh:317
void operator()(const P &_p)
Signal the event with one parameter.
Definition Event.hh:126
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameters.
Definition Event.hh:145
void Signal(const P &_p)
Signal the event with one parameter.
Definition Event.hh:284
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
Signal the event with seven parameters.
Definition Event.hh:201
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9, const P10 &_p10)
Signal the event with ten parameter.
Definition Event.hh:485
void operator()()
Access the signal.
Definition Event.hh:120
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6)
Signal the event with six parameters.
Definition Event.hh:185
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
Signal the event with seven parameter.
Definition Event.hh:401
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5)
Signal the event with five parameters.
Definition Event.hh:170
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9, const P10 &_p10)
Signal the event with ten parameters.
Definition Event.hh:260
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6)
Signal the event with six parameter.
Definition Event.hh:378
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9)
Signal the event with nine parameter.
Definition Event.hh:454
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8)
Signal the event with eight parameter.
Definition Event.hh:425
void Signal(const P1 &_p1, const P2 &_p2)
Signal the event with two parameter.
Definition Event.hh:300
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9)
Signal the event with nine parameters.
Definition Event.hh:239
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8)
Signal the event with eight parameters.
Definition Event.hh:219
void operator()(const P1 &_p1, const P2 &_p2)
Signal the event with two parameters.
Definition Event.hh:135
void Signal()
Signal the event for all subscribers.
Definition Event.hh:269
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameters.
Definition Event.hh:156
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5)
Signal the event with five parameter.
Definition Event.hh:356
Base class for all events.
Definition Event.hh:44
Event()
Constructor.
virtual void Disconnect(int _id)=0
Disconnect.
virtual ~Event()
Destructor.
void SetSignaled(const bool _sig)
Set whether this event has been signaled.
bool Signaled() const
Get whether this event has been signaled.
unsigned int ConnectionCount() const
Get the number of connections.
Definition Event.hh:573
EventT()
Constructor.
Definition Event.hh:543
virtual void Disconnect(int _id)
Disconnect a callback to this event.
Definition Event.hh:581
ConnectionPtr Connect(const std::function< T > &_subscriber)
Connect a callback to this event.
Definition Event.hh:558
virtual ~EventT()
Destructor.
Definition Event.hh:550
boost::shared_ptr< Connection > ConnectionPtr
Definition CommonTypes.hh:134
Forward declarations for the common classes.
Definition Animation.hh:27