This commit is contained in:
2024-08-29 15:00:27 +02:00
parent 6c6a60e980
commit 21a2c16607
31 changed files with 457 additions and 409 deletions
+4 -5
View File
@@ -1,19 +1,18 @@
#include "UI_button.hpp" #include "UI_button.hpp"
UI_button::UI_button(std::string id, std::string text, Color fg_color, Color bg_color, std::function<void(std::string)> on_click) UI_button::UI_button(std::string id, std::string text, Color fg_color, Color bg_color,
std::function<void(std::string)> on_click)
: UI_item(id, UI_BUTTON_TYPE, text, 12, fg_color, bg_color) : UI_item(id, UI_BUTTON_TYPE, text, 12, fg_color, bg_color)
{ {
this->m_on_click = on_click; this->m_on_click = on_click;
} }
UI_button::UI_button(const json& j) UI_button::UI_button(const json &j) : UI_item(UI_BUTTON_TYPE), m_on_click(nullptr)
: UI_item(UI_BUTTON_TYPE),
m_on_click(nullptr)
{ {
from_json(j); from_json(j);
} }
void UI_button::from_json(const json& j) void UI_button::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
} }
+11 -9
View File
@@ -6,14 +6,16 @@
class UI_button : public UI_item class UI_button : public UI_item
{ {
public: public:
UI_button(std::string id, std::string text, Color fg_color, Color bg_color, std::function<void(std::string)> on_click = nullptr); UI_button(std::string id, std::string text, Color fg_color, Color bg_color,
UI_button(const json& j); std::function<void(std::string)> on_click = nullptr);
UI_button(const json &j);
void from_json(const json& j) override;
json to_json() const override;
void click() const override; void from_json(const json &j) override;
private: json to_json() const override;
std::function<void(std::string)> m_on_click = nullptr;
void click() const override;
private:
std::function<void(std::string)> m_on_click = nullptr;
}; };
+7 -7
View File
@@ -1,11 +1,12 @@
#include "UI_checkbox.hpp" #include "UI_checkbox.hpp"
UI_checkbox::UI_checkbox() UI_checkbox::UI_checkbox() : UI_x_boxes(UI_CHECKBOX_TYPE), m_selected(), m_on_change(nullptr)
: UI_x_boxes(UI_CHECKBOX_TYPE), m_selected(), m_on_change(nullptr)
{ {
} }
UI_checkbox::UI_checkbox(std::string id, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options, std::function<void(std::string, std::vector<std::string>)> on_change) UI_checkbox::UI_checkbox(std::string id, std::string text, Color fg_color, Color bg_color,
std::vector<std::string> options,
std::function<void(std::string, std::vector<std::string>)> on_change)
: UI_x_boxes(id, UI_CHECKBOX_TYPE, text, fg_color, bg_color, options), m_selected(), m_on_change(on_change) : UI_x_boxes(id, UI_CHECKBOX_TYPE, text, fg_color, bg_color, options), m_selected(), m_on_change(on_change)
{ {
for (size_t i = 0; i < m_options.size(); i++) for (size_t i = 0; i < m_options.size(); i++)
@@ -14,8 +15,7 @@ UI_checkbox::UI_checkbox(std::string id, std::string text, Color fg_color, Color
} }
} }
UI_checkbox::UI_checkbox(const json& j) : UI_checkbox::UI_checkbox(const json &j) : UI_x_boxes(UI_CHECKBOX_TYPE), m_selected(), m_on_change(nullptr)
UI_x_boxes(UI_CHECKBOX_TYPE), m_selected(), m_on_change(nullptr)
{ {
from_json(j); from_json(j);
} }
@@ -61,10 +61,10 @@ std::vector<std::string> UI_checkbox::selected_text() const
return selected_text; return selected_text;
} }
void UI_checkbox::from_json(const json& j) void UI_checkbox::from_json(const json &j)
{ {
UI_x_boxes::from_json(j); UI_x_boxes::from_json(j);
if (j.contains("selected")) if (j.contains("selected"))
{ {
m_selected.clear(); m_selected.clear();
+17 -15
View File
@@ -1,26 +1,28 @@
#pragma once #pragma once
#include <cstdint>
#include "UI_item.hpp" #include "UI_item.hpp"
#include "UI_x_boxes.hpp" #include "UI_x_boxes.hpp"
#include <cstdint>
#define UI_CHECKBOX_TYPE std::string("UI_checkbox") #define UI_CHECKBOX_TYPE std::string("UI_checkbox")
class UI_checkbox : public UI_x_boxes class UI_checkbox : public UI_x_boxes
{ {
public: public:
UI_checkbox(); UI_checkbox();
UI_checkbox(std::string id, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options, std::function<void(std::string, std::vector<std::string>)> on_change = nullptr); UI_checkbox(std::string id, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options,
UI_checkbox(const json& j); std::function<void(std::string, std::vector<std::string>)> on_change = nullptr);
UI_checkbox(const json &j);
void toggle_selected(size_t selected); void toggle_selected(size_t selected);
void toggle_selected(std::string selected); void toggle_selected(std::string selected);
std::vector<bool> selected() const; std::vector<bool> selected() const;
std::vector<std::string> selected_text() const; std::vector<std::string> selected_text() const;
void from_json(const json& j) override;
json to_json() const override;
private:
std::vector<bool> m_selected;
std::function<void(std::string, std::vector<std::string>)> m_on_change; void from_json(const json &j) override;
json to_json() const override;
private:
std::vector<bool> m_selected;
std::function<void(std::string, std::vector<std::string>)> m_on_change;
}; };
+6 -6
View File
@@ -1,17 +1,17 @@
#include "UI_combobox.hpp" #include "UI_combobox.hpp"
UI_combobox::UI_combobox() UI_combobox::UI_combobox() : UI_x_boxes(UI_COMBOBOX_TYPE)
: UI_x_boxes(UI_COMBOBOX_TYPE)
{ {
} }
UI_combobox::UI_combobox(std::string id, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options, size_t selected, std::function<void(std::string, std::string)> on_change) UI_combobox::UI_combobox(std::string id, std::string text, Color fg_color, Color bg_color,
std::vector<std::string> options, size_t selected,
std::function<void(std::string, std::string)> on_change)
: UI_x_boxes(id, UI_COMBOBOX_TYPE, text, fg_color, bg_color, options), m_selected(selected), m_on_change(on_change) : UI_x_boxes(id, UI_COMBOBOX_TYPE, text, fg_color, bg_color, options), m_selected(selected), m_on_change(on_change)
{ {
} }
UI_combobox::UI_combobox(const json& j) UI_combobox::UI_combobox(const json &j) : UI_x_boxes(UI_COMBOBOX_TYPE), m_on_change(nullptr)
: UI_x_boxes(UI_COMBOBOX_TYPE), m_on_change(nullptr)
{ {
from_json(j); from_json(j);
} }
@@ -49,7 +49,7 @@ std::string UI_combobox::selected_text() const
return m_options[m_selected]; return m_options[m_selected];
} }
void UI_combobox::from_json(const json& j) void UI_combobox::from_json(const json &j)
{ {
UI_x_boxes::from_json(j); UI_x_boxes::from_json(j);
std::string selected_str = j.at("selected"); std::string selected_str = j.at("selected");
+17 -15
View File
@@ -1,27 +1,29 @@
#pragma once #pragma once
#include <functional>
#include "UI_item.hpp" #include "UI_item.hpp"
#include "UI_x_boxes.hpp" #include "UI_x_boxes.hpp"
#include <functional>
#define UI_COMBOBOX_TYPE std::string("UI_combobox") #define UI_COMBOBOX_TYPE std::string("UI_combobox")
class UI_combobox : public UI_x_boxes class UI_combobox : public UI_x_boxes
{ {
public: public:
UI_combobox(); UI_combobox();
UI_combobox(std::string id, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options, size_t selected = 0, std::function<void(std::string, std::string)> on_change = nullptr); UI_combobox(std::string id, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options,
UI_combobox(const json& j); size_t selected = 0, std::function<void(std::string, std::string)> on_change = nullptr);
UI_combobox(const json &j);
void set_selected(size_t selected); void set_selected(size_t selected);
void set_selected(std::string selected) override; void set_selected(std::string selected) override;
size_t selected() const; size_t selected() const;
std::string selected_text() const; std::string selected_text() const;
void from_json(const json& j) override;
json to_json() const override;
private:
size_t m_selected;
std::function<void(std::string, std::string)> m_on_change; void from_json(const json &j) override;
json to_json() const override;
private:
size_t m_selected;
std::function<void(std::string, std::string)> m_on_change;
}; };
+2 -3
View File
@@ -5,8 +5,7 @@ UI_dial::UI_dial(std::string id, std::string text, Color fg_color, Color bg_colo
{ {
} }
UI_dial::UI_dial(const json& j) UI_dial::UI_dial(const json &j) : UI_item(UI_DIAL_TYPE)
: UI_item(UI_DIAL_TYPE)
{ {
from_json(j); from_json(j);
} }
@@ -36,7 +35,7 @@ double UI_dial::max() const
return m_max; return m_max;
} }
void UI_dial::from_json(const json& j) void UI_dial::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
+14 -13
View File
@@ -5,20 +5,21 @@
class UI_dial : public UI_item class UI_dial : public UI_item
{ {
public: public:
UI_dial(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value); UI_dial(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value);
UI_dial(const json& j); UI_dial(const json &j);
void set_value(double value) override; void set_value(double value) override;
double value() const; double value() const;
double min() const; double min() const;
double max() const; double max() const;
void from_json(const json& j) override; void from_json(const json &j) override;
json to_json() const override; json to_json() const override;
private:
double m_min; private:
double m_max; double m_min;
double m_value; double m_max;
double m_value;
}; };
+7 -5
View File
@@ -1,16 +1,18 @@
#include "UI_item.hpp" #include "UI_item.hpp"
UI_item::UI_item(std::string id, std::string type, std::string text, uint8_t text_size, Color fg_color, Color bg_color) UI_item::UI_item(std::string id, std::string type, std::string text, uint8_t text_size, Color fg_color, Color bg_color)
: m_id(id), m_type(type), m_text(text), m_text_size(text_size), m_fg_color(fg_color), m_bg_color(bg_color), enabled(true), visible(true) : m_id(id), m_type(type), m_text(text), m_text_size(text_size), m_fg_color(fg_color), m_bg_color(bg_color),
enabled(true), visible(true)
{ {
} }
UI_item::UI_item(std::string type) UI_item::UI_item(std::string type)
: m_id(""), m_type(type), m_text(""), m_text_size(12), m_fg_color(Color::Black), m_bg_color(Color::White), enabled(true), visible(true) : m_id(""), m_type(type), m_text(""), m_text_size(12), m_fg_color(Color::Black), m_bg_color(Color::White),
enabled(true), visible(true)
{ {
} }
UI_item::UI_item(const json& j) UI_item::UI_item(const json &j)
{ {
from_json(j); from_json(j);
} }
@@ -106,7 +108,7 @@ bool UI_item::is_visible() const
return visible; return visible;
} }
void UI_item::from_json(const json& j) void UI_item::from_json(const json &j)
{ {
if (!is_type(j)) if (!is_type(j))
return; return;
+15 -8
View File
@@ -1,19 +1,20 @@
#pragma once #pragma once
#include <functional> #include "color.hpp"
#include <thread>
#include <cstdint> #include <cstdint>
#include <functional>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <string> #include <string>
#include "color.hpp" #include <thread>
using json = nlohmann::json; using json = nlohmann::json;
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
class UI_item { class UI_item
{
public: public:
UI_item(std::string type); UI_item(std::string type);
UI_item(std::string id, std::string type, std::string text, uint8_t text_size, Color fg_color, Color bg_color); UI_item(std::string id, std::string type, std::string text, uint8_t text_size, Color fg_color, Color bg_color);
UI_item(const json& j); UI_item(const json &j);
std::string id() const; std::string id() const;
std::string type() const; std::string type() const;
@@ -37,13 +38,19 @@ class UI_item {
void set_visible(bool visible); void set_visible(bool visible);
bool is_visible() const; bool is_visible() const;
virtual void from_json(const json& j); virtual void from_json(const json &j);
virtual json to_json() const; virtual json to_json() const;
virtual void click() const {}; virtual void click() const {};
virtual void set_selected(std::string selected) {UNUSED(selected);}; virtual void set_selected(std::string selected)
virtual void set_value(double value) {UNUSED(value);}; {
UNUSED(selected);
};
virtual void set_value(double value)
{
UNUSED(value);
};
protected: protected:
std::string m_id; std::string m_id;
+3 -4
View File
@@ -5,18 +5,17 @@ UI_label::UI_label(std::string id, std::string text, Color fg_color, Color bg_co
{ {
} }
UI_label::UI_label(const json& j) UI_label::UI_label(const json &j) : UI_item(UI_LABEL_TYPE)
: UI_item(UI_LABEL_TYPE)
{ {
from_json(j); from_json(j);
} }
void UI_label::from_json(const json& j) void UI_label::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
} }
json UI_label::to_json() const json UI_label::to_json() const
{ {
return UI_item::to_json(); return UI_item::to_json();
} }
+4 -4
View File
@@ -1,15 +1,15 @@
#pragma once #pragma once
#include <string>
#include "UI_item.hpp" #include "UI_item.hpp"
#include <string>
#define UI_LABEL_TYPE std::string("UI_label") #define UI_LABEL_TYPE std::string("UI_label")
class UI_label : public UI_item class UI_label : public UI_item
{ {
public: public:
UI_label(std::string id, std::string text, Color fg_color, Color bg_color); UI_label(std::string id, std::string text, Color fg_color, Color bg_color);
UI_label(const json& j); UI_label(const json &j);
void from_json(const json& j) override; void from_json(const json &j) override;
json to_json() const override; json to_json() const override;
}; };
+5 -8
View File
@@ -1,14 +1,11 @@
#include "UI_led.hpp" #include "UI_led.hpp"
UI_led::UI_led(std::string id, std::string text, Color fg_color, Color bg_color, Color led_color) : UI_led::UI_led(std::string id, std::string text, Color fg_color, Color bg_color, Color led_color)
UI_item(id, UI_LED_TYPE, text, 12, fg_color, bg_color), : UI_item(id, UI_LED_TYPE, text, 12, fg_color, bg_color), m_led_color(led_color)
m_led_color(led_color)
{ {
} }
UI_led::UI_led(const json& j) : UI_led::UI_led(const json &j) : UI_item(UI_LED_TYPE)
UI_item(UI_LED_TYPE)
{ {
from_json(j); from_json(j);
} }
@@ -23,7 +20,7 @@ void UI_led::set_led_color(Color led_color)
m_led_color = led_color; m_led_color = led_color;
} }
void UI_led::from_json(const json& j) void UI_led::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
std::string color; std::string color;
@@ -35,5 +32,5 @@ json UI_led::to_json() const
{ {
json j = UI_item::to_json(); json j = UI_item::to_json();
j["led_color"] = m_led_color.to_hex(); j["led_color"] = m_led_color.to_hex();
return j; return j;
} }
+6 -5
View File
@@ -1,20 +1,21 @@
#pragma once #pragma once
#include <string>
#include "UI_item.hpp" #include "UI_item.hpp"
#include <string>
#define UI_LED_TYPE std::string("UI_led") #define UI_LED_TYPE std::string("UI_led")
class UI_led : public UI_item class UI_led : public UI_item
{ {
public: public:
UI_led(std::string id, std::string text, Color fg_color, Color bg_color, Color led_color); UI_led(std::string id, std::string text, Color fg_color, Color bg_color, Color led_color);
UI_led(const json& j); UI_led(const json &j);
Color led_color() const; Color led_color() const;
void set_led_color(Color led_color); void set_led_color(Color led_color);
void from_json(const json& j) override; void from_json(const json &j) override;
json to_json() const override; json to_json() const override;
private:
private:
Color m_led_color; Color m_led_color;
}; };
+4 -5
View File
@@ -1,14 +1,13 @@
#include "UI_slider.hpp" #include "UI_slider.hpp"
UI_slider::UI_slider(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value, std::function<void(std::string, double)> on_change) UI_slider::UI_slider(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max,
double value, std::function<void(std::string, double)> on_change)
: UI_item(id, UI_SLIDER_TYPE, text, 12, fg_color, bg_color), m_min(min), m_max(max), m_value(value) : UI_item(id, UI_SLIDER_TYPE, text, 12, fg_color, bg_color), m_min(min), m_max(max), m_value(value)
{ {
this->m_on_change = on_change; this->m_on_change = on_change;
} }
UI_slider::UI_slider(const json& j) UI_slider::UI_slider(const json &j) : UI_item(UI_SLIDER_TYPE), m_on_change(nullptr)
: UI_item(UI_SLIDER_TYPE),
m_on_change(nullptr)
{ {
from_json(j); from_json(j);
} }
@@ -42,7 +41,7 @@ double UI_slider::max() const
return m_max; return m_max;
} }
void UI_slider::from_json(const json& j) void UI_slider::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
+16 -14
View File
@@ -5,22 +5,24 @@
class UI_slider : public UI_item class UI_slider : public UI_item
{ {
public: public:
UI_slider(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value, std::function<void(std::string, double)> on_change = nullptr); UI_slider(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value,
UI_slider(const json& j); std::function<void(std::string, double)> on_change = nullptr);
UI_slider(const json &j);
void set_value(double value) override; void set_value(double value) override;
double value() const; double value() const;
double min() const; double min() const;
double max() const; double max() const;
void from_json(const json& j) override; void from_json(const json &j) override;
json to_json() const override; json to_json() const override;
private:
double m_min;
double m_max;
double m_value;
std::function<void(std::string, double)> m_on_change; private:
double m_min;
double m_max;
double m_value;
std::function<void(std::string, double)> m_on_change;
}; };
+4 -5
View File
@@ -1,13 +1,12 @@
#include "UI_textbox.hpp" #include "UI_textbox.hpp"
UI_textbox::UI_textbox(std::string id, std::string hint, Color fg_color, Color bg_color, std::function<void(std::string, std::string)> on_change) UI_textbox::UI_textbox(std::string id, std::string hint, Color fg_color, Color bg_color,
std::function<void(std::string, std::string)> on_change)
: UI_item(id, UI_TEXTBOX_TYPE, "", 0, fg_color, bg_color), m_hint(hint), m_on_change(on_change) : UI_item(id, UI_TEXTBOX_TYPE, "", 0, fg_color, bg_color), m_hint(hint), m_on_change(on_change)
{ {
} }
UI_textbox::UI_textbox(const json& j) UI_textbox::UI_textbox(const json &j) : UI_item(UI_TEXTBOX_TYPE), m_on_change(nullptr)
: UI_item(UI_TEXTBOX_TYPE),
m_on_change(nullptr)
{ {
from_json(j); from_json(j);
} }
@@ -33,7 +32,7 @@ std::string UI_textbox::hint() const
return m_hint; return m_hint;
} }
void UI_textbox::from_json(const json& j) void UI_textbox::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
m_hint = j.at("hint"); m_hint = j.at("hint");
+8 -6
View File
@@ -1,23 +1,25 @@
#pragma once #pragma once
#include <string>
#include "UI_item.hpp" #include "UI_item.hpp"
#include <string>
#define UI_TEXTBOX_TYPE std::string("UI_textbox") #define UI_TEXTBOX_TYPE std::string("UI_textbox")
class UI_textbox : public UI_item class UI_textbox : public UI_item
{ {
public: public:
UI_textbox(std::string id, std::string hint, Color fg_color, Color bg_color, std::function<void(std::string, std::string)> on_change = nullptr); UI_textbox(std::string id, std::string hint, Color fg_color, Color bg_color,
UI_textbox(const json& j); std::function<void(std::string, std::string)> on_change = nullptr);
UI_textbox(const json &j);
void set_text(std::string text) override; void set_text(std::string text) override;
void set_hint(std::string hint); void set_hint(std::string hint);
std::string hint() const; std::string hint() const;
void from_json(const json& j) override; void from_json(const json &j) override;
json to_json() const override; json to_json() const override;
private:
private:
std::string m_hint; std::string m_hint;
std::function<void(std::string, std::string)> m_on_change; std::function<void(std::string, std::string)> m_on_change;
}; };
+7 -7
View File
@@ -1,12 +1,12 @@
#include "UI_thermo.hpp" #include "UI_thermo.hpp"
UI_thermo::UI_thermo(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value) UI_thermo::UI_thermo(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max,
double value)
: UI_item(id, UI_THERMO_TYPE, text, 12, fg_color, bg_color), m_min(min), m_max(max), m_value(value) : UI_item(id, UI_THERMO_TYPE, text, 12, fg_color, bg_color), m_min(min), m_max(max), m_value(value)
{ {
} }
UI_thermo::UI_thermo(const json& j) UI_thermo::UI_thermo(const json &j) : UI_item(UI_THERMO_TYPE)
: UI_item(UI_THERMO_TYPE)
{ {
from_json(j); from_json(j);
} }
@@ -50,7 +50,7 @@ void UI_thermo::add_color_stop(double value, Color color)
{ {
if (value <= 0 || value >= 1) if (value <= 0 || value >= 1)
return; return;
this->m_color_map[value] = color; this->m_color_map[value] = color;
} }
@@ -80,7 +80,7 @@ void UI_thermo::remove_color_stop_normalized(double value)
this->m_color_map.erase(normalized); this->m_color_map.erase(normalized);
} }
void UI_thermo::from_json(const json& j) void UI_thermo::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
@@ -88,7 +88,7 @@ void UI_thermo::from_json(const json& j)
this->m_max = j.at("max"); this->m_max = j.at("max");
this->m_value = j.at("value"); this->m_value = j.at("value");
this->m_color_map.clear(); this->m_color_map.clear();
for (auto& i : j["color_map"]) for (auto &i : j["color_map"])
{ {
double k = i.at("key"); double k = i.at("key");
std::string c = i.at("value"); std::string c = i.at("value");
@@ -103,7 +103,7 @@ json UI_thermo::to_json() const
j["max"] = this->m_max; j["max"] = this->m_max;
j["value"] = this->m_value; j["value"] = this->m_value;
j["color_map"] = json::array(); j["color_map"] = json::array();
for (auto& [key, value] : this->m_color_map) for (auto &[key, value] : this->m_color_map)
{ {
json item = json::object(); json item = json::object();
item["key"] = key; item["key"] = key;
+21 -20
View File
@@ -6,28 +6,29 @@
// TODO: Add color scale // TODO: Add color scale
class UI_thermo : public UI_item class UI_thermo : public UI_item
{ {
public: public:
UI_thermo(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value); UI_thermo(std::string id, std::string text, Color fg_color, Color bg_color, double min, double max, double value);
UI_thermo(const json& j); UI_thermo(const json &j);
void set_value(double value) override; void set_value(double value) override;
double value() const; double value() const;
double min() const; double min() const;
double max() const; double max() const;
void set_start_color(Color color); void set_start_color(Color color);
void set_end_color(Color color); void set_end_color(Color color);
void add_color_stop(double value, Color color); void add_color_stop(double value, Color color);
void add_color_stop_normalized(double value, Color color); void add_color_stop_normalized(double value, Color color);
void remove_color_stop(double value); void remove_color_stop(double value);
void remove_color_stop_normalized(double value); void remove_color_stop_normalized(double value);
void from_json(const json& j) override; void from_json(const json &j) override;
json to_json() const override; json to_json() const override;
private:
double m_min; private:
double m_max; double m_min;
double m_value; double m_max;
std::unordered_map<double, Color> m_color_map; double m_value;
std::unordered_map<double, Color> m_color_map;
}; };
+4 -4
View File
@@ -1,16 +1,16 @@
#include "UI_x_boxes.hpp" #include "UI_x_boxes.hpp"
UI_x_boxes::UI_x_boxes(std::string type) UI_x_boxes::UI_x_boxes(std::string type) : UI_item(type), m_options()
: UI_item(type), m_options()
{ {
} }
UI_x_boxes::UI_x_boxes(std::string id, std::string type, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options) UI_x_boxes::UI_x_boxes(std::string id, std::string type, std::string text, Color fg_color, Color bg_color,
std::vector<std::string> options)
: UI_item(id, type, text, 12, fg_color, bg_color), m_options(options) : UI_item(id, type, text, 12, fg_color, bg_color), m_options(options)
{ {
} }
void UI_x_boxes::from_json(const json& j) void UI_x_boxes::from_json(const json &j)
{ {
UI_item::from_json(j); UI_item::from_json(j);
if (j.contains("options")) if (j.contains("options"))
+9 -7
View File
@@ -4,12 +4,14 @@
class UI_x_boxes : public UI_item class UI_x_boxes : public UI_item
{ {
public: public:
UI_x_boxes(std::string type); UI_x_boxes(std::string type);
UI_x_boxes(std::string id, std::string type, std::string text, Color fg_color, Color bg_color, std::vector<std::string> options); UI_x_boxes(std::string id, std::string type, std::string text, Color fg_color, Color bg_color,
std::vector<std::string> options);
void from_json(const json& j) override; void from_json(const json &j) override;
json to_json() const override; json to_json() const override;
protected:
std::vector<std::string> m_options; protected:
std::vector<std::string> m_options;
}; };
+1 -1
View File
@@ -1,5 +1,5 @@
#include "gtest/gtest.h"
#include "UI.hpp" #include "UI.hpp"
#include "gtest/gtest.h"
#include <iostream> #include <iostream>
#define UNUSED(x) (void)(x) #define UNUSED(x) (void)(x)
+24 -17
View File
@@ -3,32 +3,36 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include "spdlog/spdlog.h"
#include "spdlog/async.h" #include "spdlog/async.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h" #include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
#include "message_parser.hpp"
#include "simulators.hpp" #include "simulators.hpp"
#include "websocket.hpp" #include "websocket.hpp"
#include "message_parser.hpp"
class Spdlog_buffer : public std::stringbuf class Spdlog_buffer : public std::stringbuf
{ {
public: public:
Spdlog_buffer(std::function <void(std::string)> log_function) : log_function(log_function) {} Spdlog_buffer(std::function<void(std::string)> log_function) : log_function(log_function)
int sync() { {
}
int sync()
{
std::string str = this->str(); std::string str = this->str();
str.pop_back(); str.pop_back();
log_function(str); log_function(str);
this->str(""); this->str("");
return 0; return 0;
} }
private:
std::function <void(std::string)> log_function; private:
std::function<void(std::string)> log_function;
}; };
Simulators* g_simulators; Simulators *g_simulators;
Websocket* g_web_socket; Websocket *g_web_socket;
Spdlog_buffer g_info_buffer([](std::string message) { spdlog::info(message); }); Spdlog_buffer g_info_buffer([](std::string message) { spdlog::info(message); });
Spdlog_buffer g_error_buffer([](std::string message) { spdlog::error(message); }); Spdlog_buffer g_error_buffer([](std::string message) { spdlog::error(message); });
std::ostream g_out(&g_info_buffer); std::ostream g_out(&g_info_buffer);
@@ -52,10 +56,11 @@ void int_handler(int s)
void init_logger() void init_logger()
{ {
spdlog::init_thread_pool(8192, 1); spdlog::init_thread_pool(8192, 1);
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt >(); auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("log-sim_us.txt", 1024*1024*10, 3); auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("log-sim_us.txt", 1024 * 1024 * 10, 3);
std::vector<spdlog::sink_ptr> sinks {stdout_sink, rotating_sink}; std::vector<spdlog::sink_ptr> sinks{stdout_sink, rotating_sink};
auto logger = std::make_shared<spdlog::async_logger>("sim_us", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block); auto logger = std::make_shared<spdlog::async_logger>("sim_us", sinks.begin(), sinks.end(), spdlog::thread_pool(),
spdlog::async_overflow_policy::block);
spdlog::set_default_logger(logger); spdlog::set_default_logger(logger);
spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v"); spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
spdlog::flush_every(std::chrono::seconds(3)); spdlog::flush_every(std::chrono::seconds(3));
@@ -80,14 +85,16 @@ int main(void)
spdlog::info("Starting server"); spdlog::info("Starting server");
Simulators simulators; Simulators simulators;
g_simulators = &simulators; g_simulators = &simulators;
Websocket web_socket(9002, &g_out, &g_err, [](std::string message) { return message_parser(message); }, []() { return g_simulators->changed_UI_items().dump(); }); Websocket web_socket(
9002, &g_out, &g_err, [](std::string message) { return message_parser(message); },
[]() { return g_simulators->changed_UI_items().dump(); });
g_web_socket = &web_socket; g_web_socket = &web_socket;
// Start the message processor and broadcast processor in separate threads // Start the message processor and broadcast processor in separate threads
std::thread message_processor_thread(std::bind(&Websocket::process_messages, &web_socket)); std::thread message_processor_thread(std::bind(&Websocket::process_messages, &web_socket));
std::thread broadcast_processor_thred(std::bind(&Websocket::process_broadcast, &web_socket)); std::thread broadcast_processor_thred(std::bind(&Websocket::process_broadcast, &web_socket));
// Run the asio loop with the main thread // Run the asio loop with the main thread
web_socket.run(); web_socket.run();
+62 -60
View File
@@ -1,8 +1,8 @@
#include "message_parser.hpp" #include "message_parser.hpp"
#include <magic_enum.hpp>
#include <iostream> #include <iostream>
#include <magic_enum.hpp>
extern Simulators* g_simulators; extern Simulators *g_simulators;
std::string message_parser(std::string message) std::string message_parser(std::string message)
{ {
@@ -31,36 +31,37 @@ json command_parser(json command)
Command cmd = magic_enum::enum_cast<Command>(type).value_or(Command::end); Command cmd = magic_enum::enum_cast<Command>(type).value_or(Command::end);
switch (cmd) switch (cmd)
{ {
case Command::get_UI_element: case Command::get_UI_element:
spdlog::info("Command {}: {}", type, std::string(command.at("id"))); spdlog::info("Command {}: {}", type, std::string(command.at("id")));
j["response"]["type"] = type; j["response"]["type"] = type;
j["response"]["UI_item"] = g_simulators->invoke_active_simulator()->get_UI_item(command.at("id"))->to_json(); j["response"]["UI_item"] =
break; g_simulators->invoke_active_simulator()->get_UI_item(command.at("id"))->to_json();
case Command::get_UI_elements: break;
spdlog::info("Command {}", type); case Command::get_UI_elements:
j["response"]["type"] = type; spdlog::info("Command {}", type);
j["response"]["UI_items"] = g_simulators->invoke_active_simulator()->get_UI_items()["UI_items"]; j["response"]["type"] = type;
break; j["response"]["UI_items"] = g_simulators->invoke_active_simulator()->get_UI_items()["UI_items"];
case Command::switch_simulator: break;
spdlog::info("Command {} to {}", type, std::string(command.at("name"))); case Command::switch_simulator:
g_simulators->switch_simulator(command.at("name")); spdlog::info("Command {} to {}", type, std::string(command.at("name")));
j["response"]["type"] = type; g_simulators->switch_simulator(command.at("name"));
break; j["response"]["type"] = type;
case Command::get_active_simulator_name: break;
spdlog::info("Command {}", type); case Command::get_active_simulator_name:
j["response"]["type"] = type; spdlog::info("Command {}", type);
j["response"]["name"] = g_simulators->active_simulator_name(); j["response"]["type"] = type;
break; j["response"]["name"] = g_simulators->active_simulator_name();
case Command::get_simulators: break;
spdlog::info("Command {}", type); case Command::get_simulators:
j["response"]["type"] = type; spdlog::info("Command {}", type);
j["response"]["simulators"] = g_simulators->list_simulators(); j["response"]["type"] = type;
break; j["response"]["simulators"] = g_simulators->list_simulators();
default: break;
break; default:
break;
} }
} }
catch(const json::exception& e) catch (const json::exception &e)
{ {
spdlog::error(e.what()); spdlog::error(e.what());
} }
@@ -80,39 +81,40 @@ void event_handler(json event)
return; return;
} }
switch(e) switch (e)
{ {
case Event::clicked: case Event::clicked: {
{ spdlog::debug("Event {}: {}", type, std::string(event.at("id")));
spdlog::debug("Event {}: {}", type, std::string(event.at("id"))); g_simulators->invoke_active_simulator()->get_UI_item(std::string(event.at("id")))->click();
g_simulators->invoke_active_simulator()->get_UI_item(std::string(event.at("id")))->click(); break;
break; }
} case Event::value_changed: {
case Event::value_changed: spdlog::debug("Event {}: {} {}", type, std::string(event.at("id")), (double)(event["value"]));
{ g_simulators->invoke_active_simulator()
spdlog::debug("Event {}: {} {}", type, std::string(event.at("id")), (double)(event["value"])); ->get_UI_item(std::string(event.at("id")))
g_simulators->invoke_active_simulator()->get_UI_item(std::string(event.at("id")))->set_value((double)event.at("value")); ->set_value((double)event.at("value"));
break; break;
} }
case Event::text_changed: case Event::text_changed: {
{ spdlog::debug("Event {}: {} {}", type, std::string(event.at("id")), std::string(event.at("text")));
spdlog::debug("Event {}: {} {}", type, std::string(event.at("id")), std::string(event.at("text"))); g_simulators->invoke_active_simulator()
g_simulators->invoke_active_simulator()->get_UI_item(std::string(event.at("id")))->set_text(std::string(event.at("text"))); ->get_UI_item(std::string(event.at("id")))
break; ->set_text(std::string(event.at("text")));
} break;
case Event::selected: }
{ case Event::selected: {
spdlog::debug("Event {}: {} {}", type, std::string(event.at("id")), std::string(event.at("selected"))); spdlog::debug("Event {}: {} {}", type, std::string(event.at("id")), std::string(event.at("selected")));
g_simulators->invoke_active_simulator()->get_UI_item(std::string(event.at("id")))->set_selected(std::string(event.at("selected"))); g_simulators->invoke_active_simulator()
break; ->get_UI_item(std::string(event.at("id")))
} ->set_selected(std::string(event.at("selected")));
default: break;
{ }
break; default: {
} break;
}
} }
} }
catch(const json::exception& e) catch (const json::exception &e)
{ {
spdlog::error(e.what()); spdlog::error(e.what());
} }
+27 -15
View File
@@ -1,20 +1,23 @@
#include "simulator_base.hpp" #include "simulator_base.hpp"
Simulator_base::Simulator_base(std::string name, std::chrono::milliseconds interval) Simulator_base::Simulator_base(std::string name, std::chrono::milliseconds interval)
: m_name(name), m_timer([this]{ timer(); }), m_interval(interval) : m_name(name), m_timer([this] { timer(); }), m_interval(interval)
{ {
} }
std::string Simulator_base::name() const { std::string Simulator_base::name() const
{
// Get the name of the simulator // Get the name of the simulator
return m_name; return m_name;
} }
bool Simulator_base::is_ui_id_unique(std::string id) const { bool Simulator_base::is_ui_id_unique(std::string id) const
{
// Check if the UI name is unique // Check if the UI name is unique
for (UI_item* item : m_UI_items) { for (UI_item *item : m_UI_items)
if (item->id() == id) { {
if (item->id() == id)
{
return false; return false;
} }
} }
@@ -22,48 +25,57 @@ bool Simulator_base::is_ui_id_unique(std::string id) const {
return true; return true;
} }
void Simulator_base::add_UI_item(UI_item* item) { void Simulator_base::add_UI_item(UI_item *item)
{
// Add a UI item to the simulator // Add a UI item to the simulator
if (is_ui_id_unique(item->id()) == false) { if (is_ui_id_unique(item->id()) == false)
{
throw std::runtime_error("UI item id " + item->id() + " is not unique"); throw std::runtime_error("UI item id " + item->id() + " is not unique");
} }
m_UI_items_map[item->id()] = item; m_UI_items_map[item->id()] = item;
m_UI_items.push_back(item); m_UI_items.push_back(item);
} }
json Simulator_base::get_UI_items() const { json Simulator_base::get_UI_items() const
{
// Get the UI items // Get the UI items
json items; json items;
items["name"] = m_name; items["name"] = m_name;
for (UI_item* item : m_UI_items) { for (UI_item *item : m_UI_items)
{
items["UI_items"].push_back(item->to_json()); items["UI_items"].push_back(item->to_json());
} }
return items; return items;
} }
UI_item* Simulator_base::get_UI_item(std::string id) const { UI_item *Simulator_base::get_UI_item(std::string id) const
{
// Get a UI item by id // Get a UI item by id
return m_UI_items_map.at(id); return m_UI_items_map.at(id);
} }
void Simulator_base::run() { void Simulator_base::run()
{
// Start the timer // Start the timer
m_timer.setInterval(m_interval); m_timer.setInterval(m_interval);
run_at_startup(); run_at_startup();
} }
void Simulator_base::stop() { void Simulator_base::stop()
{
// Stop the simulator // Stop the simulator
m_timer.stop(); m_timer.stop();
} }
void Simulator_base::shutdown() { void Simulator_base::shutdown()
{
// Shutdown the simulator // Shutdown the simulator
system("shutdown -h now"); system("shutdown -h now");
} }
void Simulator_base::reboot() { void Simulator_base::reboot()
{
// Reboot the simulator // Reboot the simulator
system("reboot"); system("reboot");
} }
+76 -74
View File
@@ -1,90 +1,92 @@
#pragma once #pragma once
#include "UI.hpp" #include "UI.hpp"
#include "timer.hpp"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
#include "timer.hpp"
class Simulator_base { class Simulator_base
{
public: public:
/** /**
* @brief Construct a new Simulator_base object * @brief Construct a new Simulator_base object
* *
* @param name The name of the simulator * @param name The name of the simulator
* @param interval The interval of the timer (default is 100ms) * @param interval The interval of the timer (default is 100ms)
*/ */
Simulator_base(std::string name, std::chrono::milliseconds interval = std::chrono::milliseconds(100)); Simulator_base(std::string name, std::chrono::milliseconds interval = std::chrono::milliseconds(100));
/** /**
* @brief Returns the name of the simulator * @brief Returns the name of the simulator
* *
* @return std::string The name of the simulator * @return std::string The name of the simulator
*/ */
std::string name() const; std::string name() const;
/** /**
* @brief This function checks if the UI id is unique * @brief This function checks if the UI id is unique
* (hence not already pushed in with the add_UI_item function) * (hence not already pushed in with the add_UI_item function)
* *
* @param id The id to check * @param id The id to check
* @return true The id is unique * @return true The id is unique
* @return false The id is already in use * @return false The id is already in use
*/ */
bool is_ui_id_unique(std::string id) const; bool is_ui_id_unique(std::string id) const;
/** /**
* @brief This function adds a UI item to the simulator * @brief This function adds a UI item to the simulator
* only if the id is unique * only if the id is unique
* Use this function only in the constructor of the simulator * Use this function only in the constructor of the simulator
* *
* @param item The UI item to add * @param item The UI item to add
*/ */
void add_UI_item(UI_item* item); void add_UI_item(UI_item *item);
/** /**
* @brief Get the UI items object * @brief Get the UI items object
* *
* @return json The UI items in json format * @return json The UI items in json format
*/ */
json get_UI_items() const; json get_UI_items() const;
/** /**
* @brief Get the UI item object by id * @brief Get the UI item object by id
* *
* @param id The id of the UI item * @param id The id of the UI item
* @return UI_item* A pointer to the UI item object * @return UI_item* A pointer to the UI item object
*/ */
UI_item* get_UI_item(std::string id) const; UI_item *get_UI_item(std::string id) const;
/** /**
* @brief Run the simulator * @brief Run the simulator
*/ */
void run(); void run();
/** /**
* @brief Stop the simulator * @brief Stop the simulator
*/ */
void stop(); void stop();
/** /**
* @brief Timer function * @brief Timer function
* This function is called every time the timer ticks * This function is called every time the timer ticks
* Override this function in the derived class * Override this function in the derived class
*/ */
virtual void timer() {}; virtual void timer() {};
/** /**
* @brief Run at startup * @brief Run at startup
* This function is called at startup * This function is called at startup
* Override this function in the derived class * Override this function in the derived class
*/ */
virtual void run_at_startup() {}; virtual void run_at_startup() {};
void shutdown(); void shutdown();
void reboot(); void reboot();
protected:
std::string m_name; protected:
std::vector<UI_item*> m_UI_items; std::string m_name;
std::map<std::string, UI_item*> m_UI_items_map; std::vector<UI_item *> m_UI_items;
Timer m_timer; std::map<std::string, UI_item *> m_UI_items_map;
std::chrono::milliseconds m_interval; Timer m_timer;
std::chrono::milliseconds m_interval;
}; };
+9 -9
View File
@@ -1,7 +1,7 @@
#include "simulators.hpp" #include "simulators.hpp"
#include <unordered_set>
#include "test_sim.hpp"
#include "can_debugger.hpp" #include "can_debugger.hpp"
#include "test_sim.hpp"
#include <unordered_set>
Simulators::Simulators() Simulators::Simulators()
{ {
@@ -66,14 +66,14 @@ void Simulators::switch_simulator(std::string name)
std::vector<std::string> Simulators::list_simulators() const std::vector<std::string> Simulators::list_simulators() const
{ {
std::vector<std::string> names; std::vector<std::string> names;
for (const auto& simulator : this->m_simulators) for (const auto &simulator : this->m_simulators)
{ {
names.push_back(simulator.first); names.push_back(simulator.first);
} }
return names; return names;
} }
Simulator_base* Simulators::invoke_active_simulator() Simulator_base *Simulators::invoke_active_simulator()
{ {
std::lock_guard<std::mutex> lock(m_mutex); std::lock_guard<std::mutex> lock(m_mutex);
if (this->m_simulators.empty()) if (this->m_simulators.empty())
@@ -84,7 +84,7 @@ Simulator_base* Simulators::invoke_active_simulator()
{ {
return nullptr; return nullptr;
} }
m_before = this->m_simulators.at(m_current_simulator)->get_UI_items(); m_before = this->m_simulators.at(m_current_simulator)->get_UI_items();
return this->m_simulators.at(m_current_simulator).get(); return this->m_simulators.at(m_current_simulator).get();
@@ -105,7 +105,7 @@ json Simulators::changed_UI_items()
json after = this->m_simulators.at(m_current_simulator)->get_UI_items(); json after = this->m_simulators.at(m_current_simulator)->get_UI_items();
json changed; json changed;
changed["event"]["type"] = "UI_changed"; changed["event"]["type"] = "UI_changed";
json diff = json::diff(m_before, after); json diff = json::diff(m_before, after);
if (diff.empty()) if (diff.empty())
@@ -121,18 +121,18 @@ json Simulators::changed_UI_items()
try try
{ {
for (auto& item : diff) for (auto &item : diff)
{ {
std::string path = item["path"]; std::string path = item["path"];
size_t index = std::stoul(path.substr(10, path.find("/", 10) - 10)); size_t index = std::stoul(path.substr(10, path.find("/", 10) - 10));
if (addedIndices.find(index) != addedIndices.end()) if (addedIndices.find(index) != addedIndices.end())
continue; continue;
changed["event"]["UI_items"].push_back(after["UI_items"][index]); changed["event"]["UI_items"].push_back(after["UI_items"][index]);
addedIndices.insert(index); addedIndices.insert(index);
} }
} }
catch(const std::exception& e) catch (const std::exception &e)
{ {
spdlog::error(e.what()); spdlog::error(e.what());
} }
+18 -16
View File
@@ -1,25 +1,27 @@
#pragma once #pragma once
#include <memory>
#include <map> #include <map>
#include <memory>
#include <mutex> #include <mutex>
#include "simulator_base.hpp" #include "simulator_base.hpp"
#define INSERT_SIMULATOR(type) m_simulators.insert(std::make_pair(type().name(), std::make_unique<type>())); #define INSERT_SIMULATOR(type) m_simulators.insert(std::make_pair(type().name(), std::make_unique<type>()));
class Simulators { class Simulators
public: {
Simulators(); public:
std::string active_simulator_name() const; Simulators();
void run(); std::string active_simulator_name() const;
void stop(); void run();
void switch_simulator(std::string name); void stop();
std::vector<std::string> list_simulators() const; void switch_simulator(std::string name);
Simulator_base* invoke_active_simulator(); std::vector<std::string> list_simulators() const;
json changed_UI_items(); Simulator_base *invoke_active_simulator();
private: json changed_UI_items();
std::map<std::string, std::unique_ptr<Simulator_base>> m_simulators;
std::string m_current_simulator = ""; private:
std::mutex m_mutex; std::map<std::string, std::unique_ptr<Simulator_base>> m_simulators;
json m_before; std::string m_current_simulator = "";
std::mutex m_mutex;
json m_before;
}; };
+30 -31
View File
@@ -1,9 +1,8 @@
#include "websocket.hpp" #include "websocket.hpp"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
Websocket::Websocket(uint16_t port, std::ostream* out, std::ostream* err, Websocket::Websocket(uint16_t port, std::ostream *out, std::ostream *err,
std::function<std::string(std::string)> on_message, std::function<std::string(std::string)> on_message, std::function<std::string()> on_update)
std::function<std::string()> on_update)
: m_on_message(on_message), m_on_update(on_update), m_port(port) : m_on_message(on_message), m_on_update(on_update), m_port(port)
{ {
// Set logging settings // Set logging settings
@@ -11,10 +10,8 @@ Websocket::Websocket(uint16_t port, std::ostream* out, std::ostream* err,
m_server.get_elog().set_custom(err != &std::cerr); m_server.get_elog().set_custom(err != &std::cerr);
m_server.get_alog().set_ostream(out); m_server.get_alog().set_ostream(out);
m_server.get_elog().set_ostream(err); m_server.get_elog().set_ostream(err);
m_server.set_access_channels(websocketpp::log::alevel::connect + m_server.set_access_channels(websocketpp::log::alevel::connect + websocketpp::log::alevel::disconnect);
websocketpp::log::alevel::disconnect); m_server.clear_access_channels(websocketpp::log::alevel::frame_payload + websocketpp::log::alevel::frame_header);
m_server.clear_access_channels(websocketpp::log::alevel::frame_payload +
websocketpp::log::alevel::frame_header);
// Initialize Asio // Initialize Asio
m_server.init_asio(); m_server.init_asio();
@@ -35,10 +32,14 @@ void Websocket::run()
m_server.start_accept(); m_server.start_accept();
// Start the ASIO io_service run loop // Start the ASIO io_service run loop
m_server.run(); m_server.run();
} catch (websocketpp::exception const& e) { }
catch (websocketpp::exception const &e)
{
spdlog::critical("{}", e.what()); spdlog::critical("{}", e.what());
exit(1); exit(1);
} catch (...) { }
catch (...)
{
spdlog::critical("other exception"); spdlog::critical("other exception");
exit(1); exit(1);
} }
@@ -94,31 +95,29 @@ void Websocket::process_messages()
lock.unlock(); lock.unlock();
switch (a.type) { switch (a.type)
case SUBSCRIBE: {
case SUBSCRIBE: {
std::lock_guard<std::mutex> guard(m_connection_lock);
m_connections.insert(a.hdl);
}
break;
case UNSUBSCRIBE: {
std::lock_guard<std::mutex> guard(m_connection_lock);
m_connections.erase(a.hdl);
}
break;
case MESSAGE: {
std::string response = m_on_message(a.msg->get_payload());
if (response.empty() || response == "{}")
{ {
std::lock_guard<std::mutex> guard(m_connection_lock); continue;
m_connections.insert(a.hdl);
} }
m_server.send(a.hdl, response, websocketpp::frame::opcode::TEXT);
}
break;
default:
break; break;
case UNSUBSCRIBE:
{
std::lock_guard<std::mutex> guard(m_connection_lock);
m_connections.erase(a.hdl);
}
break;
case MESSAGE:
{
std::string response = m_on_message(a.msg->get_payload());
if (response.empty() || response == "{}")
{
continue;
}
m_server.send(a.hdl, response, websocketpp::frame::opcode::TEXT);
}
break;
default:
break;
} }
} }
} }
+19 -11
View File
@@ -16,17 +16,22 @@ using websocketpp::lib::placeholders::_2;
* on_message queue send to all channels * on_message queue send to all channels
*/ */
enum action_type { enum action_type
{
SUBSCRIBE, SUBSCRIBE,
UNSUBSCRIBE, UNSUBSCRIBE,
MESSAGE, MESSAGE,
BROADCAST BROADCAST
}; };
struct action { struct action
action(action_type t, websocketpp::connection_hdl h) : type(t), hdl(h) {} {
action(action_type t, websocketpp::connection_hdl h, Server::message_ptr m) action(action_type t, websocketpp::connection_hdl h) : type(t), hdl(h)
: type(t), hdl(h), msg(m) {} {
}
action(action_type t, websocketpp::connection_hdl h, Server::message_ptr m) : type(t), hdl(h), msg(m)
{
}
action_type type; action_type type;
websocketpp::connection_hdl hdl; websocketpp::connection_hdl hdl;
@@ -35,22 +40,25 @@ struct action {
class Websocket class Websocket
{ {
public: public:
Websocket(uint16_t port, std::ostream* out, std::ostream* err, std::function<std::string(std::string)> on_message, std::function<std::string()> on_update); Websocket(uint16_t port, std::ostream *out, std::ostream *err, std::function<std::string(std::string)> on_message,
std::function<std::string()> on_update);
void run(); void run();
void stop(); void stop();
void process_messages(); void process_messages();
void process_broadcast(); void process_broadcast();
private:
private:
void on_open(websocketpp::connection_hdl hdl); void on_open(websocketpp::connection_hdl hdl);
void on_close(websocketpp::connection_hdl hdl); void on_close(websocketpp::connection_hdl hdl);
void on_message(websocketpp::connection_hdl hdl, Server::message_ptr msg); void on_message(websocketpp::connection_hdl hdl, Server::message_ptr msg);
private:
private:
std::function<std::string(std::string)> m_on_message; std::function<std::string(std::string)> m_on_message;
std::function<std::string()> m_on_update; std::function<std::string()> m_on_update;
Server m_server; Server m_server;
uint16_t m_port; uint16_t m_port;
typedef std::set<websocketpp::connection_hdl,std::owner_less<websocketpp::connection_hdl>> con_list; typedef std::set<websocketpp::connection_hdl, std::owner_less<websocketpp::connection_hdl>> con_list;
con_list m_connections; con_list m_connections;
std::queue<action> m_actions; std::queue<action> m_actions;