7#include <freertos/FreeRTOS.h>
8#include <freertos/timers.h>
45 void begin(rb::Protocol*
protocol,
int cols = 12,
int rows = 18,
bool enableSplitting =
true);
52 rb::Protocol*
begin(
const char* owner,
const char* deviceName);
60 rb::Protocol*
beginConnect(
const char* owner,
const char* deviceName,
const char* wifiSSID,
const char* wifiPassword =
"");
69 rb::Protocol*
beginStartAp(
const char* owner,
const char* deviceName,
const char* wifiSSID,
const char* wifiPassword =
"",
bool withCaptivePortal =
true);
76 bool handleRbPacket(
const std::string& command, rbjson::Object* pkt);
78 rb::Protocol*
protocol()
const {
return m_protocol.load(); }
82 builder::Arm&
arm(
float x,
float y,
float w,
float h, uint16_t uuid = 0, uint16_t tab = 0) {
83 return *newWidget<builder::Arm>(x, y, w, h, uuid, tab);
86 builder::Bar&
bar(
float x,
float y,
float w,
float h, uint16_t uuid = 0, uint16_t tab = 0) {
87 return *newWidget<builder::Bar>(x, y, w, h, uuid, tab);
91 return *newWidget<builder::Button>(x, y, w, h, uuid, tab);
95 return *newWidget<builder::Camera>(x, y, w, h, uuid, tab);
99 return *newWidget<builder::Checkbox>(x, y, w, h, uuid, tab);
103 return *newWidget<builder::Circle>(x, y, w, h, uuid, tab);
107 return *newWidget<builder::Input>(x, y, w, h, uuid, tab);
111 return *newWidget<builder::Joystick>(x, y, w, h, uuid, tab);
114 builder::Led&
led(
float x,
float y,
float w,
float h, uint16_t uuid = 0, uint16_t tab = 0) {
115 return *newWidget<builder::Led>(x, y, w, h, uuid, tab);
119 return *newWidget<builder::Orientation>(x, y, w, h, uuid, tab);
123 return *newWidget<builder::Slider>(x, y, w, h, uuid, tab);
127 return *newWidget<builder::SpinEdit>(x, y, w, h, uuid, tab);
131 auto*
switcher = newWidget<builder::Switcher>(x, y, w, h, uuid, tab);
139 return *newWidget<builder::Text>(x, y, w, h, uuid, tab);
143 return *newWidget<builder::Select>(x, y, w, h, uuid, tab);
147 template <
typename T>
148 T* newWidget(
float x,
float y,
float w,
float h, uint16_t uuid, uint16_t tab) {
149 static_assert(std::is_base_of<builder::Widget, T>::value,
"T must inherit from builder::Widget.");
151 std::lock_guard<std::mutex> l(m_states_mu);
153 if (!checkUuidFreeLocked(uuid))
154 uuid = generateUuidLocked();
156 auto* state =
new WidgetState(uuid, x, y, w, h, tab);
157 m_states.emplace_back(std::unique_ptr<WidgetState>(state));
159 auto* widget =
new T(T::name(), *state);
160 m_widgets.push_back(std::unique_ptr<T>(widget));
164 inline WidgetState* stateByUuidLocked(uint16_t uuid)
const {
165 for (
auto& itr : m_states) {
166 if (itr->uuid() == uuid) {
173 static void stateChangeTask(
void* self);
174 static void tabChangeTask(
void* self);
176 void notifyStateChange() {
177 m_states_modified =
true;
180 uint16_t generateUuidLocked()
const;
181 inline bool checkUuidFreeLocked(uint16_t uuid)
const {
182 return uuid != 0 && stateByUuidLocked(uuid) ==
nullptr;
185 std::vector<std::unique_ptr<builder::Widget>> m_widgets;
186 std::vector<std::unique_ptr<WidgetState>> m_states;
188 std::atomic<rb::Protocol*> m_protocol;
189 bool m_protocol_ours;
191 std::unique_ptr<rbjson::Object> m_layout;
192 esp_timer_handle_t m_update_timer;
193 TaskHandle_t m_web_server_task;
195 mutable std::mutex m_states_mu;
196 uint32_t m_state_mustarrive_id;
197 std::atomic<bool> m_states_modified;
199 mutable std::mutex m_tab_mu;
200 std::atomic<bool> m_tab_changed;
builder::Arm & arm(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Text & text(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Led & led(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Select & select(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
rb::Protocol * protocol() const
builder::Bar & bar(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Input & input(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Button & button(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Checkbox & checkbox(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
rb::Protocol * beginConnect(const char *owner, const char *deviceName, const char *wifiSSID, const char *wifiPassword="")
builder::Slider & slider(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::SpinEdit & spinedit(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Circle & circle(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
void begin(rb::Protocol *protocol, int cols=12, int rows=18, bool enableSplitting=true)
builder::Camera & camera(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
bool handleRbPacket(const std::string &command, rbjson::Object *pkt)
builder::Orientation & orientation(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
builder::Switcher & switcher(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
void changeTab(uint16_t index)
builder::Joystick & joystick(float x, float y, float w, float h, uint16_t uuid=0, uint16_t tab=0)
rb::Protocol * beginStartAp(const char *owner, const char *deviceName, const char *wifiSSID, const char *wifiPassword="", bool withCaptivePortal=true)
void addCallback(const std::string &name, callback_t cb)