$darkmode
vehicle.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
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  * SPDX-License-Identifier: Apache-2.0
17  */
25 #pragma once
26 #ifndef CLOE_VEHICLE_HPP_
27 #define CLOE_VEHICLE_HPP_
28 
29 #include <cstdint> // for uint64_t
30 #include <map> // for map<>
31 #include <memory> // for shared_ptr<>
32 #include <string> // for string
33 #include <type_traits> // for enable_if_t<>, is_enum<>
34 
35 #include <cloe/component.hpp> // for Component
36 #include <cloe/core.hpp> // for Json
37 #include <cloe/model.hpp> // for Model
38 
39 namespace cloe {
40 
44 class UnknownComponent : public Error {
45  public:
46  UnknownComponent(const std::string& vehicle,
47  const std::string& key,
48  const std::vector<std::string>& available_components);
49 
50  const std::string& vehicle() const { return vehicle_; }
51  const std::string& unknown_component() const { return unknown_; }
52  const std::vector<std::string>& available_components() const;
53 
54  private:
55  std::string vehicle_;
56  std::string unknown_;
57  std::vector<std::string> available_;
58 };
59 
63 class BadComponentCast : public Error {
64  public:
65  BadComponentCast(const std::string& vehicle, const std::string& key);
66 
67  const std::string& vehicle() const { return vehicle_; }
68  const std::string& component_name() const { return component_; }
69 
70  private:
71  std::string vehicle_;
72  std::string component_;
73 };
74 
78 class CannotAddComponent : public Error {
79  public:
80  CannotAddComponent(const std::string& msg, const std::string& vehicle, const std::string& key);
81 
82  const std::string& vehicle() const { return vehicle_; }
83  const std::string& component_name() const { return component_; }
84 
85  private:
86  std::string vehicle_;
87  std::string component_;
88 };
89 
108 class Vehicle : public Model {
109  public:
110  Vehicle(uint64_t id, const std::string& name) : Model(name), id_(id) {}
111  virtual ~Vehicle() noexcept = default;
112 
119  std::shared_ptr<Vehicle> clone(uint64_t id, const std::string& name);
120 
121  uint64_t id() const { return id_; }
122 
126  size_t size() const { return this->components_.size(); }
127 
131  bool has(const std::string& key) const { return this->components_.count(key) != 0; }
132 
137  template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
138  bool has(Enum c) const {
139  return this->has(to_string(c));
140  }
141 
149  template <typename T>
150  std::shared_ptr<const T> get(const std::string& key) const {
151  auto ptr = std::dynamic_pointer_cast<const T>(at(key));
152  if (ptr == nullptr) {
153  throw BadComponentCast(name(), key);
154  }
155  return ptr;
156  }
157 
158  template <typename T>
159  std::shared_ptr<T> get(const std::string& key) {
160  return std::const_pointer_cast<T>(const_cast<const Vehicle&>(*this).get<T>(key));
161  }
162 
169  template <typename T, typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
170  std::shared_ptr<const T> get(Enum c) const {
171  return get<T>(to_string(c));
172  }
173 
174  template <typename T, typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
175  std::shared_ptr<T> get(Enum c) {
176  return get<T>(to_string(c));
177  }
178 
179  public: // Component Management
180  template <typename... Arguments>
181  void new_component(Component* ptr, const Arguments&... aliases) {
182  auto sp = std::shared_ptr<Component>(ptr);
183  this->add_component(sp, aliases...);
184  }
185 
186  template <typename First, typename... Arguments>
187  void add_component(std::shared_ptr<Component> sp, const First& alias,
188  const Arguments&... aliases) {
189  this->add_component(sp, alias);
190  this->add_component(sp, aliases...);
191  }
192 
193  template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
194  void add_component(std::shared_ptr<Component> sp, Enum c) {
195  this->add_component(sp, to_string(c));
196  }
197 
198  void add_component(std::shared_ptr<Component> sp, const std::string& alias) {
199  if (this->has(alias)) {
200  throw CannotAddComponent("component already exists", name(), alias);
201  }
202  this->set_component(alias, sp);
203  }
204 
205  template <typename First, typename... Arguments>
206  void emplace_component(std::shared_ptr<Component> sp, const First& alias,
207  const Arguments&... aliases) {
208  this->emplace_component(sp, alias);
209  this->emplace_component(sp, aliases...);
210  }
211 
212  template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
213  void emplace_component(std::shared_ptr<Component> sp, Enum c) {
214  this->emplace_component(sp, to_string(c));
215  }
216 
217  void emplace_component(std::shared_ptr<Component> sp, const std::string& alias) {
218  this->set_component(alias, sp);
219  }
220 
221  void set_component(const std::string& key, std::shared_ptr<Component> component) {
222  this->components_[key] = component;
223  }
224 
225  public: // Overrides
238  Duration process(const Sync& sync) override;
239  void connect() override;
240  void disconnect() override;
241 
242  void enroll(Registrar& r) override;
243  void reset() override;
244  void abort() override;
245 
246  friend void to_json(Json& j, const Vehicle& v) {
247  j = Json{
248  {"id", v.id()},
249  {"name", v.name()},
250  {"components", v.components_},
251  };
252  }
253 
254  protected: // Useful methods
259  std::shared_ptr<const Component> at(const std::string& key) const;
260  std::shared_ptr<Component> at(const std::string& key);
261 
262  private:
263  uint64_t id_;
264 
282  std::map<std::string, std::shared_ptr<Component>> components_;
283 };
284 
285 } // namespace cloe
286 
287 #endif // CLOE_VEHICLE_HPP_
Definition: registrar.hpp:117
bool has(const std::string &key) const
Definition: vehicle.hpp:131
Definition: error.hpp:35
Definition: sync.hpp:35
Definition: coordinator.hpp:36
std::chrono::nanoseconds Duration
Definition: duration.hpp:45
size_t size() const
Definition: vehicle.hpp:126
Definition: vehicle.hpp:78
Definition: vehicle.hpp:44
std::string name() const
Definition: entity.hpp:68
Definition: component.hpp:144
Definition: vehicle.hpp:108
Definition: model.hpp:214
bool has(Enum c) const
Definition: vehicle.hpp:138
std::shared_ptr< const T > get(const std::string &key) const
Definition: vehicle.hpp:150
Definition: vehicle.hpp:63