Skip to content
Snippets Groups Projects
Commit 05cdc61e authored by Nicolas Pope's avatar Nicolas Pope
Browse files

Receive logs and updated control window

parent b8057aeb
No related branches found
No related tags found
1 merge request!23Feature/gui implements #53
......@@ -3,6 +3,8 @@
#include <nanogui/layout.h>
#include <nanogui/label.h>
#include <nanogui/combobox.h>
#include <nanogui/button.h>
#include <nanogui/entypo.h>
#include <vector>
#include <string>
......@@ -13,30 +15,64 @@ using std::vector;
ControlWindow::ControlWindow(nanogui::Widget *parent, ftl::ctrl::Master *ctrl)
: nanogui::Window(parent, "Control"), ctrl_(ctrl) {
: nanogui::Window(parent, "Node Control"), ctrl_(ctrl) {
setLayout(new nanogui::GroupLayout());
using namespace nanogui;
new Label(this, "Select Node","sans-bold");
vector<string> details = ctrl->getSlaves();
LOG(INFO) << "Details count = " << details.size();
vector<string> available;
for (auto &d : details) {
auto detail = ftl::config::json_t::parse(d);
LOG(INFO) << "DETAIL RECEIVED " << detail;
available.push_back(detail["title"].get<string>());
}
_updateDetails();
auto button = new Button(this, "Add Node", ENTYPO_ICON_PLUS);
button->setCallback([this] {
// Show new connection dialog
});
button = new Button(this, "Restart All", ENTYPO_ICON_CYCLE);
button->setCallback([this] {
ctrl_->restart();
});
button = new Button(this, "Shutdown All", ENTYPO_ICON_POWER_PLUG);
button->setCallback([this] {
ctrl_->shutdown();
});
auto select = new ComboBox(this, available);
select->setCallback([this,available](int ix) {
new Label(this, "Select Node","sans-bold");
auto select = new ComboBox(this, node_titles_);
select->setCallback([this](int ix) {
LOG(INFO) << "Change node: " << ix;
_changeActive(ix);
});
button = new Button(this, "Restart Node", ENTYPO_ICON_CYCLE);
button->setCallback([this] {
ctrl_->restart(_getActiveID());
});
button = new Button(this, "Shutdown Node", ENTYPO_ICON_POWER_PLUG);
button->setCallback([this] {
ctrl_->shutdown(_getActiveID());
});
_changeActive(0);
}
ControlWindow::~ControlWindow() {
}
void ControlWindow::_updateDetails() {
node_details_ = ctrl_->getSlaves();
node_titles_.clear();
for (auto &d : node_details_) {
node_titles_.push_back(d["title"].get<string>());
}
}
void ControlWindow::_changeActive(int ix) {
active_ix_ = ix;
}
ftl::UUID ControlWindow::_getActiveID() {
return ftl::UUID(node_details_[active_ix_]["id"].get<string>());
}
......@@ -3,6 +3,7 @@
#include <nanogui/window.h>
#include <ftl/master.hpp>
#include <ftl/uuid.hpp>
namespace ftl {
namespace gui {
......@@ -17,6 +18,13 @@ class ControlWindow : public nanogui::Window {
private:
ftl::ctrl::Master *ctrl_;
std::vector<ftl::config::json_t> node_details_;
std::vector<std::string> node_titles_;
int active_ix_;
void _updateDetails();
void _changeActive(int);
ftl::UUID _getActiveID();
};
}
......
......@@ -194,6 +194,8 @@ class FTLApplication : public nanogui::Screen {
}
virtual void draw(NVGcontext *ctx) {
nvgText(ctx, 10, 10, "FT-Lab Remote Presence System", NULL);
/* Draw the user interface */
Screen::draw(ctx);
}
......
......@@ -37,7 +37,7 @@ class Master {
std::vector<std::string> getConfigurables(const ftl::UUID &peer);
std::vector<std::string> getSlaves();
std::vector<ftl::config::json_t> getSlaves();
std::vector<ftl::config::json_t> get(const std::string &uri);
......
......@@ -3,6 +3,8 @@
#include <ftl/net/universe.hpp>
#include <ftl/configurable.hpp>
#include <loguru.hpp>
#include <mutex>
namespace ftl {
namespace ctrl {
......@@ -11,6 +13,13 @@ class Slave {
public:
Slave(ftl::net::Universe *, ftl::Configurable *);
~Slave();
void sendLog(const loguru::Message& message);
private:
std::vector<ftl::UUID> log_peers_;
ftl::net::Universe *net_;
std::mutex mutex_;
};
}
......
......@@ -11,12 +11,14 @@ using ftl::ctrl::LogEvent;
Master::Master(Configurable *root, Universe *net)
: root_(root), net_(net) {
net_->subscribe("log", [this](const std::string &pre, const std::string &msg) {
net->bind("log", [this](int v, const std::string &pre, const std::string &msg) {
LOG(INFO) << "RECEIVE LOG";
for (auto f : log_handlers_) {
f({pre,msg});
}
});
net->broadcast("log_subscribe", net->id());
}
Master::~Master() {
......@@ -47,8 +49,13 @@ void Master::set(const ftl::UUID &peer, const string &uri, json_t &value) {
net_->send(peer, "update_cfg", uri, (string)value);
}
vector<string> Master::getSlaves() {
return net_->findAll<string>("slave_details");
vector<json_t> Master::getSlaves() {
auto response = net_->findAll<string>("slave_details");
vector<json_t> result;
for (auto &r : response) {
result.push_back(json_t::parse(r));
}
return result;
}
vector<string> Master::getConfigurables() {
......
#include <ftl/slave.hpp>
#include <loguru.hpp>
using ftl::Configurable;
using ftl::net::Universe;
using ftl::ctrl::Slave;
using std::string;
using std::mutex;
using std::unique_lock;
static void netLog(void* user_data, const loguru::Message& message) {
Universe *net = (Universe*)user_data;
net->publish("log", message.preamble, message.message);
Slave *slave = static_cast<Slave*>(user_data);
slave->sendLog(message);
}
Slave::Slave(Universe *net, ftl::Configurable *root) {
net->createResource("log");
Slave::Slave(Universe *net, ftl::Configurable *root) : net_(net) {
net->bind("restart", []() {
LOG(WARNING) << "Remote restart...";
exit(1);
......@@ -39,9 +39,23 @@ Slave::Slave(Universe *net, ftl::Configurable *root) {
return {json.dump()};
});
loguru::add_callback("net_log", netLog, net, loguru::Verbosity_INFO);
net->bind("log_subscribe", [this](const ftl::UUID &peer) {
unique_lock<mutex> lk(mutex_);
log_peers_.push_back(peer);
});
loguru::add_callback("net_log", netLog, this, loguru::Verbosity_INFO);
}
Slave::~Slave() {
}
void Slave::sendLog(const loguru::Message& message) {
unique_lock<mutex> lk(mutex_);
for (auto &p : log_peers_) {
if (!net_->send(p, "log", message.verbosity, message.preamble, message.message)) {
// TODO(Nick) Remove peer from loggers list...
}
}
}
......@@ -104,7 +104,7 @@ class Universe : public ftl::Configurable {
R call(const UUID &pid, const std::string &name, ARGS... args);
template <typename... ARGS>
void send(const UUID &pid, const std::string &name, ARGS... args);
bool send(const UUID &pid, const std::string &name, ARGS... args);
template <typename R, typename... ARGS>
std::optional<R> findOne(const std::string &name, ARGS... args);
......@@ -285,13 +285,13 @@ R Universe::call(const ftl::UUID &pid, const std::string &name, ARGS... args) {
}
template <typename... ARGS>
void Universe::send(const ftl::UUID &pid, const std::string &name, ARGS... args) {
bool Universe::send(const ftl::UUID &pid, const std::string &name, ARGS... args) {
Peer *p = getPeer(pid);
if (p == nullptr) {
DLOG(WARNING) << "Attempting to call an unknown peer : " << pid.to_string();
throw -1;
}
p->send(name, args...);
return p->send(name, args...) > 0;
}
template <typename... ARGS>
......
......@@ -25,8 +25,17 @@ namespace ftl {
uuid_generate(uuid_);
#endif
}
explicit UUID(int u) { memset(&uuid_,u,16); }
UUID(const ftl::UUID &u) { memcpy(&uuid_,&u.uuid_,16); }
explicit UUID(int u) { memset(uuid_,u,16); }
UUID(const ftl::UUID &u) { memcpy(uuid_,u.uuid_,16); }
explicit UUID(const std::string &s) {
#ifdef WIN32
// TODO(Nick) Windows UUID parse
#else
if (uuid_parse(s.c_str(), uuid_) < 0) {
memset(uuid_,0,16);
}
#endif
}
UUID &operator=(const UUID &u) {
memcpy(&uuid_,&u.uuid_,16); return *this;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment