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 
18 #ifndef _GAZEBO_EVENT_HH_
19 #define _GAZEBO_EVENT_HH_
20 
21 #include <atomic>
22 #include <iostream>
23 #include <vector>
24 #include <map>
25 #include <memory>
26 #include <mutex>
27 #include <list>
28 
29 #ifndef Q_MOC_RUN
30 #include <boost/function.hpp>
31 #include <boost/bind.hpp>
32 #endif
33 
34 #include <gazebo/gazebo_config.h>
35 #include <gazebo/common/Time.hh>
37 #include <gazebo/math/Helpers.hh>
38 #include "gazebo/util/system.hh"
39 
40 namespace gazebo
41 {
44  namespace event
45  {
50 
52  // Private data members for Event class.
53  // This must be in the header due to templatization.
54  class GZ_COMMON_VISIBLE EventPrivate
55  {
56  // \brief Constructor
57  public: EventPrivate();
58 
60  public: bool signaled;
61  };
63 
66  class GZ_COMMON_VISIBLE Event
67  {
69  public: Event();
70 
72  public: virtual ~Event();
73 
76  public: virtual void Disconnect(ConnectionPtr _c) = 0;
77 
80  public: virtual void Disconnect(int _id) = 0;
81 
84  public: bool GetSignaled() const;
85 
88  protected: Event(EventPrivate &_d);
89 
91  protected: EventPrivate *dataPtr;
92  };
93 
95  // Private data members for Connection class.
96  class GZ_COMMON_VISIBLE ConnectionPrivate
97  {
99  public: ConnectionPrivate();
100 
104  public: ConnectionPrivate(Event *_e, int _i);
105 
107  public: Event *event;
108 
110  public: int id;
111 
113  public: common::Time creationTime;
114  };
116 
118  class GZ_COMMON_VISIBLE Connection
119  {
121  public: Connection();
122 
126  public: Connection(Event *_e, int _i);
127 
129  public: ~Connection();
130 
133  public: int GetId() const;
134 
136  private: ConnectionPrivate *dataPtr;
137 
139  public: template<typename T> friend class EventT;
140  };
141 
143  template<typename T>
145  {
147  public: EventConnection(const bool _on,
148  boost::function<T> *_cb)
149  : callback(_cb)
150  {
151  // Windows Visual Studio 2012 does not have atomic_bool constructor,
152  // so we have to set "on" using operator=
153  this->on = _on;
154  }
155 
157  public: std::atomic_bool on;
158 
160  public: std::shared_ptr<boost::function<T> > callback;
161  };
162 
164  // Private data members for EventT<T> class.
165  template< typename T>
166  class EventTPrivate : public EventPrivate
167  {
170  typedef std::map<int, std::shared_ptr<EventConnection<T> > >
171  EvtConnectionMap;
172 
174  public: EvtConnectionMap connections;
175 
177  public: std::mutex mutex;
178 
180  public: std::list<typename EvtConnectionMap::const_iterator>
181  connectionsToRemove;
182  };
184 
187  template< typename T>
188  class EventT : public Event
189  {
191  public: EventT();
192 
194  public: virtual ~EventT();
195 
200  public: ConnectionPtr Connect(const boost::function<T> &_subscriber);
201 
204  public: virtual void Disconnect(ConnectionPtr _c);
205 
208  public: virtual void Disconnect(int _id);
209 
212  public: unsigned int ConnectionCount() const;
213 
215  public: void operator()()
216  {this->Signal();}
217 
220  public: template< typename P >
221  void operator()(const P &_p)
222  {
223  this->Signal(_p);
224  }
225 
229  public: template< typename P1, typename P2 >
230  void operator()(const P1 &_p1, const P2 &_p2)
231  {
232  this->Signal(_p1, _p2);
233  }
234 
239  public: template< typename P1, typename P2, typename P3 >
240  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
241  {
242  this->Signal(_p1, _p2, _p3);
243  }
244 
250  public: template< typename P1, typename P2, typename P3, typename P4 >
251  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
252  const P4 &_p4)
253  {
254  this->Signal(_p1, _p2, _p3, _p4);
255  }
256 
263  public: template< typename P1, typename P2, typename P3, typename P4,
264  typename P5 >
265  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
266  const P4 &_p4, const P5 &_p5)
267  {
268  this->Signal(_p1, _p2, _p3, _p4, _p5);
269  }
270 
278  public: template< typename P1, typename P2, typename P3, typename P4,
279  typename P5, typename P6 >
280  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
281  const P4 &_p4, const P5 &_p5, const P6 &_p6)
282  {
283  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6);
284  }
285 
294  public: template< typename P1, typename P2, typename P3, typename P4,
295  typename P5, typename P6, typename P7 >
296  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
297  const P4 &_p4, const P5 &_p5, const P6 &_p6,
298  const P7 &_p7)
299  {
300  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
301  }
302 
312  public: template< typename P1, typename P2, typename P3, typename P4,
313  typename P5, typename P6, typename P7, typename P8 >
314  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
315  const P4 &_p4, const P5 &_p5, const P6 &_p6,
316  const P7 &_p7, const P8 &_p8)
317  {
318  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
319  }
320 
331  public: template< typename P1, typename P2, typename P3, typename P4,
332  typename P5, typename P6, typename P7, typename P8,
333  typename P9 >
334  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
335  const P4 &_p4, const P5 &_p5, const P6 &_p6,
336  const P7 &_p7, const P8 &_p8, const P9 &_p9)
337  {
338  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
339  }
340 
352  public: template< typename P1, typename P2, typename P3, typename P4,
353  typename P5, typename P6, typename P7, typename P8,
354  typename P9, typename P10 >
355  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
356  const P4 &_p4, const P5 &_p5, const P6 &_p6,
357  const P7 &_p7, const P8 &_p8, const P9 &_p9,
358  const P10 &_p10)
359  {
360  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
361  }
362 
364  public: void Signal()
365  {
366  this->Cleanup();
367 
368  this->myDataPtr->signaled = true;
369  for (auto iter: this->myDataPtr->connections)
370  {
371  if (iter.second->on)
372  (*iter.second->callback)();
373  }
374  }
375 
378  public: template< typename P >
379  void Signal(const P &_p)
380  {
381  this->Cleanup();
382 
383  this->myDataPtr->signaled = true;
384  for (auto iter: this->myDataPtr->connections)
385  {
386  if (iter.second->on)
387  (*iter.second->callback)(_p);
388  }
389  }
390 
394  public: template< typename P1, typename P2 >
395  void Signal(const P1 &_p1, const P2 &_p2)
396  {
397  this->Cleanup();
398 
399  this->myDataPtr->signaled = true;
400  for (auto iter: this->myDataPtr->connections)
401  {
402  if (iter.second->on)
403  (*iter.second->callback)(_p1, _p2);
404  }
405  }
406 
411  public: template< typename P1, typename P2, typename P3 >
412  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
413  {
414  this->Cleanup();
415 
416  this->myDataPtr->signaled = true;
417  for (auto iter: this->myDataPtr->connections)
418  {
419  if (iter.second->on)
420  (*iter.second->callback)(_p1, _p2, _p3);
421  }
422  }
423 
429  public: template<typename P1, typename P2, typename P3, typename P4>
430  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
431  const P4 &_p4)
432  {
433  this->Cleanup();
434 
435  this->myDataPtr->signaled = true;
436  for (auto iter: this->myDataPtr->connections)
437  {
438  if (iter.second->on)
439  (*iter.second->callback)(_p1, _p2, _p3, _p4);
440  }
441  }
442 
449  public: template<typename P1, typename P2, typename P3, typename P4,
450  typename P5>
451  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
452  const P4 &_p4, const P5 &_p5)
453  {
454  this->Cleanup();
455 
456  this->myDataPtr->signaled = true;
457  for (auto iter: this->myDataPtr->connections)
458  {
459  if (iter.second->on)
460  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5);
461  }
462  }
463 
471  public: template<typename P1, typename P2, typename P3, typename P4,
472  typename P5, typename P6>
473  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
474  const P4 &_p4, const P5 &_p5, const P6 &_p6)
475  {
476  this->Cleanup();
477 
478  this->myDataPtr->signaled = true;
479  for (auto iter: this->myDataPtr->connections)
480  {
481  if (iter.second->on)
482  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6);
483  }
484  }
485 
494  public: template<typename P1, typename P2, typename P3, typename P4,
495  typename P5, typename P6, typename P7>
496  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
497  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
498  {
499  this->Cleanup();
500 
501  this->myDataPtr->signaled = true;
502  for (auto iter: this->myDataPtr->connections.begin())
503  {
504  if (iter.second->on)
505  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
506  }
507  }
508 
518  public: template<typename P1, typename P2, typename P3, typename P4,
519  typename P5, typename P6, typename P7, typename P8>
520  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
521  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
522  const P8 &_p8)
523  {
524  this->Cleanup();
525 
526  this->myDataPtr->signaled = true;
527  for (auto iter: this->myDataPtr->connections)
528  {
529  if (iter.second->on)
530  {
531  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
532  }
533  }
534  }
535 
546  public: template< typename P1, typename P2, typename P3, typename P4,
547  typename P5, typename P6, typename P7, typename P8,
548  typename P9 >
549  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
550  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
551  const P8 &_p8, const P9 &_p9)
552  {
553  this->Cleanup();
554 
555  this->myDataPtr->signaled = true;
556  for (auto iter: this->myDataPtr->connections)
557  {
558  if (iter.second->on)
559  {
560  (*iter.second->callback)(
561  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
562  }
563  }
564  }
565 
577  public: template< typename P1, typename P2, typename P3, typename P4,
578  typename P5, typename P6, typename P7, typename P8,
579  typename P9, typename P10 >
580  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
581  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
582  const P8 &_p8, const P9 &_p9, const P10 &_p10)
583  {
584  this->Cleanup();
585 
586  this->myDataPtr->signaled = true;
587  for (auto iter: this->myDataPtr->connections)
588  {
589  if (iter.second->on)
590  {
591  (*iter.second->callback)(
592  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
593  }
594  }
595  }
596 
600  private: void Cleanup();
601 
603  private: EventTPrivate<T> *myDataPtr;
604  };
605 
607  template<typename T>
609  : Event(*(new EventTPrivate<T>()))
610  {
611  this->myDataPtr = static_cast<EventTPrivate<T>*>(this->dataPtr);
612  }
613 
615  template<typename T>
617  {
618  this->myDataPtr->connections.clear();
619  }
620 
623  template<typename T>
624  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
625  {
626  int index = 0;
627  if (!this->myDataPtr->connections.empty())
628  {
629  auto const &iter = this->myDataPtr->connections.rbegin();
630  index = iter->first + 1;
631  }
632  this->myDataPtr->connections[index].reset(new EventConnection<T>(true,
633  new boost::function<T>(_subscriber)));
634  return ConnectionPtr(new Connection(this, index));
635  }
636 
639  template<typename T>
641  {
642  if (!_c)
643  return;
644 
645  this->Disconnect(_c->GetId());
646  _c->dataPtr->event = NULL;
647  _c->dataPtr->id = -1;
648  }
649 
652  template<typename T>
653  unsigned int EventT<T>::ConnectionCount() const
654  {
655  return this->myDataPtr->connections.size();
656  }
657 
660  template<typename T>
661  void EventT<T>::Disconnect(int _id)
662  {
663  // Find the connection
664  auto const &it = this->myDataPtr->connections.find(_id);
665 
666  if (it != this->myDataPtr->connections.end())
667  {
668  it->second->on = false;
669  this->myDataPtr->connectionsToRemove.push_back(it);
670  }
671  }
672 
674  template<typename T>
675  void EventT<T>::Cleanup()
676  {
677  std::lock_guard<std::mutex> lock(this->myDataPtr->mutex);
678  // Remove all queue connections.
679  for (auto &conn : this->myDataPtr->connectionsToRemove)
680  this->myDataPtr->connections.erase(conn);
681  this->myDataPtr->connectionsToRemove.clear();
682  }
683 
685  }
686 }
687 #endif
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameters.
Definition: Event.hh:251
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:265
void Signal(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:379
Base class for all events.
Definition: Event.hh:66
A class that encapsulates a connection.
Definition: Event.hh:118
Forward declarations for the common classes.
Definition: Animation.hh:33
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:473
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:549
Definition: Event.hh:144
EventPrivate * dataPtr
Data pointer.
Definition: Event.hh:91
void operator()()
Access the signal.
Definition: Event.hh:215
void Signal(const P1 &_p1, const P2 &_p2)
Signal the event with two parameter.
Definition: Event.hh:395
EventT()
Constructor.
Definition: Event.hh:608
std::shared_ptr< boost::function< T > > callback
Callback function.
Definition: Event.hh:160
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:296
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:314
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:280
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:355
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameters.
Definition: Event.hh:240
void operator()(const P1 &_p1, const P2 &_p2)
Signal the event with two parameters.
Definition: Event.hh:230
boost::shared_ptr< Connection > ConnectionPtr
Definition: CommonTypes.hh:155
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:451
#define NULL
Definition: CommonTypes.hh:33
std::atomic_bool on
On/off value for the event callback.
Definition: Event.hh:157
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameter.
Definition: Event.hh:412
A class for event processing.
Definition: Event.hh:188
void Signal()
Signal the event for all subscribers.
Definition: Event.hh:364
EventConnection(const bool _on, boost::function< T > *_cb)
Constructor.
Definition: Event.hh:147
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameter.
Definition: Event.hh:430
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:496
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:580
void operator()(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:221
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:334
A Time class, can be used to hold wall- or sim-time.
Definition: Time.hh:44
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:520