diff --git a/applications/gui/src/main.cpp b/applications/gui/src/main.cpp index 5ebc552fa0ee0664c7a0b7898a723b90bf87f29c..99af829eb646f20f1e0f680837e8855739fa6be1 100644 --- a/applications/gui/src/main.cpp +++ b/applications/gui/src/main.cpp @@ -23,32 +23,6 @@ int main(int argc, char **argv) { } }); - std::map<ftl::UUID, std::vector<ftl::NetConfigurable*>> peerConfigurables; - - // FIXME: Move this elsewhere, it is not just for GUI - net->onConnect([&controller, &peerConfigurables](ftl::net::Peer *p) { - ftl::UUID peer = p->id(); - auto cs = controller->getConfigurables(peer); - for (auto c : cs) { - //LOG(INFO) << "NET CONFIG: " << c; - ftl::config::json_t *configuration = new ftl::config::json_t; - *configuration = controller->get(peer, c); - if (!configuration->empty()) { - ftl::NetConfigurable *nc = new ftl::NetConfigurable(peer, c, *controller, *configuration); - peerConfigurables[peer].push_back(nc); - } - } - }); - - net->onDisconnect([&peerConfigurables](ftl::net::Peer *p) { - ftl::UUID peer = p->id(); - for (ftl::NetConfigurable *nc : peerConfigurables[peer]) { - ftl::config::json_t *configuration = &(nc->getConfig()); - delete nc; - delete configuration; - } - }); - net->start(); net->waitConnections(); diff --git a/applications/reconstruct/src/main.cpp b/applications/reconstruct/src/main.cpp index 33db96ae046a1ee5c29898a503d0c483446e7f91..ce571918c28a237cb962bd263dbe5ace6b903655 100644 --- a/applications/reconstruct/src/main.cpp +++ b/applications/reconstruct/src/main.cpp @@ -12,7 +12,7 @@ #include <ftl/rgbd.hpp> #include <ftl/rgbd/virtual.hpp> #include <ftl/rgbd/streamer.hpp> -#include <ftl/slave.hpp> +#include <ftl/master.hpp> #include <ftl/rgbd/group.hpp> #include <ftl/threads.hpp> #include <ftl/codecs/writer.hpp> @@ -82,58 +82,9 @@ static Eigen::Affine3d create_rotation_matrix(float ax, float ay, float az) { return rz * rx * ry; } -// TODO: * Remove this class (requires more general solution). Also does not -// process disconnections/reconnections/types etc. correctly. -// * Update when new options become available. - -class ConfigProxy { - private: - vector<ftl::UUID> peers_; - vector<std::string> uris_; - ftl::net::Universe *net_; - - public: - ConfigProxy(ftl::net::Universe *net) { - net_ = net; - - auto response = net_->findAll<std::string>("node_details"); - for (auto &r : response) { - auto r_json = json_t::parse(r); - peers_.push_back(ftl::UUID(r_json["id"].get<std::string>())); - uris_.push_back(r_json["title"].get<std::string>()); - } - } - - void add(ftl::Configurable *root, const std::string &uri, const std::string &name) { - auto config = json_t::parse(net_->call<string>(peers_[0], "get_cfg", uris_[0] + "/" + uri)); - auto *proxy = ftl::create<ftl::Configurable>(root, name); - - try { - for (auto &itm : config.get<json::object_t>()) { - auto key = itm.first; - auto value = itm.second; - if (*key.begin() == '$') { continue; } - - proxy->set(key, value); - proxy->on(key, [this, uri, key, value, proxy](const ftl::config::Event&) { - for (size_t i = 0; i < uris_.size(); i++) { - // TODO: check that config exists? - auto peer = peers_[i]; - std::string name = uris_[i] + "/" + uri + "/" + key; - net_->send(peer, "update_cfg", name, proxy->getConfig()[key].dump()); - } - }); - } - } - catch (nlohmann::detail::type_error) { - LOG(ERROR) << "Failed to add config proxy for: " << uri << "/" << name; - } - } -}; - static void run(ftl::Configurable *root) { Universe *net = ftl::create<Universe>(root, "net"); - ftl::ctrl::Slave slave(net, root); + ftl::ctrl::Master ctrl(root, net); // Controls auto *controls = ftl::create<ftl::Configurable>(root, "controls"); @@ -192,17 +143,6 @@ static void run(ftl::Configurable *root) { return; } - ConfigProxy *configproxy = nullptr; - if (net->numberOfPeers() > 0) { - configproxy = new ConfigProxy(net); // TODO delete - auto *disparity = ftl::create<ftl::Configurable>(root, "disparity"); - configproxy->add(disparity, "source/disparity/algorithm", "algorithm"); - configproxy->add(disparity, "source/disparity/bilateral_filter", "bilateral_filter"); - configproxy->add(disparity, "source/disparity/optflow_filter", "optflow_filter"); - configproxy->add(disparity, "source/disparity/mls", "mls"); - configproxy->add(disparity, "source/disparity/cross", "cross"); - } - // Must find pose for each source... if (sources.size() > 1) { std::map<std::string, Eigen::Matrix4d> transformations; @@ -382,7 +322,7 @@ static void run(ftl::Configurable *root) { LOG(INFO) << "Shutting down..."; ftl::timer::stop(); - slave.stop(); + ctrl.stop(); net->shutdown(); ftl::pool.stop(); diff --git a/applications/recorder/src/main.cpp b/applications/recorder/src/main.cpp index 58966e176846367f232b9d214e0e5bd68064dede..d2001114f8f98c4bf35630c9676651bf6e91fae3 100644 --- a/applications/recorder/src/main.cpp +++ b/applications/recorder/src/main.cpp @@ -11,7 +11,7 @@ #include <ftl/rgbd.hpp> #include <ftl/rgbd/virtual.hpp> #include <ftl/rgbd/streamer.hpp> -#include <ftl/slave.hpp> +#include <ftl/master.hpp> #include <ftl/rgbd/group.hpp> #include <ftl/threads.hpp> #include <ftl/codecs/writer.hpp> @@ -64,7 +64,7 @@ static Eigen::Affine3d create_rotation_matrix(float ax, float ay, float az) { static void run(ftl::Configurable *root) { Universe *net = ftl::create<Universe>(root, "net"); - ftl::ctrl::Slave slave(net, root); + ftl::ctrl::Master ctrl(root, net); // Controls auto *controls = ftl::create<ftl::Configurable>(root, "controls"); @@ -202,7 +202,7 @@ static void run(ftl::Configurable *root) { LOG(INFO) << "Shutting down..."; ftl::timer::stop(); - slave.stop(); + ctrl.stop(); net->shutdown(); ftl::pool.stop(); diff --git a/applications/vision/src/main.cpp b/applications/vision/src/main.cpp index f99754cbf558bb3d0f53fde37763855fac7af128..4f245a07705331324e3a2730411bec992f404dce 100644 --- a/applications/vision/src/main.cpp +++ b/applications/vision/src/main.cpp @@ -22,7 +22,7 @@ //#include <ftl/display.hpp> #include <ftl/rgbd/streamer.hpp> #include <ftl/net/universe.hpp> -#include <ftl/slave.hpp> +#include <ftl/master.hpp> #include <nlohmann/json.hpp> #include "opencv2/imgproc.hpp" @@ -50,7 +50,7 @@ using json = nlohmann::json; static void run(ftl::Configurable *root) { Universe *net = ftl::create<Universe>(root, "net"); - ftl::ctrl::Slave slave(net, root); + ftl::ctrl::Master ctrl(root, net); auto paths = root->get<vector<string>>("paths"); string file = ""; @@ -84,7 +84,7 @@ static void run(ftl::Configurable *root) { ftl::timer::start(true); LOG(INFO) << "Stopping..."; - slave.stop(); + ctrl.stop(); stream->stop(); net->shutdown(); diff --git a/components/control/cpp/CMakeLists.txt b/components/control/cpp/CMakeLists.txt index f55ec9c19f0e6c30c3eafbaf203ee6a2e49b4ceb..3f6d4a29932ccd0cdadca61227de914d55d0f4b0 100644 --- a/components/control/cpp/CMakeLists.txt +++ b/components/control/cpp/CMakeLists.txt @@ -1,5 +1,4 @@ add_library(ftlctrl - src/slave.cpp src/master.cpp ) diff --git a/components/control/cpp/include/ftl/master.hpp b/components/control/cpp/include/ftl/master.hpp index 9b658aaadbedccdd86c452318ef1832230836ef7..15d27ab95c4846cc1c19a496a64db06c30c43ef5 100644 --- a/components/control/cpp/include/ftl/master.hpp +++ b/components/control/cpp/include/ftl/master.hpp @@ -10,8 +10,15 @@ #include <Eigen/Eigen> namespace ftl { + +class NetConfigurable; + namespace ctrl { +struct SystemState { + bool paused; +}; + struct LogEvent { int verbosity; std::string preamble; @@ -57,6 +64,18 @@ class Master { void setPose(const std::string &uri, const Eigen::Matrix4d &pose); + /** + * Clean up to remove log and status forwarding over the network. + */ + void stop(); + + /** + * Do not call! Automatically called from logging subsystem. + */ + void sendLog(const loguru::Message& message); + + bool isPaused() const { return state_.paused; } + // Events //void onError(); @@ -72,6 +91,12 @@ class Master { std::vector<std::function<void(const LogEvent&)>> log_handlers_; ftl::Configurable *root_; ftl::net::Universe *net_; + std::map<ftl::UUID, std::vector<ftl::NetConfigurable*>> peerConfigurables_; + std::vector<ftl::UUID> log_peers_; + RECURSIVE_MUTEX mutex_; + bool in_log_; + bool active_; + SystemState state_; }; } diff --git a/components/control/cpp/include/ftl/slave.hpp b/components/control/cpp/include/ftl/slave.hpp deleted file mode 100644 index e3ebd69e46fa5177eebbcc2d8d6b2f2cce70f204..0000000000000000000000000000000000000000 --- a/components/control/cpp/include/ftl/slave.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _FTL_CTRL_SLAVE_HPP_ -#define _FTL_CTRL_SLAVE_HPP_ - -#include <ftl/net/universe.hpp> -#include <ftl/configurable.hpp> -#include <loguru.hpp> -#include <ftl/threads.hpp> - -namespace ftl { -namespace ctrl { - -struct SystemState { - bool paused; -}; - -/** - * Allows a node to be remote controlled and observed over the network. All - * such nodes should create a single instance of this class, but must call - * "stop()" before terminating the network. - */ -class Slave { - public: - Slave(ftl::net::Universe *, ftl::Configurable *); - ~Slave(); - - /** - * Clean up to remove log and status forwarding over the network. - */ - void stop(); - - /** - * Do not call! Automatically called from logging subsystem. - */ - void sendLog(const loguru::Message& message); - - bool isPaused() const { return state_.paused; } - - private: - std::vector<ftl::UUID> log_peers_; - ftl::net::Universe *net_; - RECURSIVE_MUTEX mutex_; - bool in_log_; - bool active_; - SystemState state_; -}; - -} -} - -#endif // _FTL_CTRL_SLAVE_HPP_ diff --git a/components/control/cpp/src/master.cpp b/components/control/cpp/src/master.cpp index a13a67a90b4bc7ccc1bd2c893580fc286dfb330a..d59b61b8544ac21567d7b6cddfcc6bba90ed76b4 100644 --- a/components/control/cpp/src/master.cpp +++ b/components/control/cpp/src/master.cpp @@ -1,4 +1,5 @@ #include <ftl/master.hpp> +#include <ftl/net_configurable.hpp> using ftl::ctrl::Master; using ftl::net::Universe; @@ -11,6 +12,47 @@ using ftl::ctrl::LogEvent; Master::Master(Configurable *root, Universe *net) : root_(root), net_(net) { + // Init system state + state_.paused = false; + + net->bind("restart", []() { + LOG(WARNING) << "Remote restart..."; + //exit(1); + ftl::exit_code = 1; + ftl::running = false; + }); + + net->bind("shutdown", []() { + LOG(WARNING) << "Remote shutdown..."; + //exit(0); + ftl::running = false; + }); + + net->bind("pause", [this]() { + state_.paused = !state_.paused; + }); + + net->bind("update_cfg", [](const std::string &uri, const std::string &value) { + ftl::config::update(uri, nlohmann::json::parse(value)); + }); + + net->bind("get_cfg", [](const std::string &uri) -> std::string { + return ftl::config::resolve(uri, false).dump(); + }); + + net->bind("list_configurables", []() { + return ftl::config::list(); + }); + + net->bind("log_subscribe", [this](const ftl::UUID &peer) { + UNIQUE_LOCK(mutex_, lk); + log_peers_.push_back(peer); + }); + + net->bind("connect", [this](const std::string &url) { + net_->connect(url); + }); + net->bind("log", [this](int v, const std::string &pre, const std::string &msg) { for (auto f : log_handlers_) { f({v,pre,msg}); @@ -20,16 +62,35 @@ Master::Master(Configurable *root, Universe *net) net->bind("node_details", [net,root]() -> std::vector<std::string> { ftl::config::json_t json { {"id", net->id().to_string()}, - {"title", root->value("title", *root->get<string>("$id"))}, - {"kind", "master"} + {"title", root->value("title", *root->get<string>("$id"))} }; return {json.dump()}; }); //net->broadcast("log_subscribe", net->id()); - net->onConnect([this](ftl::net::Peer*) { + net->onConnect([this](ftl::net::Peer *p) { //net_->broadcast("log_subscribe", net_->id()); + ftl::UUID peer = p->id(); + auto cs = getConfigurables(peer); + for (auto c : cs) { + //LOG(INFO) << "NET CONFIG: " << c; + ftl::config::json_t *configuration = new ftl::config::json_t; + *configuration = get(peer, c); + if (!configuration->empty()) { + ftl::NetConfigurable *nc = new ftl::NetConfigurable(peer, c, *this, *configuration); + peerConfigurables_[peer].push_back(nc); + } + } + }); + + net->onDisconnect([this](ftl::net::Peer *p) { + ftl::UUID peer = p->id(); + for (ftl::NetConfigurable *nc : peerConfigurables_[peer]) { + ftl::config::json_t *configuration = &(nc->getConfig()); + delete nc; + delete configuration; + } }); } @@ -133,4 +194,34 @@ void Master::setPose(const std::string &uri, const Eigen::Matrix4d &pose) { //void onError(); void Master::onLog(function<void(const LogEvent &)> h) { log_handlers_.push_back(h); +} + +void Master::stop() { + if (!active_) return; + active_ = false; + loguru::remove_all_callbacks(); + net_->unbind("restart"); + net_->unbind("shutdown"); + net_->unbind("update_cfg"); + net_->unbind("get_cfg"); + net_->unbind("slave_details"); // TODO: Remove + net_->unbind("log_subscribe"); +} + +void Master::sendLog(const loguru::Message& message) { + UNIQUE_LOCK(mutex_, lk); + if (in_log_) return; + in_log_ = true; + + for (auto &p : log_peers_) { + auto peer = net_->getPeer(p); + if (!peer || !peer->isConnected()) continue; + + std::cout << "sending log to master..." << std::endl; + if (!net_->send(p, "log", message.verbosity, message.preamble, message.message)) { + // TODO(Nick) Remove peer from loggers list... + } + } + + in_log_ = false; } \ No newline at end of file diff --git a/components/control/cpp/src/slave.cpp b/components/control/cpp/src/slave.cpp deleted file mode 100644 index cd2d0f1ff03fa3aa88d94420a6811aac63c9c7b9..0000000000000000000000000000000000000000 --- a/components/control/cpp/src/slave.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include <ftl/slave.hpp> - -#include <ftl/threads.hpp> - -using ftl::Configurable; -using ftl::net::Universe; -using ftl::ctrl::Slave; -using std::string; - -// static void netLog(void* user_data, const loguru::Message& message) { -// Slave *slave = static_cast<Slave*>(user_data); -// slave->sendLog(message); -// } - -Slave::Slave(Universe *net, ftl::Configurable *root) : net_(net), in_log_(false), active_(true) { - - // Init system state - state_.paused = false; - - net->bind("restart", []() { - LOG(WARNING) << "Remote restart..."; - //exit(1); - ftl::exit_code = 1; - ftl::running = false; - }); - - net->bind("shutdown", []() { - LOG(WARNING) << "Remote shutdown..."; - //exit(0); - ftl::running = false; - }); - - net->bind("pause", [this]() { - state_.paused = !state_.paused; - }); - - net->bind("update_cfg", [](const std::string &uri, const std::string &value) { - ftl::config::update(uri, nlohmann::json::parse(value)); - }); - - net->bind("get_cfg", [](const std::string &uri) -> std::string { - return ftl::config::resolve(uri, false).dump(); - }); - - net->bind("list_configurables", []() { - return ftl::config::list(); - }); - - net->bind("node_details", [net,root]() -> std::vector<std::string> { - ftl::config::json_t json { - {"id", net->id().to_string()}, - {"title", root->value("title", *root->get<string>("$id"))}, - {"kind", "slave"} - }; - return {json.dump()}; - }); - - net->bind("log_subscribe", [this](const ftl::UUID &peer) { - UNIQUE_LOCK(mutex_, lk); - log_peers_.push_back(peer); - }); - - net->bind("connect", [this](const std::string &url) { - net_->connect(url); - }); - - //net->onConnect([this](ftl::net::Peer *peer) { - // net_->broadcast("new_peer", peer->id()); - //}); - - //loguru::add_callback("net_log", netLog, this, loguru::Verbosity_INFO); -} - -Slave::~Slave() { - stop(); -} - -void Slave::stop() { - if (!active_) return; - active_ = false; - loguru::remove_all_callbacks(); - net_->unbind("restart"); - net_->unbind("shutdown"); - net_->unbind("update_cfg"); - net_->unbind("get_cfg"); - net_->unbind("slave_details"); - net_->unbind("log_subscribe"); -} - -void Slave::sendLog(const loguru::Message& message) { - UNIQUE_LOCK(mutex_, lk); - if (in_log_) return; - in_log_ = true; - - for (auto &p : log_peers_) { - auto peer = net_->getPeer(p); - if (!peer || !peer->isConnected()) continue; - - std::cout << "sending log to master..." << std::endl; - if (!net_->send(p, "log", message.verbosity, message.preamble, message.message)) { - // TODO(Nick) Remove peer from loggers list... - } - } - - in_log_ = false; -} diff --git a/components/net/cpp/test/net_configurable_unit.cpp b/components/net/cpp/test/net_configurable_unit.cpp index c8bf42247ef3f23023b25c159a968deda1fd419b..9452f7cea40b43d2f09917c046f5b6acd5f184cc 100644 --- a/components/net/cpp/test/net_configurable_unit.cpp +++ b/components/net/cpp/test/net_configurable_unit.cpp @@ -1,6 +1,6 @@ #include "catch.hpp" #include <ftl/net_configurable.hpp> -#include <ftl/slave.hpp> +#include <ftl/master.hpp> using ftl::NetConfigurable; @@ -19,7 +19,7 @@ SCENARIO( "NetConfigurable::set()" ) { ftl::Configurable *rootSlave; rootSlave = new ftl::Configurable(jsonSlave); ftl::net::Universe *netSlave = ftl::config::create<ftl::net::Universe>(rootSlave, std::string("test")); - ftl::ctrl::Slave slave(netSlave, rootSlave); + ftl::ctrl::Master ctrl(rootSlave, netSlave); netSlave->start(); netSlave->waitConnections(); net->waitConnections();