Event.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2016 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 #include <boost/function.hpp>
30 #include <boost/bind.hpp>
31 
32 #include <gazebo/gazebo_config.h>
33 #include <gazebo/common/Time.hh>
35 #include <gazebo/math/Helpers.hh>
36 #include "gazebo/util/system.hh"
37 
38 namespace gazebo
39 {
42  namespace event
43  {
48 
50  // Private data members for Event class.
51  // This must be in the header due to templatization.
52  class GZ_COMMON_VISIBLE EventPrivate
53  {
54  // \brief Constructor
55  public: EventPrivate();
56 
58  public: bool signaled;
59  };
61 
64  class GZ_COMMON_VISIBLE Event
65  {
67  public: Event();
68 
70  public: virtual ~Event();
71 
74  public: virtual void Disconnect(ConnectionPtr _c) = 0;
75 
78  public: virtual void Disconnect(int _id) = 0;
79 
82  public: bool GetSignaled() const;
83 
86  protected: Event(EventPrivate &_d);
87 
89  protected: EventPrivate *dataPtr;
90  };
91 
93  // Private data members for Connection class.
94  class GZ_COMMON_VISIBLE ConnectionPrivate
95  {
97  public: ConnectionPrivate();
98 
102  public: ConnectionPrivate(Event *_e, int _i);
103 
105  public: Event *event;
106 
108  public: int id;
109 
111  public: common::Time creationTime;
112  };
114 
116  class GZ_COMMON_VISIBLE Connection
117  {
119  public: Connection();
120 
124  public: Connection(Event *_e, int _i);
125 
127  public: ~Connection();
128 
131  public: int GetId() const;
132 
134  private: ConnectionPrivate *dataPtr;
135 
137  public: template<typename T> friend class EventT;
138  };
139 
141  template<typename T>
143  {
145  public: EventConnection(const bool _on,
146  boost::function<T> *_cb)
147  : callback(_cb)
148  {
149  // Windows Visual Studio 2012 does not have atomic_bool constructor,
150  // so we have to set "on" using operator=
151  this->on = _on;
152  }
153 
155  public: std::atomic_bool on;
156 
158  public: std::shared_ptr<boost::function<T> > callback;
159  };
160 
162  // Private data members for EventT<T> class.
163  template< typename T>
164  class EventTPrivate : public EventPrivate
165  {
168  typedef std::map<int, std::shared_ptr<EventConnection<T> > >
169  EvtConnectionMap;
170 
172  public: EvtConnectionMap connections;
173 
175  public: std::mutex mutex;
176 
178  public: std::list<typename EvtConnectionMap::const_iterator>
179  connectionsToRemove;
180  };
182 
185  template< typename T>
186  class EventT : public Event
187  {
189  public: EventT();
190 
192  public: virtual ~EventT();
193 
198  public: ConnectionPtr Connect(const boost::function<T> &_subscriber);
199 
202  public: virtual void Disconnect(ConnectionPtr _c);
203 
206  public: virtual void Disconnect(int _id);
207 
210  public: unsigned int ConnectionCount() const;
211 
213  public: void operator()()
214  {this->Signal();}
215 
218  public: template< typename P >
219  void operator()(const P &_p)
220  {
221  this->Signal(_p);
222  }
223 
227  public: template< typename P1, typename P2 >
228  void operator()(const P1 &_p1, const P2 &_p2)
229  {
230  this->Signal(_p1, _p2);
231  }
232 
237  public: template< typename P1, typename P2, typename P3 >
238  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
239  {
240  this->Signal(_p1, _p2, _p3);
241  }
242 
248  public: template< typename P1, typename P2, typename P3, typename P4 >
249  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
250  const P4 &_p4)
251  {
252  this->Signal(_p1, _p2, _p3, _p4);
253  }
254 
261  public: template< typename P1, typename P2, typename P3, typename P4,
262  typename P5 >
263  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
264  const P4 &_p4, const P5 &_p5)
265  {
266  this->Signal(_p1, _p2, _p3, _p4, _p5);
267  }
268 
276  public: template< typename P1, typename P2, typename P3, typename P4,
277  typename P5, typename P6 >
278  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
279  const P4 &_p4, const P5 &_p5, const P6 &_p6)
280  {
281  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6);
282  }
283 
292  public: template< typename P1, typename P2, typename P3, typename P4,
293  typename P5, typename P6, typename P7 >
294  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
295  const P4 &_p4, const P5 &_p5, const P6 &_p6,
296  const P7 &_p7)
297  {
298  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
299  }
300 
310  public: template< typename P1, typename P2, typename P3, typename P4,
311  typename P5, typename P6, typename P7, typename P8 >
312  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
313  const P4 &_p4, const P5 &_p5, const P6 &_p6,
314  const P7 &_p7, const P8 &_p8)
315  {
316  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
317  }
318 
329  public: template< typename P1, typename P2, typename P3, typename P4,
330  typename P5, typename P6, typename P7, typename P8,
331  typename P9 >
332  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
333  const P4 &_p4, const P5 &_p5, const P6 &_p6,
334  const P7 &_p7, const P8 &_p8, const P9 &_p9)
335  {
336  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
337  }
338 
350  public: template< typename P1, typename P2, typename P3, typename P4,
351  typename P5, typename P6, typename P7, typename P8,
352  typename P9, typename P10 >
353  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
354  const P4 &_p4, const P5 &_p5, const P6 &_p6,
355  const P7 &_p7, const P8 &_p8, const P9 &_p9,
356  const P10 &_p10)
357  {
358  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
359  }
360 
362  public: void Signal()
363  {
364  this->Cleanup();
365 
366  this->myDataPtr->signaled = true;
367  for (auto iter: this->myDataPtr->connections)
368  {
369  if (iter.second->on)
370  (*iter.second->callback)();
371  }
372  }
373 
376  public: template< typename P >
377  void Signal(const P &_p)
378  {
379  this->Cleanup();
380 
381  this->myDataPtr->signaled = true;
382  for (auto iter: this->myDataPtr->connections)
383  {
384  if (iter.second->on)
385  (*iter.second->callback)(_p);
386  }
387  }
388 
392  public: template< typename P1, typename P2 >
393  void Signal(const P1 &_p1, const P2 &_p2)
394  {
395  this->Cleanup();
396 
397  this->myDataPtr->signaled = true;
398  for (auto iter: this->myDataPtr->connections)
399  {
400  if (iter.second->on)
401  (*iter.second->callback)(_p1, _p2);
402  }
403  }
404 
409  public: template< typename P1, typename P2, typename P3 >
410  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
411  {
412  this->Cleanup();
413 
414  this->myDataPtr->signaled = true;
415  for (auto iter: this->myDataPtr->connections)
416  {
417  if (iter.second->on)
418  (*iter.second->callback)(_p1, _p2, _p3);
419  }
420  }
421 
427  public: template<typename P1, typename P2, typename P3, typename P4>
428  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
429  const P4 &_p4)
430  {
431  this->Cleanup();
432 
433  this->myDataPtr->signaled = true;
434  for (auto iter: this->myDataPtr->connections)
435  {
436  if (iter.second->on)
437  (*iter.second->callback)(_p1, _p2, _p3, _p4);
438  }
439  }
440 
447  public: template<typename P1, typename P2, typename P3, typename P4,
448  typename P5>
449  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
450  const P4 &_p4, const P5 &_p5)
451  {
452  this->Cleanup();
453 
454  this->myDataPtr->signaled = true;
455  for (auto iter: this->myDataPtr->connections)
456  {
457  if (iter.second->on)
458  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5);
459  }
460  }
461 
469  public: template<typename P1, typename P2, typename P3, typename P4,
470  typename P5, typename P6>
471  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
472  const P4 &_p4, const P5 &_p5, const P6 &_p6)
473  {
474  this->Cleanup();
475 
476  this->myDataPtr->signaled = true;
477  for (auto iter: this->myDataPtr->connections)
478  {
479  if (iter.second->on)
480  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6);
481  }
482  }
483 
492  public: template<typename P1, typename P2, typename P3, typename P4,
493  typename P5, typename P6, typename P7>
494  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
495  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
496  {
497  this->Cleanup();
498 
499  this->myDataPtr->signaled = true;
500  for (auto iter: this->myDataPtr->connections.begin())
501  {
502  if (iter.second->on)
503  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
504  }
505  }
506 
516  public: template<typename P1, typename P2, typename P3, typename P4,
517  typename P5, typename P6, typename P7, typename P8>
518  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
519  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
520  const P8 &_p8)
521  {
522  this->Cleanup();
523 
524  this->myDataPtr->signaled = true;
525  for (auto iter: this->myDataPtr->connections)
526  {
527  if (iter.second->on)
528  {
529  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
530  }
531  }
532  }
533 
544  public: template< typename P1, typename P2, typename P3, typename P4,
545  typename P5, typename P6, typename P7, typename P8,
546  typename P9 >
547  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
548  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
549  const P8 &_p8, const P9 &_p9)
550  {
551  this->Cleanup();
552 
553  this->myDataPtr->signaled = true;
554  for (auto iter: this->myDataPtr->connections)
555  {
556  if (iter.second->on)
557  {
558  (*iter.second->callback)(
559  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
560  }
561  }
562  }
563 
575  public: template< typename P1, typename P2, typename P3, typename P4,
576  typename P5, typename P6, typename P7, typename P8,
577  typename P9, typename P10 >
578  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
579  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
580  const P8 &_p8, const P9 &_p9, const P10 &_p10)
581  {
582  this->Cleanup();
583 
584  this->myDataPtr->signaled = true;
585  for (auto iter: this->myDataPtr->connections)
586  {
587  if (iter.second->on)
588  {
589  (*iter.second->callback)(
590  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
591  }
592  }
593  }
594 
598  private: void Cleanup();
599 
601  private: EventTPrivate<T> *myDataPtr;
602  };
603 
605  template<typename T>
607  : Event(*(new EventTPrivate<T>()))
608  {
609  this->myDataPtr = static_cast<EventTPrivate<T>*>(this->dataPtr);
610  }
611 
613  template<typename T>
615  {
616  this->myDataPtr->connections.clear();
617  }
618 
621  template<typename T>
622  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
623  {
624  int index = 0;
625  if (!this->myDataPtr->connections.empty())
626  {
627  auto const &iter = this->myDataPtr->connections.rbegin();
628  index = iter->first + 1;
629  }
630  this->myDataPtr->connections[index].reset(new EventConnection<T>(true,
631  new boost::function<T>(_subscriber)));
632  return ConnectionPtr(new Connection(this, index));
633  }
634 
637  template<typename T>
639  {
640  if (!_c)
641  return;
642 
643  this->Disconnect(_c->GetId());
644  _c->dataPtr->event = NULL;
645  _c->dataPtr->id = -1;
646  }
647 
650  template<typename T>
651  unsigned int EventT<T>::ConnectionCount() const
652  {
653  return this->myDataPtr->connections.size();
654  }
655 
658  template<typename T>
659  void EventT<T>::Disconnect(int _id)
660  {
661  // Find the connection
662  auto const &it = this->myDataPtr->connections.find(_id);
663 
664  if (it != this->myDataPtr->connections.end())
665  {
666  it->second->on = false;
667  this->myDataPtr->connectionsToRemove.push_back(it);
668  }
669  }
670 
672  template<typename T>
673  void EventT<T>::Cleanup()
674  {
675  std::lock_guard<std::mutex> lock(this->myDataPtr->mutex);
676  // Remove all queue connections.
677  for (auto &conn : this->myDataPtr->connectionsToRemove)
678  this->myDataPtr->connections.erase(conn);
679  this->myDataPtr->connectionsToRemove.clear();
680  }
681 
683  }
684 }
685 #endif
unsigned int ConnectionCount() const
Get the number of connections.
Definition: Event.hh:651
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameters.
Definition: Event.hh:249
virtual ~EventT()
Destructor.
Definition: Event.hh:614
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:263
void Signal(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:377
Base class for all events.
Definition: Event.hh:64
A class that encapsulates a connection.
Definition: Event.hh:116
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:471
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:547
Definition: Event.hh:142
EventPrivate * dataPtr
Data pointer.
Definition: Event.hh:89
void operator()()
Access the signal.
Definition: Event.hh:213
void Signal(const P1 &_p1, const P2 &_p2)
Signal the event with two parameter.
Definition: Event.hh:393
EventT()
Constructor.
Definition: Event.hh:606
std::shared_ptr< boost::function< T > > callback
Callback function.
Definition: Event.hh:158
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:294
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:312
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:278
ConnectionPtr Connect(const boost::function< T > &_subscriber)
Connect a callback to this event.
Definition: Event.hh:622
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:353
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameters.
Definition: Event.hh:238
void operator()(const P1 &_p1, const P2 &_p2)
Signal the event with two parameters.
Definition: Event.hh:228
boost::shared_ptr< Connection > ConnectionPtr
Definition: CommonTypes.hh:153
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:449
#define NULL
Definition: CommonTypes.hh:31
std::atomic_bool on
On/off value for the event callback.
Definition: Event.hh:155
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameter.
Definition: Event.hh:410
virtual void Disconnect(ConnectionPtr _c)
Disconnect a callback to this event.
Definition: Event.hh:638
A class for event processing.
Definition: Event.hh:186
void Signal()
Signal the event for all subscribers.
Definition: Event.hh:362
EventConnection(const bool _on, boost::function< T > *_cb)
Constructor.
Definition: Event.hh:145
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameter.
Definition: Event.hh:428
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:494
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:578
void operator()(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:219
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:332
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:518