16#include <unordered_map>
50 std::unordered_map<std::string, double>
scalars;
51 std::unordered_map<std::string, std::vector<double>>
vectors;
52 std::unordered_map<std::string, std::vector<double>>
arrays;
53 std::unordered_map<std::string, std::string>
strings;
54 std::unordered_map<std::string, int64_t>
integers;
55 std::unordered_map<std::string, bool>
booleans;
75 template <
typename T> T
Require(
const std::string &key)
const;
84 template <
typename T> T
Get(
const std::string &key,
const T &default_value)
const;
92 template <
typename T> [[nodiscard]]
bool Has(
const std::string &key)
const;
107 return (it !=
scalars.end()) ? it->second : def;
132 int64_t val = it->second;
133 if (val <
static_cast<int64_t
>(std::numeric_limits<int>::min()) ||
134 val >
static_cast<int64_t
>(std::numeric_limits<int>::max())) {
136 std::to_string(val) +
" overflows int range [" +
137 std::to_string(std::numeric_limits<int>::min()) +
", " +
138 std::to_string(std::numeric_limits<int>::max()) +
"]");
140 return static_cast<int>(val);
149 int64_t val = it->second;
150 if (val <
static_cast<int64_t
>(std::numeric_limits<int>::min()) ||
151 val >
static_cast<int64_t
>(std::numeric_limits<int>::max())) {
153 std::to_string(val) +
" overflows int range [" +
154 std::to_string(std::numeric_limits<int>::min()) +
", " +
155 std::to_string(std::numeric_limits<int>::max()) +
"]");
157 return static_cast<int>(val);
167 return (it !=
integers.end()) ? it->second : def;
188 return (it !=
booleans.end()) ? it->second : def;
193 const std::string &key)
const {
211 const std::string &def)
const {
212 auto it = strings.find(key);
213 return (it != strings.end()) ? it->second : def;
217 auto it = strings.find(key);
218 if (it == strings.end()) {
219 throw ConfigError(
"Component '" + FullPath() +
"' missing required string: " + key);
234 const Vec3<double> &def)
const {
235 auto it = vectors.find(key);
236 if (it == vectors.end() || it->second.size() != 3) {
239 return Vec3<double>{it->second[0], it->second[1], it->second[2]};
244 auto it = vectors.find(key);
245 if (it == vectors.end()) {
246 throw ConfigError(
"Component '" + FullPath() +
"' missing required vector: " + key);
248 if (it->second.size() != 3) {
249 throw ConfigError(
"Component '" + FullPath() +
"' vector '" + key +
250 "' must have exactly 3 elements, got " +
251 std::to_string(it->second.size()));
253 return Vec3<double>{it->second[0], it->second[1], it->second[2]};
258 return it !=
vectors.end() && it->second.size() == 3;
267 const Vec4<double> &def)
const {
268 auto it = vectors.find(key);
269 if (it == vectors.end() || it->second.size() != 4) {
272 return Vec4<double>{it->second[0], it->second[1], it->second[2], it->second[3]};
277 auto it = vectors.find(key);
278 if (it == vectors.end()) {
280 "' missing required quaternion/vec4: " + key);
282 if (it->second.size() != 4) {
283 throw ConfigError(
"Component '" + FullPath() +
"' quaternion/vec4 '" + key +
284 "' must have exactly 4 elements, got " +
285 std::to_string(it->second.size()));
287 return Vec4<double>{it->second[0], it->second[1], it->second[2], it->second[3]};
292 return it !=
vectors.end() && it->second.size() == 4;
300inline std::vector<double>
302 const std::vector<double> &def)
const {
303 auto it = arrays.find(key);
304 if (it != arrays.end()) {
308 auto vit = vectors.find(key);
309 return (vit != vectors.end()) ? vit->second : def;
313inline std::vector<double>
315 auto it = arrays.find(key);
316 if (it != arrays.end()) {
319 auto vit = vectors.find(key);
320 if (vit != vectors.end()) {
323 throw ConfigError(
"Component '" + FullPath() +
"' missing required array: " + key);
327 return arrays.count(key) > 0 || vectors.count(key) > 0;
335inline std::vector<std::string>
337 const std::vector<std::string> &def)
const {
339 if (key ==
"sources") {
340 return sources.empty() ? def : sources;
342 if (key ==
"body_sources") {
343 return body_sources.empty() ? def : body_sources;
345 if (key ==
"ecef_sources") {
346 return ecef_sources.empty() ? def : ecef_sources;
352inline std::vector<std::string>
354 if (key ==
"sources") {
355 if (sources.empty()) {
356 throw ConfigError(
"Component '" + FullPath() +
"' missing required sources list");
360 if (key ==
"body_sources") {
361 if (body_sources.empty()) {
362 throw ConfigError(
"Component '" + FullPath() +
"' missing required body_sources list");
366 if (key ==
"ecef_sources") {
367 if (ecef_sources.empty()) {
368 throw ConfigError(
"Component '" + FullPath() +
"' missing required ecef_sources list");
372 throw ConfigError(
"Component '" + FullPath() +
"' missing required string list: " + key);
377 if (key ==
"sources") {
378 return !sources.empty();
380 if (key ==
"body_sources") {
381 return !body_sources.empty();
383 if (key ==
"ecef_sources") {
384 return !ecef_sources.empty();
Core type definitions, concepts, and configuration for Icarus.
Consolidated error handling for Icarus.
Configuration/parsing errors with optional file context.
Definition Error.hpp:185
Definition AggregationTypes.hpp:13
std::string MakeFullPath(const std::string &entity, const std::string &name)
Build a full path from entity and name.
Definition CoreTypes.hpp:166
Configuration container for components.
Definition ComponentConfig.hpp:37
std::string entity
Entity namespace (optional).
Definition ComponentConfig.hpp:43
T Get(const std::string &key, const T &default_value) const
Get an optional config value with default.
std::string type
Component type name.
Definition ComponentConfig.hpp:44
std::string FullPath() const
Get the full component path: entity.name (or just name if no entity).
Definition ComponentConfig.hpp:97
std::unordered_map< std::string, int64_t > integers
Definition ComponentConfig.hpp:54
std::unordered_map< std::string, bool > booleans
Definition ComponentConfig.hpp:55
bool Has(const std::string &key) const
Check if a key exists.
std::unordered_map< std::string, std::string > strings
Definition ComponentConfig.hpp:53
T Require(const std::string &key) const
Get a required config value (throws if missing).
std::string name
Component instance name.
Definition ComponentConfig.hpp:42
std::unordered_map< std::string, std::vector< double > > vectors
Vec3 stored as [x,y,z].
Definition ComponentConfig.hpp:51
std::vector< std::string > body_sources
Frame-categorized source lists (for ForceAggregator frame transformations).
Definition ComponentConfig.hpp:61
std::unordered_map< std::string, double > scalars
Definition ComponentConfig.hpp:50
std::vector< std::string > sources
List-based config (for aggregators with variable source counts, etc.).
Definition ComponentConfig.hpp:58
std::unordered_map< std::string, std::vector< double > > arrays
Definition ComponentConfig.hpp:52
std::vector< std::string > ecef_sources
Sources outputting in ECEF frame.
Definition ComponentConfig.hpp:62