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  {
46 
48  // Private data members for Event class.
49  // This must be in the header due to templatization.
51  {
52  // \brief Constructor
53  public: EventPrivate();
54 
56  public: bool signaled;
57  };
58 
62  {
64  public: Event();
65 
67  public: virtual ~Event();
68 
71  public: virtual void Disconnect(ConnectionPtr _c) = 0;
72 
75  public: virtual void Disconnect(int _id) = 0;
76 
79  public: bool GetSignaled() const;
80 
83  protected: Event(EventPrivate &_d);
84 
86  protected: EventPrivate *dataPtr;
87  };
88 
90  // Private data members for Connection class.
92  {
94  public: ConnectionPrivate();
95 
99  public: ConnectionPrivate(Event *_e, int _i);
100 
102  public: Event *event;
103 
105  public: int id;
106 
109  };
110 
113  {
115  public: Connection();
116 
120  public: Connection(Event *_e, int _i);
121 
123  public: ~Connection();
124 
127  public: int GetId() const;
128 
130  private: ConnectionPrivate *dataPtr;
131 
133  public: template<typename T> friend class EventT;
134  };
135 
137  template<typename T>
139  {
141  public: EventConnection(const bool _on,
142  boost::function<T> *_cb)
143  : callback(_cb)
144  {
145  // Windows Visual Studio 2012 does not have atomic_bool constructor,
146  // so we have to set "on" using operator=
147  this->on = _on;
148  }
149 
151  public: std::atomic_bool on;
152 
154  public: std::shared_ptr<boost::function<T> > callback;
155  };
156 
158  // Private data members for EventT<T> class.
159  template< typename T>
161  {
164  typedef std::map<int, std::shared_ptr<EventConnection<T> > >
165  EvtConnectionMap;
166 
168  public: EvtConnectionMap connections;
169 
171  public: std::mutex mutex;
172 
174  public: std::list<typename EvtConnectionMap::const_iterator>
176  };
177 
180  template< typename T>
181  class EventT : public Event
182  {
184  public: EventT();
185 
187  public: virtual ~EventT();
188 
193  public: ConnectionPtr Connect(const boost::function<T> &_subscriber);
194 
197  public: virtual void Disconnect(ConnectionPtr _c);
198 
201  public: virtual void Disconnect(int _id);
202 
205  public: unsigned int ConnectionCount() const;
206 
208  public: void operator()()
209  {this->Signal();}
210 
213  public: template< typename P >
214  void operator()(const P &_p)
215  {
216  this->Signal(_p);
217  }
218 
222  public: template< typename P1, typename P2 >
223  void operator()(const P1 &_p1, const P2 &_p2)
224  {
225  this->Signal(_p1, _p2);
226  }
227 
232  public: template< typename P1, typename P2, typename P3 >
233  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
234  {
235  this->Signal(_p1, _p2, _p3);
236  }
237 
243  public: template< typename P1, typename P2, typename P3, typename P4 >
244  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
245  const P4 &_p4)
246  {
247  this->Signal(_p1, _p2, _p3, _p4);
248  }
249 
256  public: template< typename P1, typename P2, typename P3, typename P4,
257  typename P5 >
258  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
259  const P4 &_p4, const P5 &_p5)
260  {
261  this->Signal(_p1, _p2, _p3, _p4, _p5);
262  }
263 
271  public: template< typename P1, typename P2, typename P3, typename P4,
272  typename P5, typename P6 >
273  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
274  const P4 &_p4, const P5 &_p5, const P6 &_p6)
275  {
276  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6);
277  }
278 
287  public: template< typename P1, typename P2, typename P3, typename P4,
288  typename P5, typename P6, typename P7 >
289  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
290  const P4 &_p4, const P5 &_p5, const P6 &_p6,
291  const P7 &_p7)
292  {
293  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
294  }
295 
305  public: template< typename P1, typename P2, typename P3, typename P4,
306  typename P5, typename P6, typename P7, typename P8 >
307  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
308  const P4 &_p4, const P5 &_p5, const P6 &_p6,
309  const P7 &_p7, const P8 &_p8)
310  {
311  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
312  }
313 
324  public: template< typename P1, typename P2, typename P3, typename P4,
325  typename P5, typename P6, typename P7, typename P8,
326  typename P9 >
327  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
328  const P4 &_p4, const P5 &_p5, const P6 &_p6,
329  const P7 &_p7, const P8 &_p8, const P9 &_p9)
330  {
331  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
332  }
333 
345  public: template< typename P1, typename P2, typename P3, typename P4,
346  typename P5, typename P6, typename P7, typename P8,
347  typename P9, typename P10 >
348  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
349  const P4 &_p4, const P5 &_p5, const P6 &_p6,
350  const P7 &_p7, const P8 &_p8, const P9 &_p9,
351  const P10 &_p10)
352  {
353  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
354  }
355 
357  public: void Signal()
358  {
359  this->Cleanup();
360 
361  this->myDataPtr->signaled = true;
362  for (auto iter: this->myDataPtr->connections)
363  {
364  if (iter.second->on)
365  (*iter.second->callback)();
366  }
367  }
368 
371  public: template< typename P >
372  void Signal(const P &_p)
373  {
374  this->Cleanup();
375 
376  this->myDataPtr->signaled = true;
377  for (auto iter: this->myDataPtr->connections)
378  {
379  if (iter.second->on)
380  (*iter.second->callback)(_p);
381  }
382  }
383 
387  public: template< typename P1, typename P2 >
388  void Signal(const P1 &_p1, const P2 &_p2)
389  {
390  this->Cleanup();
391 
392  this->myDataPtr->signaled = true;
393  for (auto iter: this->myDataPtr->connections)
394  {
395  if (iter.second->on)
396  (*iter.second->callback)(_p1, _p2);
397  }
398  }
399 
404  public: template< typename P1, typename P2, typename P3 >
405  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
406  {
407  this->Cleanup();
408 
409  this->myDataPtr->signaled = true;
410  for (auto iter: this->myDataPtr->connections)
411  {
412  if (iter.second->on)
413  (*iter.second->callback)(_p1, _p2, _p3);
414  }
415  }
416 
422  public: template<typename P1, typename P2, typename P3, typename P4>
423  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
424  const P4 &_p4)
425  {
426  this->Cleanup();
427 
428  this->myDataPtr->signaled = true;
429  for (auto iter: this->myDataPtr->connections)
430  {
431  if (iter.second->on)
432  (*iter.second->callback)(_p1, _p2, _p3, _p4);
433  }
434  }
435 
442  public: template<typename P1, typename P2, typename P3, typename P4,
443  typename P5>
444  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
445  const P4 &_p4, const P5 &_p5)
446  {
447  this->Cleanup();
448 
449  this->myDataPtr->signaled = true;
450  for (auto iter: this->myDataPtr->connections)
451  {
452  if (iter.second->on)
453  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5);
454  }
455  }
456 
464  public: template<typename P1, typename P2, typename P3, typename P4,
465  typename P5, typename P6>
466  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
467  const P4 &_p4, const P5 &_p5, const P6 &_p6)
468  {
469  this->Cleanup();
470 
471  this->myDataPtr->signaled = true;
472  for (auto iter: this->myDataPtr->connections)
473  {
474  if (iter.second->on)
475  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6);
476  }
477  }
478 
487  public: template<typename P1, typename P2, typename P3, typename P4,
488  typename P5, typename P6, typename P7>
489  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
490  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
491  {
492  this->Cleanup();
493 
494  this->myDataPtr->signaled = true;
495  for (auto iter: this->myDataPtr->connections.begin())
496  {
497  if (iter.second->on)
498  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
499  }
500  }
501 
511  public: template<typename P1, typename P2, typename P3, typename P4,
512  typename P5, typename P6, typename P7, typename P8>
513  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
514  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
515  const P8 &_p8)
516  {
517  this->Cleanup();
518 
519  this->myDataPtr->signaled = true;
520  for (auto iter: this->myDataPtr->connections)
521  {
522  if (iter.second->on)
523  {
524  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
525  }
526  }
527  }
528 
539  public: template< typename P1, typename P2, typename P3, typename P4,
540  typename P5, typename P6, typename P7, typename P8,
541  typename P9 >
542  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
543  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
544  const P8 &_p8, const P9 &_p9)
545  {
546  this->Cleanup();
547 
548  this->myDataPtr->signaled = true;
549  for (auto iter: this->myDataPtr->connections)
550  {
551  if (iter.second->on)
552  {
553  (*iter.second->callback)(
554  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
555  }
556  }
557  }
558 
570  public: template< typename P1, typename P2, typename P3, typename P4,
571  typename P5, typename P6, typename P7, typename P8,
572  typename P9, typename P10 >
573  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
574  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
575  const P8 &_p8, const P9 &_p9, const P10 &_p10)
576  {
577  this->Cleanup();
578 
579  this->myDataPtr->signaled = true;
580  for (auto iter: this->myDataPtr->connections)
581  {
582  if (iter.second->on)
583  {
584  (*iter.second->callback)(
585  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
586  }
587  }
588  }
589 
593  private: void Cleanup();
594 
596  private: EventTPrivate<T> *myDataPtr;
597  };
598 
600  template<typename T>
602  : Event(*(new EventTPrivate<T>()))
603  {
604  this->myDataPtr = static_cast<EventTPrivate<T>*>(this->dataPtr);
605  }
606 
608  template<typename T>
610  {
611  this->myDataPtr->connections.clear();
612  }
613 
616  template<typename T>
617  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
618  {
619  int index = 0;
620  if (!this->myDataPtr->connections.empty())
621  {
622  auto const &iter = this->myDataPtr->connections.rbegin();
623  index = iter->first + 1;
624  }
625  this->myDataPtr->connections[index].reset(new EventConnection<T>(true,
626  new boost::function<T>(_subscriber)));
627  return ConnectionPtr(new Connection(this, index));
628  }
629 
632  template<typename T>
634  {
635  if (!_c)
636  return;
637 
638  this->Disconnect(_c->GetId());
639  _c->dataPtr->event = NULL;
640  _c->dataPtr->id = -1;
641  }
642 
645  template<typename T>
646  unsigned int EventT<T>::ConnectionCount() const
647  {
648  return this->myDataPtr->connections.size();
649  }
650 
653  template<typename T>
654  void EventT<T>::Disconnect(int _id)
655  {
656  // Find the connection
657  auto const &it = this->myDataPtr->connections.find(_id);
658 
659  if (it != this->myDataPtr->connections.end())
660  {
661  it->second->on = false;
662  this->myDataPtr->connectionsToRemove.push_back(it);
663  }
664  }
665 
667  template<typename T>
668  void EventT<T>::Cleanup()
669  {
670  std::lock_guard<std::mutex> lock(this->myDataPtr->mutex);
671  // Remove all queue connections.
672  for (auto &conn : this->myDataPtr->connectionsToRemove)
673  this->myDataPtr->connections.erase(conn);
674  this->myDataPtr->connectionsToRemove.clear();
675  }
676 
678  }
679 }
680 #endif
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:542
boost::shared_ptr< Connection > ConnectionPtr
Definition: CommonTypes.hh:153
Base class for all events.
Definition: Event.hh:61
std::list< typename EvtConnectionMap::const_iterator > connectionsToRemove
List of connections to remove.
Definition: Event.hh:175
A class that encapsulates a connection.
Definition: Event.hh:112
EventPrivate * dataPtr
Data pointer.
Definition: Event.hh:86
Definition: Event.hh:50
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:489
std::shared_ptr< boost::function< T > > callback
Callback function.
Definition: Event.hh:154
virtual void Disconnect(ConnectionPtr _c)
Disconnect a callback to this event.
Definition: Event.hh:633
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameter.
Definition: Event.hh:423
Definition: Event.hh:138
void Signal()
Signal the event for all subscribers.
Definition: Event.hh:357
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:444
Definition: Event.hh:160
void operator()(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:214
int id
the id set in the constructor
Definition: Event.hh:105
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameters.
Definition: Event.hh:233
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:289
EventConnection(const bool _on, boost::function< T > *_cb)
Constructor.
Definition: Event.hh:141
Event * event
the event for this connection
Definition: Event.hh:102
std::mutex mutex
A thread lock.
Definition: Event.hh:171
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:258
void operator()(const P1 &_p1, const P2 &_p2)
Signal the event with two parameters.
Definition: Event.hh:223
virtual ~EventT()
Destructor.
Definition: Event.hh:609
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameter.
Definition: Event.hh:405
EvtConnectionMap connections
Array of connection callbacks.
Definition: Event.hh:168
void Signal(const P1 &_p1, const P2 &_p2)
Signal the event with two parameter.
Definition: Event.hh:388
#define GZ_COMMON_VISIBLE
Definition: system.hh:84
bool signaled
True if the event has been signaled.
Definition: Event.hh:56
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:307
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:513
void Signal(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:372
std::atomic_bool on
On/off value for the event callback.
Definition: Event.hh:151
ConnectionPtr Connect(const boost::function< T > &_subscriber)
Connect a callback to this event.
Definition: Event.hh:617
void operator()()
Access the signal.
Definition: Event.hh:208
common::Time creationTime
set during the constructor
Definition: Event.hh:108
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:327
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:573
#define NULL
Definition: CommonTypes.hh:31
Definition: Event.hh:91
A class for event processing.
Definition: Event.hh:181
unsigned int ConnectionCount() const
Get the number of connections.
Definition: Event.hh:646
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameters.
Definition: Event.hh:244
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:273
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:466
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:348
A Time class, can be used to hold wall- or sim-time.
Definition: Time.hh:44
EventT()
Constructor.
Definition: Event.hh:601