Ignition Gazebo

API Reference

5.1.0
Component.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 IGNITION_GAZEBO_COMPONENTS_COMPONENT_HH_
18 #define IGNITION_GAZEBO_COMPONENTS_COMPONENT_HH_
19 
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 #include <sstream>
24 #include <utility>
25 
27 
28 #include <ignition/gazebo/config.hh>
29 #include <ignition/gazebo/Export.hh>
30 #include <ignition/gazebo/Types.hh>
31 
32 namespace ignition
33 {
34 namespace gazebo
35 {
36 // namespace ignition
37 // Inline bracket to help doxygen filtering.
38 inline namespace IGNITION_GAZEBO_VERSION_NAMESPACE {
39 namespace traits
40 {
42  template <typename T>
44  {
45  };
46 
48  template <typename T>
49  struct IsSharedPtr<std::shared_ptr<T>> : std::true_type
50  {
51  };
52 
61  template <typename Stream, typename DataType>
63  {
64  private: template <typename StreamArg, typename DataTypeArg>
65  static auto Test(int _test)
66  -> decltype(std::declval<StreamArg &>()
67  << std::declval<const DataTypeArg &>(), std::true_type());
68 
69  private: template <typename, typename>
70  static auto Test(...) -> std::false_type;
71 
72  public: static constexpr bool value = // NOLINT
73  decltype(Test<Stream, DataType>(true))::value;
74  };
75 
85  template <typename Stream, typename DataType>
87  {
88  private: template <typename StreamArg, typename DataTypeArg>
89  static auto Test(int _test)
90  -> decltype(std::declval<StreamArg &>() >> std::declval<DataTypeArg &>(),
91  std::true_type());
92 
93  private: template <typename, typename>
94  static auto Test(...) -> std::false_type;
95 
96  public: static constexpr bool value = // NOLINT
97  decltype(Test<Stream, DataType>(0))::value;
98  };
99 }
100 
101 namespace serializers
102 {
107  template <typename DataType>
109  {
111  public: static std::ostream &Serialize(std::ostream &_out,
112  const DataType &_data)
113  {
114  // cppcheck-suppress syntaxError
115  if constexpr (traits::IsSharedPtr<DataType>::value) // NOLINT
116  {
118  typename DataType::element_type>::value)
119  {
120  _out << *_data;
121  }
122  else
123  {
124  static bool warned{false};
125  if (!warned)
126  {
127  ignwarn << "Trying to serialize component with data type ["
128  << typeid(DataType).name() << "], which doesn't have "
129  << "`operator<<`. Component will not be serialized."
130  << std::endl;
131  warned = true;
132  }
133  }
134  }
136  {
137  _out << _data;
138  }
139  else
140  {
141  static bool warned{false};
142  if (!warned)
143  {
144  ignwarn << "Trying to serialize component with data type ["
145  << typeid(DataType).name() << "], which doesn't have "
146  << "`operator<<`. Component will not be serialized."
147  << std::endl;
148  warned = true;
149  }
150  }
151  return _out;
152  }
153 
157  public: static std::istream &Deserialize(std::istream &_in,
158  DataType &_data)
159  {
161  {
162  if constexpr (traits::IsInStreamable<std::istream,
163  typename DataType::element_type>::value)
164  {
165  _in >> *_data;
166  }
167  else
168  {
169  static bool warned{false};
170  if (!warned)
171  {
172  ignwarn << "Trying to deserialize component with data type ["
173  << typeid(DataType).name() << "], which doesn't have "
174  << "`operator>>`. Component will not be deserialized."
175  << std::endl;
176  warned = true;
177  }
178  }
179  }
181  {
182  _in >> _data;
183  }
184  else
185  {
186  static bool warned{false};
187  if (!warned)
188  {
189  ignwarn << "Trying to deserialize component with data type ["
190  << typeid(DataType).name() << "], which doesn't have "
191  << "`operator>>`. Component will not be deserialized."
192  << std::endl;
193  warned = true;
194  }
195  }
196  return _in;
197  }
198  };
199 }
200 
201 namespace components
202 {
207 }
208 
209 namespace serializers
210 {
212  template<> class DefaultSerializer<components::NoData>
213  {
214  public: static std::ostream &Serialize(std::ostream &_out)
215  {
216  _out << "-";
217  return _out;
218  }
219 
220  public: static std::istream &Deserialize(std::istream &_in)
221  {
222  return _in;
223  }
224  };
225 }
226 
227 namespace components
228 {
231  {
233  public: BaseComponent() = default;
234 
236  public: virtual ~BaseComponent() = default;
237 
243  public: virtual void Serialize(std::ostream &_out) const
244  {
245  // This will avoid a doxygen warning
246  (void)_out;
247  static bool warned{false};
248  if (!warned)
249  {
250  ignwarn << "Trying to serialize component of type [" << this->TypeId()
251  << "], which hasn't implemented the `Serialize` function. "
252  << "Component will not be serialized." << std::endl;
253  warned = true;
254  }
255  };
256 
262  public: virtual void Deserialize(std::istream &_in)
263  {
264  // This will avoid a doxygen warning
265  (void)_in;
266  static bool warned{false};
267  if (!warned)
268  {
269  ignwarn << "Trying to deserialize component of type ["
270  << this->TypeId() << "], which hasn't implemented the "
271  << "`Deserialize` function. Component will not be deserialized."
272  << std::endl;
273  warned = true;
274  }
275  };
276 
281  public: virtual ComponentTypeId TypeId() const = 0;
282  };
283 
318  template <typename DataType, typename Identifier,
319  typename Serializer = serializers::DefaultSerializer<DataType>>
320  class Component : public BaseComponent
321  {
323  public: using Type = DataType;
324 
326  public: Component() = default;
327 
330  public: explicit Component(DataType _data);
331 
333  public: ~Component() override = default;
334 
338  public: bool operator==(const Component &_component) const;
339 
343  public: bool operator!=(const Component &_component) const;
344 
345  // Documentation inherited
346  public: ComponentTypeId TypeId() const override;
347 
348  // Documentation inherited
349  public: void Serialize(std::ostream &_out) const override;
350 
351  // Documentation inherited
352  public: void Deserialize(std::istream &_in) override;
353 
359  public: DataType &Data();
360 
366  public: bool SetData(const DataType &_data,
367  const std::function<
368  bool(const DataType &, const DataType &)> &_eql);
369 
372  public: const DataType &Data() const;
373 
375  private: DataType data;
376 
379  public: inline static ComponentTypeId typeId{0};
380 
383  public: inline static std::string typeName;
384  };
385 
394  template <typename Identifier, typename Serializer>
395  class Component<NoData, Identifier, Serializer> : public BaseComponent
396  {
401  public: bool operator==(const Component<NoData, Identifier,
402  Serializer> &_component) const;
403 
408  public: bool operator!=(const Component<NoData, Identifier,
409  Serializer> &_component) const;
410 
411  // Documentation inherited
412  public: ComponentTypeId TypeId() const override;
413 
414  // Documentation inherited
415  public: void Serialize(std::ostream &_out) const override;
416 
417  // Documentation inherited
418  public: void Deserialize(std::istream &_in) override;
419 
422  public: inline static ComponentTypeId typeId{0};
423 
426  public: inline static std::string typeName;
427  };
428 
430  template <typename DataType, typename Identifier, typename Serializer>
432  : data(std::move(_data))
433  {
434  }
435 
437  template <typename DataType, typename Identifier, typename Serializer>
439  {
440  return this->data;
441  }
442 
444  template <typename DataType, typename Identifier, typename Serializer>
446  const DataType &_data,
447  const std::function<bool(const DataType &, const DataType &)> &_eql)
448  {
449  bool result = !_eql(_data, this->data);
450  this->data = _data;
451  return result;
452  }
453 
455  template <typename DataType, typename Identifier, typename Serializer>
457  {
458  return this->data;
459  }
460 
462  template <typename DataType, typename Identifier, typename Serializer>
464  const Component<DataType, Identifier, Serializer> &_component) const
465  {
466  return this->data == _component.Data();
467  }
468 
470  template <typename DataType, typename Identifier, typename Serializer>
472  const Component<DataType, Identifier, Serializer> &_component) const
473  {
474  return this->data != _component.Data();
475  }
476 
478  template <typename DataType, typename Identifier, typename Serializer>
480  std::ostream &_out) const
481  {
482  Serializer::Serialize(_out, this->Data());
483  }
484 
486  template <typename DataType, typename Identifier, typename Serializer>
488  std::istream &_in)
489  {
490  Serializer::Deserialize(_in, this->Data());
491  }
492 
494  template <typename DataType, typename Identifier, typename Serializer>
496  {
497  return typeId;
498  }
499 
501  template <typename Identifier, typename Serializer>
504  {
505  return true;
506  }
507 
509  template <typename Identifier, typename Serializer>
512  {
513  return false;
514  }
515 
517  template <typename Identifier, typename Serializer>
519  {
520  return typeId;
521  }
522 
524  template <typename Identifier, typename Serializer>
526  std::ostream &_out) const
527  {
528  Serializer::Serialize(_out);
529  }
530 
532  template <typename Identifier, typename Serializer>
534  std::istream &_in)
535  {
536  Serializer::Deserialize(_in);
537  }
538 }
539 }
540 }
541 }
542 #endif
Type trait that determines if a operator<< is defined on Stream and DataType, i.e, it checks if the function Stream& operator<<(Stream&, const DataType&) exists. Example:
Definition: Component.hh:62
Default serializer template to call stream operators only on types that support them. If the stream operator is not available, a warning message is printed.
Definition: Component.hh:108
bool operator!=(const Component &_component) const
Inequality operator.
Definition: Component.hh:471
static ComponentTypeId typeId
Unique ID for this component type. This is set through the Factory registration.
Definition: Component.hh:379
bool operator==(const Component &_component) const
Equality operator.
Definition: Component.hh:463
std::add_lvalue_reference< void > NoData
Convenient type to be used by components that don&#39;t wrap any data. I.e. they act as tags and their pr...
Definition: Component.hh:206
void Serialize(std::ostream &_out) const override
Fills a stream with a serialized version of the component. By default, it will leave the stream empty...
Definition: Component.hh:479
ComponentTypeId TypeId() const override
Returns the unique ID for the component&#39;s type. The ID is derived from the name that is manually chos...
Definition: Component.hh:495
T endl(T... args)
STL class.
virtual void Serialize(std::ostream &_out) const
Fills a stream with a serialized version of the component. By default, it will leave the stream empty...
Definition: Component.hh:243
STL class.
Specialization for components that don&#39;t wrap any data. This class to be used to create simple compon...
Definition: Component.hh:395
static std::string typeName
Unique name for this component type. This is set through the Factory registration.
Definition: Component.hh:383
static std::ostream & Serialize(std::ostream &_out)
Definition: Component.hh:214
uint64_t ComponentTypeId
A unique identifier for a component type. A component type must be derived from components::BaseCompo...
Definition: Types.hh:86
DataType Type
Alias for DataType.
Definition: Component.hh:323
void Deserialize(std::istream &_in) override
Fills a component based on a stream with a serialized data. By default, it will do nothing...
Definition: Component.hh:487
static std::ostream & Serialize(std::ostream &_out, const DataType &_data)
Serialization.
Definition: Component.hh:111
static std::istream & Deserialize(std::istream &_in, DataType &_data)
Deserialization.
Definition: Component.hh:157
Helper trait to determine if a type is shared_ptr or not.
Definition: Component.hh:43
A component type that wraps any data type. The intention is for this class to be used to create simpl...
Definition: Component.hh:320
static std::istream & Deserialize(std::istream &_in)
Definition: Component.hh:220
This library is part of the Ignition Robotics project.
static std::string typeName
Unique name for this component type. This is set through the Factory registration.
Definition: Component.hh:426
STL class.
DataType & Data()
Get the mutable component data. This function will be deprecated in Gazebo 3, replaced by const DataT...
Definition: Component.hh:438
bool SetData(const DataType &_data, const std::function< bool(const DataType &, const DataType &)> &_eql)
Set the data of this component.
Definition: Component.hh:445
Base class for all components.
Definition: Component.hh:230
virtual void Deserialize(std::istream &_in)
Fills a component based on a stream with a serialized data. By default, it will do nothing...
Definition: Component.hh:262
Type trait that determines if a operator>> is defined on Stream and DataType, i.e, it checks if the function Stream& operator>>(Stream&, DataType&) exists. Example:
Definition: Component.hh:86
#define ignwarn