mirror of
https://github.com/s00500/ESPUI.git
synced 2024-11-22 04:00:55 +00:00
Changes to support keeping multiple Browser Clients in sync
This commit is contained in:
parent
85ccff0ee0
commit
00841ce32d
@ -601,10 +601,13 @@ void ESPUIClass::onWsEvent(
|
|||||||
// Serial.println("ESPUIClass::OnWsEvent:Create new client.");
|
// Serial.println("ESPUIClass::OnWsEvent:Create new client.");
|
||||||
MapOfClients[client->id()] = new ESPUIclient(client);
|
MapOfClients[client->id()] = new ESPUIclient(client);
|
||||||
}
|
}
|
||||||
MapOfClients[client->id()]->onWsEvent(type, arg, data, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
ClearControlUpdateFlags();
|
if(MapOfClients[client->id()]->onWsEvent(type, arg, data, len))
|
||||||
|
{
|
||||||
|
// Serial.println("ESPUIClass::OnWsEvent:notify the clients that they need to be updated.");
|
||||||
|
NotifyClients(ESPUIclient::UpdateNeeded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -854,11 +857,21 @@ void ESPUIClass::updateControl(Control* control, int)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// tel the control it has been updated
|
// tell the control it has been updated
|
||||||
control->HasBeenUpdated();
|
control->SetControlChangedId(ESPUI.GetNextControlChangeId());
|
||||||
NotifyClients(ClientUpdateType_t::UpdateNeeded);
|
NotifyClients(ClientUpdateType_t::UpdateNeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t ESPUIClass::GetNextControlChangeId()
|
||||||
|
{
|
||||||
|
if(uint32_t(-1) == ControlChangeID)
|
||||||
|
{
|
||||||
|
// force a reload which resets the counters
|
||||||
|
jsonReload();
|
||||||
|
}
|
||||||
|
return ++ControlChangeID;
|
||||||
|
}
|
||||||
|
|
||||||
void ESPUIClass::setPanelStyle(uint16_t id, const String& style, int clientId)
|
void ESPUIClass::setPanelStyle(uint16_t id, const String& style, int clientId)
|
||||||
{
|
{
|
||||||
Control* control = getControl(id);
|
Control* control = getControl(id);
|
||||||
@ -1126,30 +1139,6 @@ void ESPUIClass::NotifyClients(ClientUpdateType_t newState)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ESPUIClass::ClearControlUpdateFlags()
|
|
||||||
{
|
|
||||||
bool CanClearUpdateFlags = true;
|
|
||||||
|
|
||||||
for (auto& CurrentClient : MapOfClients)
|
|
||||||
{
|
|
||||||
if (!CurrentClient.second->IsSyncronized())
|
|
||||||
{
|
|
||||||
CanClearUpdateFlags = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CanClearUpdateFlags)
|
|
||||||
{
|
|
||||||
Control* control = controls;
|
|
||||||
while (nullptr != control)
|
|
||||||
{
|
|
||||||
control->HasBeenSynchronized();
|
|
||||||
control = control->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ESPUIClass::jsonReload()
|
void ESPUIClass::jsonReload()
|
||||||
{
|
{
|
||||||
for (auto& CurrentClient : MapOfClients)
|
for (auto& CurrentClient : MapOfClients)
|
||||||
|
@ -193,7 +193,7 @@ public:
|
|||||||
void jsonDom(uint16_t startidx, AsyncWebSocketClient* client = nullptr, bool Updating = false);
|
void jsonDom(uint16_t startidx, AsyncWebSocketClient* client = nullptr, bool Updating = false);
|
||||||
|
|
||||||
Verbosity verbosity = Verbosity::Quiet;
|
Verbosity verbosity = Verbosity::Quiet;
|
||||||
|
uint32_t GetNextControlChangeId();
|
||||||
// emulate former extended callback API by using an intermediate lambda (no deprecation)
|
// emulate former extended callback API by using an intermediate lambda (no deprecation)
|
||||||
uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, std::function<void(Control*, int, void*)> callback, void* userData)
|
uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, std::function<void(Control*, int, void*)> callback, void* userData)
|
||||||
{
|
{
|
||||||
@ -255,12 +255,12 @@ protected:
|
|||||||
#define ClientUpdateType_t ESPUIclient::ClientUpdateType_t
|
#define ClientUpdateType_t ESPUIclient::ClientUpdateType_t
|
||||||
void NotifyClients(ClientUpdateType_t newState);
|
void NotifyClients(ClientUpdateType_t newState);
|
||||||
void NotifyClient(uint32_t WsClientId, ClientUpdateType_t newState);
|
void NotifyClient(uint32_t WsClientId, ClientUpdateType_t newState);
|
||||||
void ClearControlUpdateFlags();
|
|
||||||
|
|
||||||
bool SendJsonDocToWebSocket(ArduinoJson::DynamicJsonDocument& document, uint16_t clientId);
|
bool SendJsonDocToWebSocket(ArduinoJson::DynamicJsonDocument& document, uint16_t clientId);
|
||||||
|
|
||||||
std::map<uint32_t, ESPUIclient*> MapOfClients;
|
std::map<uint32_t, ESPUIclient*> MapOfClients;
|
||||||
|
|
||||||
|
uint32_t ControlChangeID = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ESPUIClass ESPUI;
|
extern ESPUIClass ESPUI;
|
||||||
|
@ -100,7 +100,7 @@ bool ESPUIclient::SendClientNotification(ClientUpdateType_t value)
|
|||||||
{
|
{
|
||||||
if(!CanSend())
|
if(!CanSend())
|
||||||
{
|
{
|
||||||
// Serial.println(F("ESPUIclient::NotifyClient"));
|
// Serial.println(F("ESPUIclient::SendClientNotification:CannotSend"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,42 +124,12 @@ void ESPUIclient::NotifyClient(ClientUpdateType_t newState)
|
|||||||
{
|
{
|
||||||
SetState(newState);
|
SetState(newState);
|
||||||
pCurrentFsmState->NotifyClient();
|
pCurrentFsmState->NotifyClient();
|
||||||
|
|
||||||
#ifdef OldWay
|
|
||||||
do // once
|
|
||||||
{
|
|
||||||
// Serial.println(String("ESPUIclient::NotifyClient: State: ") + String(int(newState)));
|
|
||||||
SetState(newState);
|
|
||||||
|
|
||||||
if (HasBeenNotified)
|
|
||||||
{
|
|
||||||
// do not need to do anything
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(TransferIsInprogress)
|
|
||||||
{
|
|
||||||
// record that a notification was needed while we were transfering data to the client
|
|
||||||
DelayedNotification = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
DelayedNotification = false;
|
|
||||||
|
|
||||||
if (SendJsonDocToWebSocket(document))
|
|
||||||
{
|
|
||||||
HasBeenNotified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while (false);
|
|
||||||
|
|
||||||
return HasBeenNotified;
|
|
||||||
#endif // def OldWay
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle Websockets Communication
|
// Handle Websockets Communication
|
||||||
void ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t len)
|
bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t len)
|
||||||
{
|
{
|
||||||
|
bool Response = false;
|
||||||
// Serial.println(String("ESPUIclient::OnWsEvent: type: ") + String(type));
|
// Serial.println(String("ESPUIclient::OnWsEvent: type: ") + String(type));
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -228,21 +198,23 @@ void ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
|
|||||||
|
|
||||||
if (cmd.equals(F("uiok")))
|
if (cmd.equals(F("uiok")))
|
||||||
{
|
{
|
||||||
// Serial.println(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:ProcessAck"));
|
|
||||||
|
// Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:ProcessAck:")) + pCurrentFsmState->GetStateName());
|
||||||
pCurrentFsmState->ProcessAck(id, emptyString);
|
pCurrentFsmState->ProcessAck(id, emptyString);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.equals(F("uifragmentok")))
|
if (cmd.equals(F("uifragmentok")))
|
||||||
{
|
{
|
||||||
|
// Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:uifragmentok:")) + pCurrentFsmState->GetStateName() + ":ProcessAck");
|
||||||
if(!emptyString.equals(value))
|
if(!emptyString.equals(value))
|
||||||
{
|
{
|
||||||
// Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uifragmentok:ProcessAck:value: '")) + value + "'");
|
// Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:uifragmentok:")) + pCurrentFsmState->GetStateName() + ":ProcessAck:value:'" + value + "'");
|
||||||
pCurrentFsmState->ProcessAck(uint16_t(-1), value);
|
pCurrentFsmState->ProcessAck(uint16_t(-1), value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Serial.println(F("ERROR:ESPUIclient::OnWsEvent:WS_EVT_DATA:uifragmentok:ProcessAck:Fragment Header is missing"));
|
Serial.println(F("ERROR:ESPUIclient::OnWsEvent:WS_EVT_DATA:uifragmentok:ProcessAck:Fragment Header is missing"));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -253,6 +225,7 @@ void ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Serial.println(F("WS_EVT_DATA:Process Control"));
|
||||||
Control* control = ESPUI.getControl(id);
|
Control* control = ESPUI.getControl(id);
|
||||||
if (nullptr == control)
|
if (nullptr == control)
|
||||||
{
|
{
|
||||||
@ -265,6 +238,8 @@ void ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
control->onWsEvent(cmd, value);
|
control->onWsEvent(cmd, value);
|
||||||
|
// notify other clients of change
|
||||||
|
Response = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,6 +249,8 @@ void ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} // end switch
|
} // end switch
|
||||||
|
|
||||||
|
return Response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -361,7 +338,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
|
|||||||
if(InUpdateMode)
|
if(InUpdateMode)
|
||||||
{
|
{
|
||||||
// In update mode we only count the controls that have been updated.
|
// In update mode we only count the controls that have been updated.
|
||||||
if(control->IsUpdated())
|
if(control->NeedsSync(CurrentSyncID))
|
||||||
{
|
{
|
||||||
++currentIndex;
|
++currentIndex;
|
||||||
}
|
}
|
||||||
@ -397,7 +374,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
|
|||||||
|
|
||||||
if(InUpdateMode && !SingleControl)
|
if(InUpdateMode && !SingleControl)
|
||||||
{
|
{
|
||||||
if(control->IsUpdated())
|
if(control->NeedsSync(CurrentSyncID))
|
||||||
{
|
{
|
||||||
// dont skip this control
|
// dont skip this control
|
||||||
}
|
}
|
||||||
@ -505,6 +482,8 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx, ClientUpdateType_t Tra
|
|||||||
{
|
{
|
||||||
// Serial.println("ESPUIclient:SendControlsToClient: Tell client we are starting a transfer of controls.");
|
// Serial.println("ESPUIclient:SendControlsToClient: Tell client we are starting a transfer of controls.");
|
||||||
document["type"] = (ClientUpdateType_t::RebuildNeeded == TransferMode) ? UI_INITIAL_GUI : UI_EXTEND_GUI;
|
document["type"] = (ClientUpdateType_t::RebuildNeeded == TransferMode) ? UI_INITIAL_GUI : UI_EXTEND_GUI;
|
||||||
|
CurrentSyncID = NextSyncID;
|
||||||
|
NextSyncID = ESPUI.GetNextControlChangeId();
|
||||||
}
|
}
|
||||||
// Serial.println(String("ESPUIclient:SendControlsToClient:type: ") + String((uint32_t)document["type"]));
|
// Serial.println(String("ESPUIclient:SendControlsToClient:type: ") + String((uint32_t)document["type"]));
|
||||||
|
|
||||||
|
@ -49,14 +49,19 @@ protected:
|
|||||||
|
|
||||||
bool SendClientNotification(ClientUpdateType_t value);
|
bool SendClientNotification(ClientUpdateType_t value);
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t CurrentSyncID = 0;
|
||||||
|
uint32_t NextSyncID = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ESPUIclient(AsyncWebSocketClient * _client);
|
ESPUIclient(AsyncWebSocketClient * _client);
|
||||||
ESPUIclient(const ESPUIclient & source);
|
ESPUIclient(const ESPUIclient & source);
|
||||||
virtual ~ESPUIclient();
|
virtual ~ESPUIclient();
|
||||||
void NotifyClient(ClientUpdateType_t value);
|
void NotifyClient(ClientUpdateType_t value);
|
||||||
void onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t len);
|
bool onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||||
bool IsSyncronized();
|
bool IsSyncronized();
|
||||||
uint32_t id() { return client->id(); }
|
uint32_t id() { return client->id(); }
|
||||||
void SetState(ClientUpdateType_t value);
|
void SetState(ClientUpdateType_t value);
|
||||||
bool SendJsonDocToWebSocket(ArduinoJson::DynamicJsonDocument& document);
|
bool SendJsonDocToWebSocket(ArduinoJson::DynamicJsonDocument& document);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -69,7 +69,7 @@ void fsm_EspuiClient_state_Idle::ProcessAck(uint16_t ControlIndex, String Fragme
|
|||||||
{
|
{
|
||||||
// This is an unexpected request for control data from the browser
|
// This is an unexpected request for control data from the browser
|
||||||
// treat it as if it was a rebuild operation
|
// treat it as if it was a rebuild operation
|
||||||
// Serial.println(F("fsm_EspuiClient_state_Idle: ProcessAck"));
|
// Serial.println(F("fsm_EspuiClient_state_Idle: ProcessAck:Error: Rebuild"));
|
||||||
Parent->NotifyClient(ClientUpdateType_t::RebuildNeeded);
|
Parent->NotifyClient(ClientUpdateType_t::RebuildNeeded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,6 +97,14 @@ void fsm_EspuiClient_state_SendingUpdate::ProcessAck(uint16_t ControlIndex, Stri
|
|||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
|
void fsm_EspuiClient_state_Rebuilding::Init()
|
||||||
|
{
|
||||||
|
// Serial.println(String("fsm_EspuiClient_state:Init: ") + GetStateName());
|
||||||
|
Parent->CurrentSyncID = 0;
|
||||||
|
Parent->NextSyncID = 0;
|
||||||
|
Parent->pCurrentFsmState = this;
|
||||||
|
}
|
||||||
|
|
||||||
bool fsm_EspuiClient_state_Rebuilding::NotifyClient()
|
bool fsm_EspuiClient_state_Rebuilding::NotifyClient()
|
||||||
{
|
{
|
||||||
// Serial.println(F("fsm_EspuiClient_state_Rebuilding: NotifyClient"));
|
// Serial.println(F("fsm_EspuiClient_state_Rebuilding: NotifyClient"));
|
||||||
@ -117,6 +125,14 @@ void fsm_EspuiClient_state_Rebuilding::ProcessAck(uint16_t ControlIndex, String
|
|||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
//----------------------------------------------
|
//----------------------------------------------
|
||||||
|
void fsm_EspuiClient_state_Reloading::Init()
|
||||||
|
{
|
||||||
|
// Serial.println(String("fsm_EspuiClient_state:Init: ") + GetStateName());
|
||||||
|
Parent->CurrentSyncID = 0;
|
||||||
|
Parent->NextSyncID = 0;
|
||||||
|
Parent->pCurrentFsmState = this;
|
||||||
|
}
|
||||||
|
|
||||||
void fsm_EspuiClient_state_Reloading::ProcessAck(uint16_t ControlIndex, String FragmentRequestString)
|
void fsm_EspuiClient_state_Reloading::ProcessAck(uint16_t ControlIndex, String FragmentRequestString)
|
||||||
{
|
{
|
||||||
if(!emptyString.equals(FragmentRequestString))
|
if(!emptyString.equals(FragmentRequestString))
|
||||||
@ -125,3 +141,9 @@ void fsm_EspuiClient_state_Reloading::ProcessAck(uint16_t ControlIndex, String F
|
|||||||
Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::UpdateNeeded, FragmentRequestString);
|
Parent->SendControlsToClient(ControlIndex, ClientUpdateType_t::UpdateNeeded, FragmentRequestString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool fsm_EspuiClient_state_Reloading::NotifyClient()
|
||||||
|
{
|
||||||
|
// Serial.println(F("fsm_EspuiClient_state_Reloading: NotifyClient"));
|
||||||
|
return true; /* Ignore request */
|
||||||
|
}
|
||||||
|
@ -59,6 +59,7 @@ public:
|
|||||||
fsm_EspuiClient_state_Rebuilding() {}
|
fsm_EspuiClient_state_Rebuilding() {}
|
||||||
virtual ~fsm_EspuiClient_state_Rebuilding() {}
|
virtual ~fsm_EspuiClient_state_Rebuilding() {}
|
||||||
|
|
||||||
|
void Init();
|
||||||
virtual bool NotifyClient();
|
virtual bool NotifyClient();
|
||||||
virtual void ProcessAck(uint16_t id, String FragmentRequest);
|
virtual void ProcessAck(uint16_t id, String FragmentRequest);
|
||||||
String GetStateName() { return String(F("Sending Rebuild")); }
|
String GetStateName() { return String(F("Sending Rebuild")); }
|
||||||
@ -71,7 +72,8 @@ public:
|
|||||||
fsm_EspuiClient_state_Reloading() {}
|
fsm_EspuiClient_state_Reloading() {}
|
||||||
virtual ~fsm_EspuiClient_state_Reloading() {}
|
virtual ~fsm_EspuiClient_state_Reloading() {}
|
||||||
|
|
||||||
virtual bool NotifyClient() { return false; }
|
void Init();
|
||||||
|
virtual bool NotifyClient();
|
||||||
virtual void ProcessAck(uint16_t id, String FragmentRequest);
|
virtual void ProcessAck(uint16_t id, String FragmentRequest);
|
||||||
String GetStateName() { return String(F("Reloading")); }
|
String GetStateName() { return String(F("Reloading")); }
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ Control::Control(ControlType type, const char* label, std::function<void(Control
|
|||||||
next(nullptr)
|
next(nullptr)
|
||||||
{
|
{
|
||||||
id = ++idCounter;
|
id = ++idCounter;
|
||||||
|
ControlChangeID = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Control::Control(const Control& Control)
|
Control::Control(const Control& Control)
|
||||||
@ -29,7 +30,8 @@ Control::Control(const Control& Control)
|
|||||||
color(Control.color),
|
color(Control.color),
|
||||||
visible(Control.visible),
|
visible(Control.visible),
|
||||||
parentControl(Control.parentControl),
|
parentControl(Control.parentControl),
|
||||||
next(Control.next)
|
next(Control.next),
|
||||||
|
ControlChangeID(Control.ControlChangeID)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void Control::SendCallback(int type)
|
void Control::SendCallback(int type)
|
||||||
@ -42,7 +44,7 @@ void Control::SendCallback(int type)
|
|||||||
|
|
||||||
void Control::DeleteControl()
|
void Control::DeleteControl()
|
||||||
{
|
{
|
||||||
ControlSyncState = ControlSyncState_t::deleted;
|
_ToBeDeleted = true;
|
||||||
callback = nullptr;
|
callback = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,6 +152,8 @@ void Control::onWsEvent(String & cmd, String& data)
|
|||||||
{
|
{
|
||||||
do // once
|
do // once
|
||||||
{
|
{
|
||||||
|
// Serial.println(String(F("Control::onWsEvent")));
|
||||||
|
SetControlChangedId(ESPUI.GetNextControlChangeId());
|
||||||
if (!HasCallback())
|
if (!HasCallback())
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_ESPUI)
|
#if defined(DEBUG_ESPUI)
|
||||||
|
@ -84,21 +84,15 @@ public:
|
|||||||
bool HasCallback() { return (nullptr != callback); }
|
bool HasCallback() { return (nullptr != callback); }
|
||||||
void MarshalControl(ArduinoJson::JsonObject& item, bool refresh, uint32_t DataOffset);
|
void MarshalControl(ArduinoJson::JsonObject& item, bool refresh, uint32_t DataOffset);
|
||||||
void MarshalErrorMessage(ArduinoJson::JsonObject& item);
|
void MarshalErrorMessage(ArduinoJson::JsonObject& item);
|
||||||
bool ToBeDeleted() { return (ControlSyncState_t::deleted == ControlSyncState); }
|
|
||||||
void DeleteControl();
|
void DeleteControl();
|
||||||
bool IsUpdated() { return ControlSyncState_t::synchronized != ControlSyncState; }
|
|
||||||
void HasBeenUpdated() { ControlSyncState = ControlSyncState_t::updated; }
|
|
||||||
void HasBeenSynchronized() {ControlSyncState = ControlSyncState_t::synchronized;}
|
|
||||||
void onWsEvent(String& cmd, String& data);
|
void onWsEvent(String& cmd, String& data);
|
||||||
|
inline bool ToBeDeleted() { return _ToBeDeleted; }
|
||||||
|
inline bool NeedsSync(uint32_t lastControlChangeID) {return (false == _ToBeDeleted) && (lastControlChangeID < ControlChangeID);}
|
||||||
|
void SetControlChangedId(uint32_t value) {ControlChangeID = value;}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum ControlSyncState_t
|
bool _ToBeDeleted = false;
|
||||||
{
|
uint32_t ControlChangeID = 0;
|
||||||
synchronized = 0,
|
|
||||||
updated,
|
|
||||||
deleted,
|
|
||||||
};
|
|
||||||
ControlSyncState_t ControlSyncState = ControlSyncState_t::synchronized;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UI_TITLE ControlType::Title
|
#define UI_TITLE ControlType::Title
|
||||||
|
Loading…
Reference in New Issue
Block a user