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
32#include "ignition/common/Profiler.hh"
33
34namespace gazebo
35{
38 namespace event
39 {
42
45 class GZ_COMMON_VISIBLE Event
46 {
48 public: Event();
49
51 public: virtual ~Event();
52
55 public: virtual void Disconnect(int _id) = 0;
56
59 public: bool Signaled() const;
60
63 public: void SetSignaled(const bool _sig);
64
66 private: bool signaled;
67 };
68
70 class GZ_COMMON_VISIBLE Connection
71 {
75 public: Connection(Event *_e, const int _i);
76
78 public: ~Connection();
79
82 public: int Id() const;
83
85 private: Event *event = nullptr;
86
88 private: int id = -1;
89
91 private: common::Time creationTime;
92
94 public: template<typename T> friend class EventT;
95 };
96
98 template<typename T>
99 class EventT : public Event
100 {
102 public: EventT();
103
105 public: virtual ~EventT();
106
111 public: ConnectionPtr Connect(const std::function<T> &_subscriber);
112
115 public: virtual void Disconnect(int _id);
116
119 public: unsigned int ConnectionCount() const;
120
122 public: void operator()()
123 {this->Signal();}
124
127 public: template< typename P >
128 void operator()(const P &_p)
129 {
130 this->Signal(_p);
131 }
132
136 public: template< typename P1, typename P2 >
137 void operator()(const P1 &_p1, const P2 &_p2)
138 {
139 this->Signal(_p1, _p2);
140 }
141
146 public: template< typename P1, typename P2, typename P3 >
147 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
148 {
149 this->Signal(_p1, _p2, _p3);
150 }
151
157 public: template< typename P1, typename P2, typename P3, typename P4 >
158 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
159 const P4 &_p4)
160 {
161 this->Signal(_p1, _p2, _p3, _p4);
162 }
163
170 public: template< typename P1, typename P2, typename P3, typename P4,
171 typename P5 >
172 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
173 const P4 &_p4, const P5 &_p5)
174 {
175 this->Signal(_p1, _p2, _p3, _p4, _p5);
176 }
177
185 public: template< typename P1, typename P2, typename P3, typename P4,
186 typename P5, typename P6 >
187 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
188 const P4 &_p4, const P5 &_p5, const P6 &_p6)
189 {
190 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6);
191 }
192
201 public: template< typename P1, typename P2, typename P3, typename P4,
202 typename P5, typename P6, typename P7 >
203 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
204 const P4 &_p4, const P5 &_p5, const P6 &_p6,
205 const P7 &_p7)
206 {
207 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
208 }
209
219 public: template< typename P1, typename P2, typename P3, typename P4,
220 typename P5, typename P6, typename P7, typename P8 >
221 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
222 const P4 &_p4, const P5 &_p5, const P6 &_p6,
223 const P7 &_p7, const P8 &_p8)
224 {
225 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
226 }
227
238 public: template< typename P1, typename P2, typename P3, typename P4,
239 typename P5, typename P6, typename P7, typename P8,
240 typename P9 >
241 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
242 const P4 &_p4, const P5 &_p5, const P6 &_p6,
243 const P7 &_p7, const P8 &_p8, const P9 &_p9)
244 {
245 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
246 }
247
259 public: template< typename P1, typename P2, typename P3, typename P4,
260 typename P5, typename P6, typename P7, typename P8,
261 typename P9, typename P10 >
262 void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
263 const P4 &_p4, const P5 &_p5, const P6 &_p6,
264 const P7 &_p7, const P8 &_p8, const P9 &_p9,
265 const P10 &_p10)
266 {
267 this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
268 }
269
271 public: void Signal()
272 {
273 IGN_PROFILE("Event::Signal");
274
275 this->Cleanup();
276
277 this->SetSignaled(true);
278 for (const auto &iter: this->connections)
279 {
280 if ((iter.second != NULL) && iter.second->on)
281 {
282 IGN_PROFILE_BEGIN("callback0");
283 iter.second->callback();
284 IGN_PROFILE_END();
285 }
286 }
287 }
288
291 public: template< typename P >
292 void Signal(const P &_p)
293 {
294 IGN_PROFILE("Event::Signal");
295
296 this->Cleanup();
297
298 this->SetSignaled(true);
299 for (const auto &iter: this->connections)
300 {
301 if ((iter.second != NULL) && iter.second->on)
302 {
303 IGN_PROFILE_BEGIN("callback1");
304 iter.second->callback(_p);
305 IGN_PROFILE_END();
306 }
307 }
308 }
309
313 public: template< typename P1, typename P2 >
314 void Signal(const P1 &_p1, const P2 &_p2)
315 {
316 IGN_PROFILE("Event::Signal");
317
318 this->Cleanup();
319
320 this->SetSignaled(true);
321 for (const auto &iter: this->connections)
322 {
323 if ((iter.second != NULL) && iter.second->on)
324 {
325 IGN_PROFILE_BEGIN("callback2");
326 iter.second->callback(_p1, _p2);
327 IGN_PROFILE_END();
328 }
329 }
330 }
331
336 public: template< typename P1, typename P2, typename P3 >
337 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
338 {
339 IGN_PROFILE("Event::Signal");
340
341 this->Cleanup();
342
343 this->SetSignaled(true);
344 for (const auto &iter: this->connections)
345 {
346 if ((iter.second != NULL) && iter.second->on)
347 {
348 IGN_PROFILE_BEGIN("callback3");
349 iter.second->callback(_p1, _p2, _p3);
350 IGN_PROFILE_END();
351 }
352 }
353 }
354
360 public: template<typename P1, typename P2, typename P3, typename P4>
361 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
362 const P4 &_p4)
363 {
364 IGN_PROFILE("Event::Signal");
365
366 this->Cleanup();
367
368 this->SetSignaled(true);
369 for (const auto &iter: this->connections)
370 {
371 if ((iter.second != NULL) && iter.second->on)
372 {
373 IGN_PROFILE_BEGIN("callback4");
374 iter.second->callback(_p1, _p2, _p3, _p4);
375 IGN_PROFILE_END();
376 }
377 }
378 }
379
386 public: template<typename P1, typename P2, typename P3, typename P4,
387 typename P5>
388 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
389 const P4 &_p4, const P5 &_p5)
390 {
391 IGN_PROFILE("Event::Signal");
392
393 this->Cleanup();
394
395 this->SetSignaled(true);
396 for (const auto &iter: this->connections)
397 {
398 if ((iter.second != NULL) && iter.second->on)
399 {
400 IGN_PROFILE_BEGIN("callback5");
401 iter.second->callback(_p1, _p2, _p3, _p4, _p5);
402 IGN_PROFILE_END();
403 }
404 }
405 }
406
414 public: template<typename P1, typename P2, typename P3, typename P4,
415 typename P5, typename P6>
416 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
417 const P4 &_p4, const P5 &_p5, const P6 &_p6)
418 {
419 IGN_PROFILE("Event::Signal");
420
421 this->Cleanup();
422
423 this->SetSignaled(true);
424 for (const auto &iter: this->connections)
425 {
426 if ((iter.second != NULL) && iter.second->on)
427 {
428 IGN_PROFILE_BEGIN("callback6");
429 iter.second->callback(_p1, _p2, _p3, _p4, _p5, _p6);
430 IGN_PROFILE_END();
431 }
432 }
433 }
434
443 public: template<typename P1, typename P2, typename P3, typename P4,
444 typename P5, typename P6, typename P7>
445 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
446 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
447 {
448 IGN_PROFILE("Event::Signal");
449
450 this->Cleanup();
451
452 this->SetSignaled(true);
453 for (const auto &iter: this->connections)
454 {
455 if ((iter.second != NULL) && iter.second->on)
456 {
457 IGN_PROFILE_BEGIN("callback7");
458 iter.second->callback(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
459 IGN_PROFILE_END();
460 }
461 }
462 }
463
473 public: template<typename P1, typename P2, typename P3, typename P4,
474 typename P5, typename P6, typename P7, typename P8>
475 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
476 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
477 const P8 &_p8)
478 {
479 IGN_PROFILE("Event::Signal");
480
481 this->Cleanup();
482
483 this->SetSignaled(true);
484 for (const auto &iter: this->connections)
485 {
486 if ((iter.second != NULL) && iter.second->on)
487 {
488 IGN_PROFILE_BEGIN("callback8");
489 iter.second->callback(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
490 IGN_PROFILE_END();
491 }
492 }
493 }
494
505 public: template< typename P1, typename P2, typename P3, typename P4,
506 typename P5, typename P6, typename P7, typename P8,
507 typename P9 >
508 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
509 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
510 const P8 &_p8, const P9 &_p9)
511 {
512 IGN_PROFILE("Event::Signal");
513
514 this->Cleanup();
515
516 this->SetSignaled(true);
517 for (const auto &iter: this->connections)
518 {
519 if ((iter.second != NULL) && iter.second->on)
520 {
521 IGN_PROFILE_BEGIN("callback9");
522 iter.second->callback(
523 _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
524 IGN_PROFILE_END();
525 }
526 }
527 }
528
540 public: template< typename P1, typename P2, typename P3, typename P4,
541 typename P5, typename P6, typename P7, typename P8,
542 typename P9, typename P10 >
543 void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
544 const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
545 const P8 &_p8, const P9 &_p9, const P10 &_p10)
546 {
547 IGN_PROFILE("Event::Signal");
548
549 this->Cleanup();
550
551 this->SetSignaled(true);
552 for (const auto &iter: this->connections)
553 {
554 if ((iter.second != NULL) && iter.second->on)
555 {
556 IGN_PROFILE_BEGIN("callback10");
557 iter.second->callback(
558 _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
559 IGN_PROFILE_END();
560 }
561 }
562 }
563
567 private: void Cleanup();
568
570 private: class EventConnection
571 {
573 public: EventConnection(const bool _on, const std::function<T> &_cb)
574 : callback(_cb)
575 {
576 // Windows Visual Studio 2012 does not have atomic_bool constructor,
577 // so we have to set "on" using operator=
578 this->on = _on;
579 }
580
582 public: std::atomic_bool on;
583
585 public: std::function<T> callback;
586 };
587
590 typedef std::map<int, std::unique_ptr<EventConnection>> EvtConnectionMap;
591
593 private: EvtConnectionMap connections;
594
596 private: mutable std::mutex mutex;
597
599 private: std::list<typename EvtConnectionMap::const_iterator>
600 connectionsToRemove;
601 };
602
604 template<typename T>
606 : Event()
607 {
608 }
609
611 template<typename T>
613 {
614 std::lock_guard<std::mutex> lock(this->mutex);
615 this->connections.clear();
616 }
617
620 template<typename T>
621 ConnectionPtr EventT<T>::Connect(const std::function<T> &_subscriber)
622 {
623 std::lock_guard<std::mutex> lock(this->mutex);
624 int index = 0;
625 if (!this->connections.empty())
626 {
627 auto const &iter = this->connections.rbegin();
628 index = iter->first + 1;
629 }
630 this->connections[index].reset(new EventConnection(true, _subscriber));
631 return ConnectionPtr(new Connection(this, index));
632 }
633
636 template<typename T>
637 unsigned int EventT<T>::ConnectionCount() const
638 {
639 std::lock_guard<std::mutex> lock(this->mutex);
640 return this->connections.size();
641 }
642
645 template<typename T>
647 {
648 std::lock_guard<std::mutex> lock(this->mutex);
649 // Find the connection
650 auto const &it = this->connections.find(_id);
651
652 if (it != this->connections.end())
653 {
654 it->second->on = false;
655 this->connectionsToRemove.push_back(it);
656 }
657 }
658
661 template<typename T>
662 void EventT<T>::Cleanup()
663 {
664 std::lock_guard<std::mutex> lock(this->mutex);
665 // Remove all queue connections.
666 for (auto &conn : this->connectionsToRemove)
667 this->connections.erase(conn);
668 this->connectionsToRemove.clear();
669 }
671 }
672}
673#endif
#define NULL
Definition CommonTypes.hh:31
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:71
int Id() const
Get the id of this connection.
Connection(Event *_e, const int _i)
Constructor.
A class for event processing.
Definition Event.hh:100
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameter.
Definition Event.hh:361
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameter.
Definition Event.hh:337
void operator()(const P &_p)
Signal the event with one parameter.
Definition Event.hh:128
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameters.
Definition Event.hh:147
void Signal(const P &_p)
Signal the event with one parameter.
Definition Event.hh:292
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:203
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:543
void operator()()
Access the signal.
Definition Event.hh:122
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:187
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:445
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:172
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:262
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:416
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:508
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:475
void Signal(const P1 &_p1, const P2 &_p2)
Signal the event with two parameter.
Definition Event.hh:314
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:241
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:221
void operator()(const P1 &_p1, const P2 &_p2)
Signal the event with two parameters.
Definition Event.hh:137
void Signal()
Signal the event for all subscribers.
Definition Event.hh:271
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameters.
Definition Event.hh:158
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:388
Base class for all events.
Definition Event.hh:46
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:637
EventT()
Constructor.
Definition Event.hh:605
virtual void Disconnect(int _id)
Disconnect a callback to this event.
Definition Event.hh:646
ConnectionPtr Connect(const std::function< T > &_subscriber)
Connect a callback to this event.
Definition Event.hh:621
virtual ~EventT()
Destructor.
Definition Event.hh:612
boost::shared_ptr< Connection > ConnectionPtr
Definition CommonTypes.hh:134
Forward declarations for the common classes.
Definition Animation.hh:27