33
33
cul::Engine::Engine(const cul::ProviderSelectionPolicy::Ptr& provider_selection_policy,
34
34
const cul::Settings::Ptr& settings)
35
: provider_selection_policy(provider_selection_policy),
35
: provider_selection_policy(provider_selection_policy),
38
if (!provider_selection_policy) throw std::runtime_error
40
"Cannot construct an engine given a null ProviderSelectionPolicy"
38
if (!provider_selection_policy)
39
throw std::runtime_error{
40
"Cannot construct an engine given a null ProviderSelectionPolicy"};
43
if (!settings) throw std::runtime_error
45
"Cannot construct an engine given a null Settings instance"
43
throw std::runtime_error{
44
"Cannot construct an engine given a null Settings instance"};
48
46
// Setup behavior in case of configuration changes.
49
47
configuration.satellite_based_positioning_state.changed().connect([this](const SatelliteBasedPositioningState& state)
51
49
for_each_provider([this, state](const Provider::Ptr& provider)
53
51
if (provider->requires(cul::Provider::Requirements::satellites))
92
90
configuration.engine_state =
93
settings->get_enum_for_key<Engine::Status>(
94
Configuration::Keys::engine_state,
95
Configuration::Defaults::engine_state);
91
settings->get_enum_for_key<Engine::Status>(
92
Configuration::Keys::engine_state,
93
Configuration::Defaults::engine_state);
97
95
configuration.satellite_based_positioning_state =
98
settings->get_enum_for_key<SatelliteBasedPositioningState>(
99
Configuration::Keys::satellite_based_positioning_state,
100
Configuration::Defaults::satellite_based_positioning_state);
96
settings->get_enum_for_key<SatelliteBasedPositioningState>(
97
Configuration::Keys::satellite_based_positioning_state,
98
Configuration::Defaults::satellite_based_positioning_state);
102
100
configuration.wifi_and_cell_id_reporting_state =
103
settings->get_enum_for_key<WifiAndCellIdReportingState>(
104
Configuration::Keys::wifi_and_cell_id_reporting_state,
105
Configuration::Defaults::wifi_and_cell_id_reporting_state);
101
settings->get_enum_for_key<WifiAndCellIdReportingState>(
102
Configuration::Keys::wifi_and_cell_id_reporting_state,
103
Configuration::Defaults::wifi_and_cell_id_reporting_state);
107
105
configuration.engine_state.changed().connect([this](const Engine::Status& status)
109
107
Engine::settings->set_enum_for_key<Engine::Status>(Configuration::Keys::engine_state, status);
112
110
configuration.satellite_based_positioning_state.changed().connect([this](SatelliteBasedPositioningState state)
114
112
Engine::settings->set_enum_for_key<SatelliteBasedPositioningState>(Configuration::Keys::satellite_based_positioning_state, state);
117
115
configuration.wifi_and_cell_id_reporting_state.changed().connect([this](WifiAndCellIdReportingState state)
119
117
Engine::settings->set_enum_for_key<WifiAndCellIdReportingState>(Configuration::Keys::wifi_and_cell_id_reporting_state, state);
123
121
cul::Engine::~Engine()
135
133
configuration.wifi_and_cell_id_reporting_state);
137
135
for_each_provider([](const Provider::Ptr& provider)
139
137
provider->state_controller()->stop_position_updates();
140
138
provider->state_controller()->stop_heading_updates();
141
139
provider->state_controller()->stop_velocity_updates();
145
143
cul::ProviderSelection cul::Engine::determine_provider_selection_for_criteria(const cul::Criteria& criteria)
167
165
// We wire up changes in the engine's configuration to the respective slots
168
166
// of the provider.
169
167
auto cp = updates.reference_location.changed().connect([provider](const cul::Update<cul::Position>& pos)
171
169
provider->on_reference_location_updated(pos);
174
172
auto cv = updates.reference_velocity.changed().connect([provider](const cul::Update<cul::Velocity>& velocity)
176
174
provider->on_reference_velocity_updated(velocity);
179
177
auto ch = updates.reference_heading.changed().connect([provider](const cul::Update<cul::Heading>& heading)
181
179
provider->on_reference_heading_updated(heading);
184
182
auto cr = configuration.wifi_and_cell_id_reporting_state.changed().connect([provider](cul::WifiAndCellIdReportingState state)
186
184
provider->on_wifi_and_cell_reporting_state_changed(state);
189
187
// And do the reverse: Satellite visibility updates are funneled via the engine's configuration.
190
188
auto cs = provider->updates().svs.connect([this](const cul::Update<std::set<cul::SpaceVehicle>>& src)
192
190
updates.visible_space_vehicles.update([src](std::map<cul::SpaceVehicle::Key, cul::SpaceVehicle>& dest)
194
192
for(auto& sv : src.value)
203
201
// We are a bit dumb and just take any position update as new reference.
204
202
// We should come up with a better heuristic here.
205
203
auto cpr = provider->updates().position.connect([this](const cul::Update<cul::Position>& src)
207
205
updates.reference_location = src;
210
208
std::lock_guard<std::mutex> lg(guard);
211
209
providers.emplace(provider, std::move(ProviderConnections{cp, ch, cv, cr, cs, cpr}));
254
252
std::ostream& cul::operator<<(std::ostream& out, cul::Engine::Status state)
256
static constexpr const char* the_unknown_state
258
"Engine::Status::unknown"
254
static constexpr const char* the_unknown_state{
255
"Engine::Status::unknown"};
261
static const std::unordered_map<location::Engine::Status, std::string> lut
257
static const std::unordered_map<location::Engine::Status, std::string> lut{
263
258
{cul::Engine::Status::off, "Engine::Status::off"},
264
259
{cul::Engine::Status::on, "Engine::Status::on"},
265
{cul::Engine::Status::active, "Engine::Status::active"}
260
{cul::Engine::Status::active, "Engine::Status::active"}};
268
262
auto it = lut.find(state);
269
263
if (it != lut.end())
277
271
/** @brief Parses the status from the given stream. */
278
272
std::istream& cul::operator>>(std::istream& in, cul::Engine::Status& state)
280
static const std::unordered_map<std::string, cul::Engine::Status> lut
274
static const std::unordered_map<std::string, cul::Engine::Status> lut{
282
275
{"Engine::Status::off", cul::Engine::Status::off},
283
276
{"Engine::Status::on", cul::Engine::Status::on},
284
{"Engine::Status::active", cul::Engine::Status::active}
277
{"Engine::Status::active", cul::Engine::Status::active}};
287
std::string s; in >> s;
288
281
auto it = lut.find(s);
289
282
if (it != lut.end())
290
283
state = it->second;
291
else throw std::runtime_error
293
"cul::operator>>(std::istream&, Engine::Status&): "
294
"Could not resolve state " + s
285
throw std::runtime_error{
286
"cul::operator>>(std::istream&, Engine::Status&): "
287
"Could not resolve state " +