diff --git a/components/common/cpp/include/ftl/configurable.hpp b/components/common/cpp/include/ftl/configurable.hpp index 210184e76e50ab6f9c6ed7fe3f6c6afea7cfee29..3fb497c1d3bb9ccc17d543db5716670ca79c55f6 100644 --- a/components/common/cpp/include/ftl/configurable.hpp +++ b/components/common/cpp/include/ftl/configurable.hpp @@ -97,7 +97,7 @@ class Configurable { void on(const std::string &prop, std::function<void(const config::Event&)>); protected: - nlohmann::json config_; + nlohmann::json &config_; private: std::map<std::string, std::list<std::function<void(const config::Event&)>>> observers_; @@ -132,7 +132,7 @@ std::optional<T> ftl::Configurable::get(const std::string &name) { std::string res_uri = config_["$ref"].get<std::string>()+"/"+name; auto &r = ftl::config::resolve(res_uri); - DLOG(1) << "GET: " << res_uri << " = " << r; + DLOG(2) << "GET: " << res_uri << " = " << r; try { return r.get<T>(); diff --git a/components/common/cpp/include/ftl/configuration.hpp b/components/common/cpp/include/ftl/configuration.hpp index 4d3d9134a10ad9fc9628dd23b67afd2a90ac65fe..099a6c33b504dfb97ec9f0b9f3ff2ffd09236ad5 100644 --- a/components/common/cpp/include/ftl/configuration.hpp +++ b/components/common/cpp/include/ftl/configuration.hpp @@ -27,6 +27,12 @@ std::optional<std::string> locateFile(const std::string &name); Configurable *configure(int argc, char **argv, const std::string &root); +/** + * Change a configuration value based upon a URI. Return true if changed, + * false if it was not able to change. + */ +bool update(const std::string &puri, const json_t &value); + /** * Resolve a JSON schema reference, but do not wait for a remote reference * if it is not available. A null entity is returned if not resolved. diff --git a/components/common/cpp/src/configuration.cpp b/components/common/cpp/src/configuration.cpp index f21eb026202dd2cfaaa1ed822932414136849cdb..58cade5dd1d08c1e9b9c7e87ecf56da327465679 100644 --- a/components/common/cpp/src/configuration.cpp +++ b/components/common/cpp/src/configuration.cpp @@ -192,6 +192,43 @@ void ftl::config::registerConfigurable(ftl::Configurable *cfg) { json_t null_json; +bool ftl::config::update(const std::string &puri, const json_t &value) { + // Remove last component of URI + string tail = ""; + string head = ""; + size_t last_hash = puri.find_last_of('#'); + if (last_hash != string::npos) { + size_t last = puri.find_last_of('/'); + if (last != string::npos && last > last_hash) { + tail = puri.substr(last+1); + head = puri.substr(0, last); + } else { + tail = puri.substr(last_hash+1); + head = puri.substr(0, last_hash); + } + } else { + LOG(WARNING) << "Expected a # in an update URI: " << puri; + return false; + } + + Configurable *cfg = find(head); + + if (cfg) { + DLOG(1) << "Updating CFG: " << head << "[" << tail << "] = " << value; + cfg->set<json_t>(tail, value); + } else { + DLOG(1) << "Updating: " << head << "[" << tail << "] = " << value; + auto r = resolve(head); + if (!r.is_structured()) { + LOG(ERROR) << "Cannot update property '" << tail << "' of '" << head << "'"; + return false; + } + + r[tail] = value; + return true; + } +} + json_t &ftl::config::resolve(const std::string &puri) { string uri_str = puri; @@ -219,44 +256,6 @@ json_t &ftl::config::resolve(const std::string &puri) { } catch(...) { return null_json; } - //} -/* - - int n = 0; - while (u.size() != 0) { - LOG(INFO) << "Resolve URI: " << u; - auto ix = config_index.find(u); - if (ix == config_index.end()) { - u = uri.getBaseURI(--n); - continue; - } - //LOG(INFO) << "FOUND URI " << *(*ix).second; - - if (n == 0) { - return *(*ix).second; - } else { - // Must apply path segments again... - nlohmann::json *c = (*ix).second; - while (n < 0) { - auto seg = uri.getPathSegment(n++); - c = &(*c)[seg]; - - // Recursive resolve... - if ((*c).is_string()) { - c = &resolve(*c); - } - } - - // Give it the correct URI - if (!(*c)["$id"].is_string()) { - (*c)["$id"] = uri.getBaseURI(); - } - - return *c; - } - } - LOG(FATAL) << "Unresolvable configuration URI: " << uri.getBaseURI(); - return null_json;*/ } else { return null_json; } @@ -364,7 +363,7 @@ static void process_options(Configurable *root, const map<string, string> &opts) } try { - //auto ptr = nlohmann::json::json_pointer("/"+opt.first); + /* //auto ptr = nlohmann::json::json_pointer("/"+opt.first); auto ptr = ftl::config::resolve(*root->get<string>("$id") + string("/") + opt.first); LOG(INFO) << "PARAM RES TO " << (*root->get<string>("$id") + string("/") + opt.first); @@ -375,7 +374,10 @@ static void process_options(Configurable *root, const map<string, string> &opts) LOG(ERROR) << "Incorrect type for argument " << opt.first << " - expected '" << type << "', got '" << v.type_name() << "'"; continue; } - ptr.update(v); + ptr.swap(v);*/ + + auto v = nlohmann::json::parse(opt.second); + ftl::config::update(*root->get<string>("$id") + string("/") + opt.first, v); } catch(...) { LOG(ERROR) << "Unrecognised option: " << *root->get<string>("$id") << "#" << opt.first; } diff --git a/components/rgbd-sources/src/rgbd_streamer.cpp b/components/rgbd-sources/src/rgbd_streamer.cpp index 8cf1e8f96c919aef4c5eb8e118e11272aeab70b5..375ae8ebd0d697b6bdab345292e25e9a419bb86d 100644 --- a/components/rgbd-sources/src/rgbd_streamer.cpp +++ b/components/rgbd-sources/src/rgbd_streamer.cpp @@ -161,7 +161,7 @@ void Streamer::_schedule() { shared_lock<shared_mutex> slk(s.second->mutex); if (s.second->state != 0) { - LOG(ERROR) << "Stream not ready to schedule on time: " << uri; + LOG(WARNING) << "Stream not ready to schedule on time: " << uri; continue; } if (s.second->clients[0].size() == 0) {