Gazebo Sim

API Reference

8.7.0
EventManager.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 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 GZ_SIM_EVENTMANAGER_HH_
18 #define GZ_SIM_EVENTMANAGER_HH_
19 
20 #include <functional>
21 #include <memory>
22 #include <typeinfo>
23 #include <unordered_map>
24 #include <utility>
25 
26 #include <gz/common/Console.hh>
27 #include <gz/common/Event.hh>
28 
29 #include <gz/sim/config.hh>
30 #include <gz/sim/Export.hh>
31 #include <gz/sim/Types.hh>
32 
33 namespace gz
34 {
35  namespace sim
36  {
37  // Inline bracket to help doxygen filtering.
38  inline namespace GZ_SIM_VERSION_NAMESPACE {
39  // Forward declarations.
40  class GZ_SIM_HIDDEN EventManagerPrivate;
41 
50 
55  {
57  public: EventManager() = default;
58 
59  public: EventManager(const EventManager &) = delete;
60  public: EventManager &operator=(const EventManager &) = delete;
61 
63  public: ~EventManager() = default;
64 
70  public: template <typename E>
72  Connect(const typename E::CallbackT &_subscriber)
73  {
74  if (this->events.find(typeid(E)) == this->events.end()) {
75  this->events[typeid(E)] = std::make_unique<E>();
76  }
77 
78  E *eventPtr = dynamic_cast<E *>(this->events[typeid(E)].get());
79  // All values in the map should be derived from Event,
80  // so this shouldn't be an issue, but it doesn't hurt to check.
81  if (eventPtr != nullptr)
82  {
83  return eventPtr->Connect(_subscriber);
84  }
85  else
86  {
87  gzerr << "Failed to connect event: "
88  << typeid(E).name() << std::endl;
89  return nullptr;
90  }
91  }
92 
96  public: template <typename E, typename ... Args>
97  void Emit(Args && ... _args)
98  {
99  if (this->events.find(typeid(E)) == this->events.end())
100  {
101  // If there are no events of type E in the map, create it.
102  // But it also means there is nothing to signal.
103  //
104  // This is also needed to suppress unused function warnings
105  // for Events that are purely emitted, with no connections.
106  this->events[typeid(E)] = std::make_unique<E>();
107  return;
108  }
109 
110  E *eventPtr = dynamic_cast<E *>(this->events[typeid(E)].get());
111  // All values in the map should be derived from Event,
112  // so this shouldn't be an issue, but it doesn't hurt to check.
113  if (eventPtr != nullptr)
114  {
115  eventPtr->Signal(std::forward<Args>(_args) ...);
116  }
117  else
118  {
119  gzerr << "Failed to signal event: "
120  << typeid(E).name() << std::endl;
121  }
122  }
123 
126  public: template <typename E>
127  unsigned int
129  {
130  if (this->events.find(typeid(E)) == this->events.end())
131  {
132  return 0u;
133  }
134 
135  E *eventPtr = dynamic_cast<E *>(this->events[typeid(E)].get());
136  // All values in the map should be derived from Event,
137  // so this shouldn't be an issue, but it doesn't hurt to check.
138  if (eventPtr != nullptr)
139  {
140  return eventPtr->ConnectionCount();
141  }
142  else
143  {
144  gzerr << "Failed to get connection count for event: "
145  << typeid(E).name() << std::endl;
146  return 0u;
147  }
148  }
149 
151  private: using TypeInfoRef = std::reference_wrapper<const std::type_info>;
152 
154  private: struct Hasher
155  {
156  std::size_t operator()(TypeInfoRef _code) const
157  {
158  return _code.get().hash_code();
159  }
160  };
161 
163  private: struct EqualTo
164  {
165  bool operator()(TypeInfoRef _lhs, TypeInfoRef _rhs) const
166  {
167  return _lhs.get() == _rhs.get();
168  }
169  };
170 
172  private: std::unordered_map<TypeInfoRef,
174  Hasher, EqualTo> events;
175  };
176  }
177  }
178 }
179 
180 #endif // GZ_SIM_EVENTMANAGER_HH_