Gazebo Sim

API Reference

8.7.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 GZ_SIM_COMPONENTS_COMPONENT_HH_
18 #define GZ_SIM_COMPONENTS_COMPONENT_HH_
19 
20 #include <cstdint>
21 #include <memory>
22 #include <string>
23 #include <sstream>
24 #include <utility>
25 
26 #include <gz/common/Console.hh>
27 
28 #include <gz/sim/config.hh>
29 #include <gz/sim/Export.hh>
30 #include <gz/sim/Types.hh>
31 
32 namespace gz
33 {
34 namespace sim
35 {
36 // namespace gz
37 // Inline bracket to help doxygen filtering.
38 inline namespace GZ_SIM_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  gzwarn << "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  gzwarn << "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  gzwarn << "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  gzwarn << "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  gzwarn << "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  gzwarn << "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 
285  public: virtual std::unique_ptr<BaseComponent> Clone() const = 0;
286  };
287 
322  template <typename DataType, typename Identifier,
323  typename Serializer = serializers::DefaultSerializer<DataType>>
324  class Component : public BaseComponent
325  {
327  public: using Type = DataType;
328 
330  public: Component() = default;
331 
334  public: explicit Component(DataType _data);
335 
337  public: ~Component() override = default;
338 
342  public: bool operator==(const Component &_component) const;
343 
347  public: bool operator!=(const Component &_component) const;
348 
349  // Documentation inherited
350  public: std::unique_ptr<BaseComponent> Clone() const override;
351 
352  // Documentation inherited
353  public: ComponentTypeId TypeId() const override;
354 
355  // Documentation inherited
356  public: void Serialize(std::ostream &_out) const override;
357 
358  // Documentation inherited
359  public: void Deserialize(std::istream &_in) override;
360 
366  public: DataType &Data();
367 
373  public: bool SetData(const DataType &_data,
374  const std::function<
375  bool(const DataType &, const DataType &)> &_eql);
376 
379  public: const DataType &Data() const;
380 
382  private: DataType data;
383 
386  public: inline static ComponentTypeId typeId{0};
387 
390  public: inline static const char *typeName{nullptr};
391  };
392 
401  template <typename Identifier, typename Serializer>
402  class Component<NoData, Identifier, Serializer> : public BaseComponent
403  {
408  public: bool operator==(const Component<NoData, Identifier,
409  Serializer> &_component) const;
410 
415  public: bool operator!=(const Component<NoData, Identifier,
416  Serializer> &_component) const;
417 
418  // Documentation inherited
419  public: std::unique_ptr<BaseComponent> Clone() const override;
420 
421  // Documentation inherited
422  public: ComponentTypeId TypeId() const override;
423 
424  // Documentation inherited
425  public: void Serialize(std::ostream &_out) const override;
426 
427  // Documentation inherited
428  public: void Deserialize(std::istream &_in) override;
429 
432  public: inline static ComponentTypeId typeId{0};
433 
436  public: inline static const char *typeName{nullptr};
437  };
438 
440  template <typename DataType, typename Identifier, typename Serializer>
442  : data(std::move(_data))
443  {
444  }
445 
447  template <typename DataType, typename Identifier, typename Serializer>
449  {
450  return this->data;
451  }
452 
454  template <typename DataType, typename Identifier, typename Serializer>
456  const DataType &_data,
457  const std::function<bool(const DataType &, const DataType &)> &_eql)
458  {
459  bool result = !_eql(_data, this->data);
460  this->data = _data;
461  return result;
462  }
463 
465  template <typename DataType, typename Identifier, typename Serializer>
467  {
468  return this->data;
469  }
470 
472  template <typename DataType, typename Identifier, typename Serializer>
474  const Component<DataType, Identifier, Serializer> &_component) const
475  {
476  return this->data == _component.Data();
477  }
478 
480  template <typename DataType, typename Identifier, typename Serializer>
482  const Component<DataType, Identifier, Serializer> &_component) const
483  {
484  return this->data != _component.Data();
485  }
486 
488  template <typename DataType, typename Identifier, typename Serializer>
490  std::ostream &_out) const
491  {
492  Serializer::Serialize(_out, this->Data());
493  }
494 
496  template <typename DataType, typename Identifier, typename Serializer>
498  std::istream &_in)
499  {
500  Serializer::Deserialize(_in, this->Data());
501  }
502 
504  template <typename DataType, typename Identifier, typename Serializer>
507  {
508  Component<DataType, Identifier, Serializer> clonedComp(this->Data());
509  return std::make_unique<Component<DataType, Identifier, Serializer>>(
510  clonedComp);
511  }
512 
514  template <typename DataType, typename Identifier, typename Serializer>
516  {
517  return typeId;
518  }
519 
521  template <typename Identifier, typename Serializer>
524  {
525  return true;
526  }
527 
529  template <typename Identifier, typename Serializer>
532  {
533  return false;
534  }
535 
537  template <typename Identifier, typename Serializer>
540  {
541  return std::make_unique<Component<NoData, Identifier, Serializer>>();
542  }
543 
545  template <typename Identifier, typename Serializer>
547  {
548  return typeId;
549  }
550 
552  template <typename Identifier, typename Serializer>
554  std::ostream &_out) const
555  {
556  Serializer::Serialize(_out);
557  }
558 
560  template <typename Identifier, typename Serializer>
562  std::istream &_in)
563  {
564  Serializer::Deserialize(_in);
565  }
566 }
567 }
568 }
569 }
570 #endif