7#include <freertos/FreeRTOS.h>
8#include <freertos/timers.h>
12#include "rbwebserver.h"
49 void begin(rb::Protocol*
protocol,
int cols = 12,
int rows = 18,
bool enableSplitting =
true);
56 rb::Protocol*
begin(
const char* owner,
const char* deviceName);
64 rb::Protocol*
beginConnect(
const char* owner,
const char* deviceName,
const char* wifiSSID,
const char* wifiPassword =
"");
73 rb::Protocol*
beginStartAp(
const char* owner,
const char* deviceName,
const char* wifiSSID,
const char* wifiPassword =
"",
bool withCaptivePortal =
true);
80 bool handleRbPacket(
const std::string& command, rbjson::Object* pkt);
82 rb::Protocol*
protocol()
const {
return m_protocol.load(); }
86 builder::Arm&
arm(
float x,
float y,
float w,
float h, uint16_t uuid = 0, uint16_t tab = 0) {
87 return *newWidget<builder::Arm>(x, y, w, h, uuid, tab);
90 builder::Bar&
bar(
float x,
float y,
float w,
float h, uint16_t uuid = 0, uint16_t tab = 0) {
91 return *newWidget<builder::Bar>(x, y, w, h, uuid, tab);
95 return *newWidget<builder::Button>(x, y, w, h, uuid, tab);
99 return *newWidget<builder::Camera>(x, y, w, h, uuid, tab);
103 return *newWidget<builder::Checkbox>(x, y, w, h, uuid, tab);
107 return *newWidget<builder::Circle>(x, y, w, h, uuid, tab);
111 return *newWidget<builder::Input>(x, y, w, h, uuid, tab);
115 return *newWidget<builder::Joystick>(x, y, w, h, uuid, tab);
118 builder::Led&
led(
float x,
float y,
float w,
float h, uint16_t uuid = 0, uint16_t tab = 0) {
119 return *newWidget<builder::Led>(x, y, w, h, uuid, tab);
123 return *newWidget<builder::Orientation>(x, y, w, h, uuid, tab);
127 return *newWidget<builder::Slider>(x, y, w, h, uuid, tab);
131 return *newWidget<builder::SpinEdit>(x, y, w, h, uuid, tab);
135 auto*
switcher = newWidget<builder::Switcher>(x, y, w, h, uuid, tab);
143 return *newWidget<builder::Text>(x, y, w, h, uuid, tab);
147 return *newWidget<builder::Select>(x, y, w, h, uuid, tab);
150 template <
typename T>
151 T*
newWidget(
float x,
float y,
float w,
float h, uint16_t uuid, uint16_t tab) {
152 static_assert(std::is_base_of<builder::Widget, T>::value,
"T must inherit from builder::Widget.");
154 std::lock_guard<std::mutex> l(m_states_mu);
156 if (!checkUuidFreeLocked(uuid))
157 uuid = generateUuidLocked();
159 auto* state =
new WidgetState(uuid, x, y, w, h, tab);
160 m_states.emplace_back(std::unique_ptr<WidgetState>(state));
162 auto* widget =
new T(T::name(), *state);
163 m_widgets.emplace_back(std::unique_ptr<T>(widget));
168 inline WidgetState* stateByUuidLocked(uint16_t uuid)
const {
169 for (
auto& itr : m_states) {
170 if (itr->uuid() == uuid) {
177 static void stateChangeTask(
void* self);
178 static void tabChangeTask(
void* self);
180 void notifyStateChange() {
181 m_states_modified =
true;
184 uint16_t generateUuidLocked()
const;
185 inline bool checkUuidFreeLocked(uint16_t uuid)
const {
186 return uuid != 0 && stateByUuidLocked(uuid) ==
nullptr;
189 std::vector<std::unique_ptr<builder::Widget>> m_widgets;
190 std::vector<std::unique_ptr<WidgetState>> m_states;
192 std::atomic<rb::Protocol*> m_protocol;
193 bool m_protocol_ours;
195 std::unique_ptr<rbjson::Object> m_layout;
196 esp_timer_handle_t m_update_timer;
197 TaskHandle_t m_web_server_task;
199 mutable std::mutex m_states_mu;
200 uint32_t m_state_mustarrive_id;
201 std::atomic<bool> m_states_modified;
203 mutable std::mutex m_tab_mu;
204 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)
T * newWidget(float x, float y, float w, float h, uint16_t uuid, uint16_t tab)
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, const callback_t &cb)
not_found_response_t webserverNotFoundCallback(const char *request_path)