Gazebo Sim

API Reference

7.7.0
gz/sim/components/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  // TODO(azeey) Change to const char* in Harmonic to prevent static
391  // initialization order fiasco.
392  public: inline static std::string typeName;
393  };
394 
403  template <typename Identifier, typename Serializer>
404  class Component<NoData, Identifier, Serializer> : public BaseComponent
405  {
410  public: bool operator==(const Component<NoData, Identifier,
411  Serializer> &_component) const;
412 
417  public: bool operator!=(const Component<NoData, Identifier,
418  Serializer> &_component) const;
419 
420  // Documentation inherited
421  public: std::unique_ptr<BaseComponent> Clone() const override;
422 
423  // Documentation inherited
424  public: ComponentTypeId TypeId() const override;
425 
426  // Documentation inherited
427  public: void Serialize(std::ostream &_out) const override;
428 
429  // Documentation inherited
430  public: void Deserialize(std::istream &_in) override;
431 
434  public: inline static ComponentTypeId typeId{0};
435 
438  // TODO(azeey) Change to const char* in Harmonic to prevent static
439  // initialization order fiasco.
440  public: inline static std::string typeName;
441  };
442 
444  template <typename DataType, typename Identifier, typename Serializer>
446  : data(std::move(_data))
447  {
448  }
449 
451  template <typename DataType, typename Identifier, typename Serializer>
453  {
454  return this->data;
455  }
456 
458  template <typename DataType, typename Identifier, typename Serializer>
460  const DataType &_data,
461  const std::function<bool(const DataType &, const DataType &)> &_eql)
462  {
463  bool result = !_eql(_data, this->data);
464  this->data = _data;
465  return result;
466  }
467 
469  template <typename DataType, typename Identifier, typename Serializer>
471  {
472  return this->data;
473  }
474 
476  template <typename DataType, typename Identifier, typename Serializer>
478  const Component<DataType, Identifier, Serializer> &_component) const
479  {
480  return this->data == _component.Data();
481  }
482 
484  template <typename DataType, typename Identifier, typename Serializer>
486  const Component<DataType, Identifier, Serializer> &_component) const
487  {
488  return this->data != _component.Data();
489  }
490 
492  template <typename DataType, typename Identifier, typename Serializer>
494  std::ostream &_out) const
495  {
496  Serializer::Serialize(_out, this->Data());
497  }
498 
500  template <typename DataType, typename Identifier, typename Serializer>
502  std::istream &_in)
503  {
504  Serializer::Deserialize(_in, this->Data());
505  }
506 
508  template <typename DataType, typename Identifier, typename Serializer>
511  {
512  Component<DataType, Identifier, Serializer> clonedComp(this->Data());
513  return std::make_unique<Component<DataType, Identifier, Serializer>>(
514  clonedComp);
515  }
516 
518  template <typename DataType, typename Identifier, typename Serializer>
520  {
521  return typeId;
522  }
523 
525  template <typename Identifier, typename Serializer>
528  {
529  return true;
530  }
531 
533  template <typename Identifier, typename Serializer>
536  {
537  return false;
538  }
539 
541  template <typename Identifier, typename Serializer>
544  {
545  return std::make_unique<Component<NoData, Identifier, Serializer>>();
546  }
547 
549  template <typename Identifier, typename Serializer>
551  {
552  return typeId;
553  }
554 
556  template <typename Identifier, typename Serializer>
558  std::ostream &_out) const
559  {
560  Serializer::Serialize(_out);
561  }
562 
564  template <typename Identifier, typename Serializer>
566  std::istream &_in)
567  {
568  Serializer::Deserialize(_in);
569  }
570 }
571 }
572 }
573 }
574 #endif