diff options
author | lonkaars <loek@pipeframe.xyz> | 2022-12-09 15:47:27 +0100 |
---|---|---|
committer | lonkaars <loek@pipeframe.xyz> | 2022-12-09 15:47:27 +0100 |
commit | 1d1799da8880b19aac0dbd2975facf97138bab61 (patch) | |
tree | 4b05c2e4d61782d5da1499435df32c9142dc38af | |
parent | 7db6cde62ee6df76df798f108b747398de8ab26b (diff) |
refactor mesh connector and fix duplicate list entries on refresh
-rw-r--r-- | confui/mainwindow.cpp | 12 | ||||
-rw-r--r-- | confui/mainwindow.h | 4 | ||||
-rw-r--r-- | confui/mesh_connector.cpp | 170 | ||||
-rw-r--r-- | confui/mesh_connector.h | 44 | ||||
-rw-r--r-- | confui/ui_automation.cpp | 8 | ||||
-rw-r--r-- | confui/ui_node.cpp | 6 | ||||
-rw-r--r-- | confui/ui_tab_automations.cpp | 14 | ||||
-rw-r--r-- | confui/ui_tab_automations.h | 4 | ||||
-rw-r--r-- | confui/ui_tab_node_overview.cpp | 6 | ||||
-rw-r--r-- | confui/ui_tab_node_overview.h | 4 |
10 files changed, 144 insertions, 128 deletions
diff --git a/confui/mainwindow.cpp b/confui/mainwindow.cpp index 1f3e333..bc2adee 100644 --- a/confui/mainwindow.cpp +++ b/confui/mainwindow.cpp @@ -20,11 +20,11 @@ CDMainWindow::CDMainWindow(QWidget *parent) : QMainWindow(parent) { QTabWidget* tab_bar_widget = new QTabWidget(this); - automations_widget = new CDAutomationsTabWidget(this); - node_overview_widget = new CDNodeOverviewTabWidget(this); + automations_tab = new CDAutomationsTabWidget(this); + node_overview_tab = new CDNodeOverviewTabWidget(this); - tab_bar_widget->addTab(this->node_overview_widget, "node overview"); - tab_bar_widget->addTab(this->automations_widget, "automations"); + tab_bar_widget->addTab(this->node_overview_tab, "node overview"); + tab_bar_widget->addTab(this->automations_tab, "automations"); setMenuBar(menu_bar); setCentralWidget(tab_bar_widget); @@ -32,6 +32,10 @@ CDMainWindow::CDMainWindow(QWidget *parent) : QMainWindow(parent) { } void CDMainWindow::update() { + // update tabs (children widgets) + automations_tab->update(); + node_overview_tab->update(); + setWindowTitle("confui"); menu_bar->clear(); diff --git a/confui/mainwindow.h b/confui/mainwindow.h index d689f2e..398ed7f 100644 --- a/confui/mainwindow.h +++ b/confui/mainwindow.h @@ -14,8 +14,8 @@ class CDMainWindow : public QMainWindow { Q_OBJECT private: QMenuBar* menu_bar = nullptr; - CDAutomationsTabWidget* automations_widget = nullptr; - CDNodeOverviewTabWidget* node_overview_widget = nullptr; + CDAutomationsTabWidget* automations_tab = nullptr; + CDNodeOverviewTabWidget* node_overview_tab = nullptr; public: CDMeshConnector *mesh_connector = nullptr; diff --git a/confui/mesh_connector.cpp b/confui/mesh_connector.cpp index c87d8c5..d32855a 100644 --- a/confui/mesh_connector.cpp +++ b/confui/mesh_connector.cpp @@ -8,78 +8,85 @@ using std::pair; -cd_link_t CDMeshConnector::get_new_map_id() { - return _fresh_map_id++; +void CDMeshConnector::refresh_config_sync() { } +void CDMeshConnector::refresh_nodes_sync() { } + +cd_link_t CDMeshConnector::get_new_link_id() { + return _fresh_link_id++; +} + +cd_uid_t CDMeshConnector::get_new_node_id() { + return _fresh_node_id++; } CDMeshConnector::CDMeshConnector() { - printf("adding dummy node berta...\n"); - - char* temp_node_berta_name = (char*) malloc(5); - memcpy(temp_node_berta_name, "berta", 5); - - cd_s_node* temp_node_berta = (cd_s_node*) malloc(sizeof(cd_s_node)); - temp_node_berta->name = temp_node_berta_name; - temp_node_berta->name_len = 5; - temp_node_berta->light_on = false; - temp_node_berta->provisioned = false; - cd_mac_addr_t temp_node_berta_address = { 0x00, 0xff, 0x21, 0x69, 0xf2, 0x31 }; - memcpy(temp_node_berta->address, temp_node_berta_address, 6); - - printf("adding dummy node gerrit...\n"); - char* temp_node_gerrit_name = (char*) malloc(6); - memcpy(temp_node_gerrit_name, "gerrit", 6); - - cd_s_node* temp_node_gerrit = (cd_s_node*) malloc(sizeof(cd_s_node)); - temp_node_gerrit->name = temp_node_gerrit_name; - temp_node_gerrit->name_len = 6; - temp_node_gerrit->light_on = false; - temp_node_gerrit->provisioned = false; - cd_mac_addr_t temp_node_gerrit_address = { 0x0e, 0xf9, 0x46, 0x4d, 0xe8, 0x02 }; - memcpy(temp_node_gerrit->address, temp_node_gerrit_address, 6); - - _nodes.push_back(temp_node_berta); - _nodes.push_back(temp_node_gerrit); - create_link(temp_node_berta, temp_node_berta, CD_AUTOMATION_TYPE_TOGGLE); - create_link(temp_node_berta, temp_node_gerrit, CD_AUTOMATION_TYPE_TOGGLE); - create_link(temp_node_gerrit, temp_node_berta, CD_AUTOMATION_TYPE_TURN_OFF); - create_link(temp_node_gerrit, temp_node_gerrit, CD_AUTOMATION_TYPE_TURN_ON); + cd_uid_t berta = create_node({ + .id = 0, // automatically assigned (satisfy compiler) + .address = { 0x00, 0xff, 0x21, 0x69, 0xf2, 0x31 }, + .name_len = 5, + .name = "berta", + .light_on = false, + .provisioned = false, + }); + + cd_uid_t gerrit = create_node({ + .id = 0, // automatically assigned (satisfy compiler) + .address = { 0x0e, 0xf9, 0x46, 0x4d, 0xe8, 0x02 }, + .name_len = 6, + .name = "gerrit", + .light_on = false, + .provisioned = false, + }); + + create_link(berta, berta, CD_AUTOMATION_TYPE_TOGGLE); + create_link(berta, berta, CD_AUTOMATION_TYPE_TOGGLE); + create_link(gerrit, berta, CD_AUTOMATION_TYPE_TURN_OFF); + create_link(gerrit, gerrit, CD_AUTOMATION_TYPE_TURN_ON); return; } -CDMeshConnector::~CDMeshConnector() { - map<cd_link_t, cd_s_automation*> links = get_links(); - vector<cd_s_node*> nodes = get_raw_nodes(); +cd_uid_t CDMeshConnector::create_node(cd_s_node node) { + cd_s_node* _node = (cd_s_node*) malloc(sizeof(cd_s_node)); - // free all automation structs - for (pair<cd_link_t, cd_s_automation*> link : links) - remove_link(link.first); + // id + cd_uid_t id = get_new_node_id(); + _node->id = id; + // address + memcpy(_node->address, node.address, sizeof(cd_mac_addr_t)); + // name len + _node->name_len = node.name_len; + // name + char* name = (char*) malloc(node.name_len); + memcpy(name, node.name, node.name_len); + _node->name = name; + // light on + _node->light_on = node.light_on; + // provisioned + _node->provisioned = node.provisioned; - // free all node structs - for (cd_s_node* node : nodes) - if (node != nullptr) free(node); + printf("(new) node[%d] = %.*s\n", id, (int) node.name_len, node.name); - return; + _nodes[id] = _node; + return id; } -void CDMeshConnector::refresh_config_sync() { - return; -} +CDMeshConnector::~CDMeshConnector() { + // free all automation structs + for (pair<cd_link_t, cd_s_automation*> link : _links) + remove_link(link.first); -void CDMeshConnector::refresh_nodes_sync() { - return; -} + // free all node structs + for (pair<cd_uid_t, cd_s_node*> node : _nodes) + remove_node(node.first); -vector<cd_s_node*> CDMeshConnector::get_raw_nodes() { - return _nodes; + return; } -map<cd_mac_addr_cpp_t, cd_s_node*> CDMeshConnector::get_nodes(bool provisioned) { - map<cd_mac_addr_cpp_t, cd_s_node*> nodes; - vector<cd_s_node*> raw_nodes = get_raw_nodes(); - for (cd_s_node* node : raw_nodes) { - if (provisioned && (node->provisioned == false)) continue; - nodes[cd_mac_to_cpp_arr(node->address)] = node; +map<cd_uid_t, cd_s_node*> CDMeshConnector::get_nodes(bool provisioned) { + map<cd_uid_t, cd_s_node*> nodes; + for (pair<cd_uid_t, cd_s_node*> node : _nodes) { + if (provisioned && (node.second->provisioned == false)) continue; + nodes[node.first] = node.second; } return nodes; } @@ -88,45 +95,40 @@ map<cd_link_t, cd_s_automation*> CDMeshConnector::get_links() { return _links; } -vector<cd_s_automation*> CDMeshConnector::get_config() { - vector<cd_s_automation*> automations; - map<cd_link_t, cd_s_automation*> links = get_links(); - for (pair<cd_link_t, cd_s_automation*> link : links) - automations.push_back(link.second); - return automations; -} - -void CDMeshConnector::set_link(cd_link_t link, cd_s_automation* automation) { +void CDMeshConnector::update_link(cd_link_t link, cd_s_automation* automation) { _links[link] = automation; printf("link[%d] = %.*s %s %.*s\n", link, (int) automation->button->name_len, automation->button->name, automation->type == CD_AUTOMATION_TYPE_TOGGLE ? "toggles" : automation->type == CD_AUTOMATION_TYPE_TURN_OFF ? "turns off" : "turns on", (int) automation->light->name_len, automation->light->name); } -cd_link_t CDMeshConnector::create_link(cd_s_node* button, cd_s_node* light, enum cd_e_automation_type type) { +cd_link_t CDMeshConnector::create_link(cd_uid_t button, cd_uid_t light, enum cd_e_automation_type type) { + cd_link_t id = get_new_link_id(); + cd_s_automation* automation = (cd_s_automation*) malloc(sizeof(cd_s_automation)); - automation->button = button; - automation->light = light; + automation->id = id; automation->type = type; + automation->button = _nodes[button]; + automation->light = _nodes[light]; - cd_link_t link = get_new_map_id(); printf("(new) "); - set_link(link, automation); + update_link(id, automation); - return link; + return id; } void CDMeshConnector::remove_link(cd_link_t link_handle) { printf("remove link[%d]\n", link_handle); - if (_links[link_handle] != nullptr) free(_links[link_handle]); + if (_links[link_handle] != nullptr) + free(_links[link_handle]); _links.erase(link_handle); return; } -cd_s_node* CDMeshConnector::get_node_by_id(cd_mac_addr_t address) { - cd_s_node* node = std::find_if(_nodes.begin(), _nodes.end(), - [address] (const cd_s_node* n) { - return strncmp((char*)n->address, (char*)address, 6); - })[0]; - return node; +void CDMeshConnector::remove_node(cd_uid_t node_handle) { + printf("remove node[%d]\n", node_handle); + if (_nodes[node_handle] != nullptr) + free(_nodes[node_handle]); + _nodes.erase(node_handle); + return; } void CDMeshConnector::update_node(cd_s_node* node_ptr) { @@ -134,19 +136,19 @@ void CDMeshConnector::update_node(cd_s_node* node_ptr) { return; } -void CDMeshConnector::node_join_network(cd_s_node* node_ptr) { +void CDMeshConnector::network_join_node(cd_s_node* node_ptr) { node_ptr->provisioned = true; printf("join %.*s into network\n", (int) node_ptr->name_len, node_ptr->name); return; } -void CDMeshConnector::node_remove_network(cd_s_node* node_ptr) { +void CDMeshConnector::network_remove_node(cd_s_node* node_ptr) { node_ptr->provisioned = false; printf("remove %.*s from network\n", (int) node_ptr->name_len, node_ptr->name); return; } -string cd_mac_to_string(cd_mac_addr_t mac) { +string CDMeshConnector::cd_mac_to_string(cd_mac_addr_t mac) { char* addr = nullptr; asprintf(&addr, "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); string ret = addr; @@ -154,7 +156,3 @@ string cd_mac_to_string(cd_mac_addr_t mac) { return ret; } -cd_mac_addr_cpp_t cd_mac_to_cpp_arr(cd_mac_addr_t mac) { - return { mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] }; -} - diff --git a/confui/mesh_connector.h b/confui/mesh_connector.h index 220974a..7ead59a 100644 --- a/confui/mesh_connector.h +++ b/confui/mesh_connector.h @@ -11,9 +11,9 @@ using std::map; using std::string; using std::array; +typedef uint32_t cd_uid_t; typedef uint32_t cd_link_t; typedef uint8_t cd_mac_addr_t[6]; -typedef array<uint8_t, 6> cd_mac_addr_cpp_t; enum cd_e_automation_type { CD_AUTOMATION_TYPE_TOGGLE, @@ -22,6 +22,7 @@ enum cd_e_automation_type { }; typedef struct { + cd_uid_t id; cd_mac_addr_t address; size_t name_len; const char* name; @@ -30,6 +31,7 @@ typedef struct { } cd_s_node; typedef struct { + cd_link_t id; cd_e_automation_type type; cd_s_node* button; cd_s_node* light; @@ -37,30 +39,42 @@ typedef struct { class CDMeshConnector { private: - vector<cd_s_node*> _nodes; map<cd_link_t, cd_s_automation*> _links; - cd_link_t _fresh_map_id = 0; - virtual cd_link_t get_new_map_id(); + map<cd_uid_t, cd_s_node*> _nodes; + + virtual cd_link_t get_new_link_id(); + virtual cd_uid_t get_new_node_id(); + + cd_link_t _fresh_link_id = 0; + cd_uid_t _fresh_node_id = 0; + + virtual cd_uid_t create_node(cd_s_node node); + virtual void remove_node(cd_uid_t node_handle); + public: CDMeshConnector(); virtual ~CDMeshConnector(); + + // (UNUSED/UNIMPLEMENTED) refresh functions virtual void refresh_nodes_sync(); virtual void refresh_config_sync(); + + // data fetching functions virtual map<cd_link_t, cd_s_automation*> get_links(); - virtual map<cd_mac_addr_cpp_t, cd_s_node*> get_nodes(bool provisioned); - virtual vector<cd_s_node*> get_raw_nodes(); - virtual vector<cd_s_automation*> get_config(); - virtual cd_link_t create_link(cd_s_node* button, cd_s_node* light, enum cd_e_automation_type action); - virtual void set_link(cd_link_t link, cd_s_automation* automation); + virtual map<cd_uid_t, cd_s_node*> get_nodes(bool provisioned = false); + + // network modification functions + virtual cd_link_t create_link(cd_uid_t button, cd_uid_t light, enum cd_e_automation_type action); + virtual void update_link(cd_link_t link, cd_s_automation* automation); virtual void remove_link(cd_link_t link_handle); - virtual cd_s_node* get_node_by_id(cd_mac_addr_t address); + virtual void update_node(cd_s_node* node_ptr); - virtual void node_join_network(cd_s_node* node_ptr); - virtual void node_remove_network(cd_s_node* node_ptr); + virtual void network_join_node(cd_s_node* node_ptr); + virtual void network_remove_node(cd_s_node* node_ptr); + + // conversion functions + static string cd_mac_to_string(cd_mac_addr_t mac); }; extern CDMeshConnector* g_cd_mesh_connector; -string cd_mac_to_string(cd_mac_addr_t mac); -cd_mac_addr_cpp_t cd_mac_to_cpp_arr(cd_mac_addr_t mac); - diff --git a/confui/ui_automation.cpp b/confui/ui_automation.cpp index 3c555cd..72e2446 100644 --- a/confui/ui_automation.cpp +++ b/confui/ui_automation.cpp @@ -30,15 +30,15 @@ void CDAutomationWidget::set_automation(cd_link_t link, cd_s_automation* automat void CDAutomationWidget::update() { button_remove->setText("Delete"); - map<cd_mac_addr_cpp_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false); + map<cd_uid_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false); dropdown_button->clear(); dropdown_light->clear(); - for (pair<cd_mac_addr_cpp_t, cd_s_node*> node : nodes) { + for (pair<cd_uid_t, cd_s_node*> node : nodes) { QString label = ""; label.append(QString::fromLocal8Bit(node.second->name, node.second->name_len)); label.append(" ("); - label.append(QString::fromStdString(cd_mac_to_string(node.second->address))); + label.append(QString::fromStdString(CDMeshConnector::cd_mac_to_string(node.second->address))); label.append(")"); QString userData = QString::fromLocal8Bit((char*) node.second->address, 6); @@ -66,5 +66,5 @@ bool CDAutomationWidget::conf_valid() { void CDAutomationWidget::apply() { if (!conf_valid()) return; - g_cd_mesh_connector->set_link(_id, _automation); + g_cd_mesh_connector->update_link(_id, _automation); } diff --git a/confui/ui_node.cpp b/confui/ui_node.cpp index f369fba..41ffad6 100644 --- a/confui/ui_node.cpp +++ b/confui/ui_node.cpp @@ -31,7 +31,7 @@ void CDNodeWidget::update() { QString node_name = QString::fromLocal8Bit(_node->name, _node->name_len); label_node_name->setText(node_name); - QString node_address = QString::fromStdString(cd_mac_to_string(_node->address)); + QString node_address = QString::fromStdString(CDMeshConnector::cd_mac_to_string(_node->address)); node_address.prepend("("); node_address.append(")"); label_node_address->setText(node_address); @@ -45,8 +45,8 @@ void CDNodeWidget::update() { } void CDNodeWidget::toggle_provision() { - if (_node->provisioned) g_cd_mesh_connector->node_remove_network(_node); - else g_cd_mesh_connector->node_join_network(_node); + if (_node->provisioned) g_cd_mesh_connector->network_remove_node(_node); + else g_cd_mesh_connector->network_join_node(_node); update(); } diff --git a/confui/ui_tab_automations.cpp b/confui/ui_tab_automations.cpp index 0702d20..af02ab9 100644 --- a/confui/ui_tab_automations.cpp +++ b/confui/ui_tab_automations.cpp @@ -4,7 +4,6 @@ #include <QPushButton> #include "ui_tab_automations.h" -#include "ui_automation.h" using std::pair; @@ -44,17 +43,16 @@ CDAutomationsTabWidget::CDAutomationsTabWidget(CDMainWindow* main_window) : QWid void CDAutomationsTabWidget::update() { map<cd_link_t, cd_s_automation*> links = this->mainwindow->mesh_connector->get_links(); - map<cd_link_t, CDAutomationWidget*> widgets; for (pair<cd_link_t, cd_s_automation*> link : links) { - if (widgets.count(link.first)) { // node is already in list - widgets[link.first]->update(); + if (automation_widgets.count(link.first)) { // node is already in list + automation_widgets[link.first]->update(); } else { - widgets[link.first] = new CDAutomationWidget(this); - widgets[link.first]->set_automation(link.first, link.second); - widgets[link.first]->update(); + automation_widgets[link.first] = new CDAutomationWidget(this); + automation_widgets[link.first]->set_automation(link.first, link.second); + automation_widgets[link.first]->update(); } - automations->addWidget(widgets[link.first]); + automations->addWidget(automation_widgets[link.first]); } } diff --git a/confui/ui_tab_automations.h b/confui/ui_tab_automations.h index 3fd433a..ec34189 100644 --- a/confui/ui_tab_automations.h +++ b/confui/ui_tab_automations.h @@ -2,8 +2,9 @@ #include <QMainWindow> -#include "ui_scroll_container.h" #include "mainwindow.h" +#include "ui_automation.h" +#include "ui_scroll_container.h" class CDAddAutomationWidget; class CDAutomationsTabWidget : public QWidget { @@ -13,6 +14,7 @@ private: CDScrollContainerLayout* main_layout; QVBoxLayout* automations; CDAddAutomationWidget* new_automation_button; + map<cd_link_t, CDAutomationWidget*> automation_widgets; public: CDMainWindow *mainwindow = nullptr; diff --git a/confui/ui_tab_node_overview.cpp b/confui/ui_tab_node_overview.cpp index d0280cf..84f1d6e 100644 --- a/confui/ui_tab_node_overview.cpp +++ b/confui/ui_tab_node_overview.cpp @@ -4,7 +4,6 @@ #include <QScrollArea> #include "ui_tab_node_overview.h" -#include "ui_node.h" using std::pair; @@ -18,10 +17,9 @@ CDNodeOverviewTabWidget::CDNodeOverviewTabWidget(CDMainWindow* main_window) : QW } void CDNodeOverviewTabWidget::update() { - map<cd_mac_addr_cpp_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false); - map<cd_mac_addr_cpp_t, CDNodeWidget*> node_widgets; + map<cd_uid_t, cd_s_node*> nodes = g_cd_mesh_connector->get_nodes(false); - for (pair<cd_mac_addr_cpp_t, cd_s_node*> node : nodes) { + for (pair<cd_uid_t, cd_s_node*> node : nodes) { if (node_widgets.count(node.first)) { // node is already in list node_widgets[node.first]->update(); } else { diff --git a/confui/ui_tab_node_overview.h b/confui/ui_tab_node_overview.h index d541dc6..d2197b1 100644 --- a/confui/ui_tab_node_overview.h +++ b/confui/ui_tab_node_overview.h @@ -2,14 +2,16 @@ #include <QMainWindow> -#include "ui_scroll_container.h" #include "mainwindow.h" +#include "ui_node.h" +#include "ui_scroll_container.h" class CDNodeOverviewTabWidget : public QWidget { Q_OBJECT private: CDScrollContainerLayout* main_layout; + map<cd_uid_t, CDNodeWidget*> node_widgets; public: CDMainWindow *mainwindow = nullptr; |