$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 
27 #include <cstdint> // for uint64_t
28 #include <map> // for map<>
29 #include <memory> // for shared_ptr<>
30 #include <string> // for string
31 #include <type_traits> // for enable_if_t<>, is_enum<>
32 
33 #include <cloe/component.hpp> // for Component
34 #include <cloe/core.hpp> // for Json
35 #include <cloe/model.hpp> // for Model
36 
37 namespace cloe {
38 
42 class UnknownComponent : public Error {
43  public:
44  UnknownComponent(const std::string& vehicle,
45  const std::string& key,
46  const std::vector<std::string>& available_components);
47 
48  const std::string& vehicle() const { return vehicle_; }
49  const std::string& unknown_component() const { return unknown_; }
50  const std::vector<std::string>& available_components() const;
51 
52  private:
53  std::string vehicle_;
54  std::string unknown_;
55  std::vector<std::string> available_;
56 };
57 
61 class BadComponentCast : public Error {
62  public:
63  BadComponentCast(const std::string& vehicle, const std::string& key);
64 
65  const std::string& vehicle() const { return vehicle_; }
66  const std::string& component_name() const { return component_; }
67 
68  private:
69  std::string vehicle_;
70  std::string component_;
71 };
72 
76 class CannotAddComponent : public Error {
77  public:
78  CannotAddComponent(const std::string& msg, const std::string& vehicle, const std::string& key);
79 
80  const std::string& vehicle() const { return vehicle_; }
81  const std::string& component_name() const { return component_; }
82 
83  private:
84  std::string vehicle_;
85  std::string component_;
86 };
87 
106 class Vehicle : public Model {
107  public:
108  Vehicle(uint64_t id, const std::string& name) : Model(name), id_(id) {}
109  virtual ~Vehicle() noexcept = default;
110 
117  std::shared_ptr<Vehicle> clone(uint64_t id, const std::string& name);
118 
119  uint64_t id() const { return id_; }
120 
124  size_t size() const { return this->components_.size(); }
125 
129  bool has(const std::string& key) const { return this->components_.count(key) != 0; }
130 
135  template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
136  bool has(Enum c) const {
137  return this->has(to_string(c));
138  }
139 
147  template <typename T>
148  std::shared_ptr<const T> get(const std::string& key) const {
149  auto ptr = std::dynamic_pointer_cast<const T>(at(key));
150  if (ptr == nullptr) {
151  throw BadComponentCast(name(), key);
152  }
153  return ptr;
154  }
155 
156  template <typename T>
157  std::shared_ptr<T> get(const std::string& key) {
158  return std::const_pointer_cast<T>(const_cast<const Vehicle&>(*this).get<T>(key));
159  }
160 
167  template <typename T, typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
168  std::shared_ptr<const T> get(Enum c) const {
169  return get<T>(to_string(c));
170  }
171 
172  template <typename T, typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
173  std::shared_ptr<T> get(Enum c) {
174  return get<T>(to_string(c));
175  }
176 
177  public: // Component Management
178  template <typename... Arguments>
179  void new_component(Component* ptr, const Arguments&... aliases) {
180  auto sp = std::shared_ptr<Component>(ptr);
181  this->add_component(sp, aliases...);
182  }
183 
184  template <typename First, typename... Arguments>
185  void add_component(std::shared_ptr<Component> sp, const First& alias,
186  const Arguments&... aliases) {
187  this->add_component(sp, alias);
188  this->add_component(sp, aliases...);
189  }
190 
191  template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
192  void add_component(std::shared_ptr<Component> sp, Enum c) {
193  this->add_component(sp, to_string(c));
194  }
195 
196  void add_component(std::shared_ptr<Component> sp, const std::string& alias) {
197  if (this->has(alias)) {
198  throw CannotAddComponent("component already exists", name(), alias);
199  }
200  this->set_component(alias, sp);
201  }
202 
203  template <typename First, typename... Arguments>
204  void emplace_component(std::shared_ptr<Component> sp, const First& alias,
205  const Arguments&... aliases) {
206  this->emplace_component(sp, alias);
207  this->emplace_component(sp, aliases...);
208  }
209 
210  template <typename Enum, std::enable_if_t<std::is_enum<Enum>::value, int> = 0>
211  void emplace_component(std::shared_ptr<Component> sp, Enum c) {
212  this->emplace_component(sp, to_string(c));
213  }
214 
215  void emplace_component(std::shared_ptr<Component> sp, const std::string& alias) {
216  this->set_component(alias, sp);
217  }
218 
219  void set_component(const std::string& key, std::shared_ptr<Component> component) {
220  this->components_[key] = component;
221  }
222 
223  std::vector<std::string> component_names() const {
224  std::vector<std::string> results;
225  results.reserve(components_.size());
226  for (const auto& kv : components_) {
227  results.emplace_back(kv.first);
228  }
229  return results;
230  }
231 
232  public: // Overrides
245  Duration process(const Sync& sync) override;
246  void connect() override;
247  void disconnect() override;
248 
249  void enroll(Registrar& r) override;
250  void reset() override;
251  void abort() override;
252 
253  friend void to_json(Json& j, const Vehicle& v) {
254  j = Json{
255  {"id", v.id()},
256  {"name", v.name()},
257  {"components", v.components_},
258  };
259  }
260 
261  protected: // Useful methods
266  std::shared_ptr<const Component> at(const std::string& key) const;
267  std::shared_ptr<Component> at(const std::string& key);
268 
269  private:
270  uint64_t id_;
271 
289  std::map<std::string, std::shared_ptr<Component>> components_;
290 };
291 
292 } // namespace cloe
Definition: vehicle.hpp:61
Definition: vehicle.hpp:76
const std::string & name() const
Definition: entity.hpp:67
Definition: error.hpp:35
Definition: model.hpp:203
Definition: vehicle.hpp:42
Definition: vehicle.hpp:106
void abort() override
Definition: vehicle.cpp:92
void disconnect() override
Definition: vehicle.cpp:59
void enroll(Registrar &r) override
Definition: vehicle.cpp:44
size_t size() const
Definition: vehicle.hpp:124
std::shared_ptr< const T > get(Enum c) const
Definition: vehicle.hpp:168
void connect() override
Definition: vehicle.cpp:48
bool has(Enum c) const
Definition: vehicle.hpp:136
Duration process(const Sync &sync) override
Definition: vehicle.cpp:70
bool has(const std::string &key) const
Definition: vehicle.hpp:129
void reset() override
Definition: vehicle.cpp:86
std::shared_ptr< const Component > at(const std::string &key) const
Definition: vehicle.cpp:98
std::shared_ptr< const T > get(const std::string &key) const
Definition: vehicle.hpp:148
std::shared_ptr< Vehicle > clone(uint64_t id, const std::string &name)
Definition: vehicle.cpp:38
std::chrono::nanoseconds Duration
Definition: cloe_fwd.hpp:36
nlohmann::json Json
Definition: fable_fwd.hpp:35