mirror of
https://github.com/s00500/ESPUI.git
synced 2024-11-26 05:21:29 +00:00
Moved the generation of jsonChunks to control manager
This commit is contained in:
parent
83104e9e1e
commit
0a0a97d7f9
@ -79,7 +79,7 @@ void ESPUIclient::FillInHeader(JsonDocument& document)
|
|||||||
document[F("type")] = UI_EXTEND_GUI;
|
document[F("type")] = UI_EXTEND_GUI;
|
||||||
document[F("sliderContinuous")] = ESPUI.sliderContinuous;
|
document[F("sliderContinuous")] = ESPUI.sliderContinuous;
|
||||||
document[F("startindex")] = 0;
|
document[F("startindex")] = 0;
|
||||||
document[F("totalcontrols")] = ESPUI.controlCount;
|
document[F("totalcontrols")] = ESPUIcontrolMgr.GetControlCount();
|
||||||
JsonArray items = AllocateJsonArray(document, F("controls"));
|
JsonArray items = AllocateJsonArray(document, F("controls"));
|
||||||
JsonObject titleItem = AllocateJsonObject(items);
|
JsonObject titleItem = AllocateJsonObject(items);
|
||||||
titleItem[F("type")] = (int)UI_TITLE;
|
titleItem[F("type")] = (int)UI_TITLE;
|
||||||
@ -253,213 +253,6 @@ bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
|
|||||||
return Response;
|
return Response;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Prepare a chunk of elements as a single JSON string. If the allowed number of elements is greater than the total
|
|
||||||
number this will represent the entire UI. More likely, it will represent a small section of the UI to be sent. The
|
|
||||||
client will acknowledge receipt by requesting the next chunk.
|
|
||||||
*/
|
|
||||||
uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
|
|
||||||
JsonDocument & rootDoc,
|
|
||||||
bool InUpdateMode,
|
|
||||||
String FragmentRequestString)
|
|
||||||
{
|
|
||||||
#ifdef ESP32
|
|
||||||
xSemaphoreTake(ESPUI.ControlsSemaphore, portMAX_DELAY);
|
|
||||||
#endif // def ESP32
|
|
||||||
|
|
||||||
// Serial.println(String("prepareJSONChunk: Start. InUpdateMode: ") + String(InUpdateMode));
|
|
||||||
// Serial.println(String("prepareJSONChunk: Start. startindex: ") + String(startindex));
|
|
||||||
// Serial.println(String("prepareJSONChunk: Start. FragmentRequestString: '") + FragmentRequestString + "'");
|
|
||||||
int elementcount = 0;
|
|
||||||
uint32_t MaxMarshaledJsonSize = (!InUpdateMode) ? ESPUI.jsonInitialDocumentSize: ESPUI.jsonUpdateDocumentSize;
|
|
||||||
uint32_t EstimatedUsedMarshaledJsonSize = 0;
|
|
||||||
|
|
||||||
do // once
|
|
||||||
{
|
|
||||||
// Follow the list until control points to the startindex'th node
|
|
||||||
Control* control = ESPUI.controls;
|
|
||||||
uint32_t currentIndex = 0;
|
|
||||||
uint32_t DataOffset = 0;
|
|
||||||
JsonArray items = rootDoc[F("controls")];
|
|
||||||
bool SingleControl = false;
|
|
||||||
|
|
||||||
if(!emptyString.equals(FragmentRequestString))
|
|
||||||
{
|
|
||||||
// Serial.println(F("prepareJSONChunk:Fragmentation:Got Header (1)"));
|
|
||||||
// Serial.println(String("prepareJSONChunk:startindex: ") + String(startindex));
|
|
||||||
// Serial.println(String("prepareJSONChunk:currentIndex: ") + String(currentIndex));
|
|
||||||
// Serial.println(String("prepareJSONChunk:FragmentRequestString: '") + FragmentRequestString + "'");
|
|
||||||
|
|
||||||
// this is actually a fragment or directed update request
|
|
||||||
// parse the string we got from the UI and try to update that specific
|
|
||||||
// control.
|
|
||||||
AllocateJsonDocument(FragmentRequest, FragmentRequestString.length() * 3);
|
|
||||||
/*
|
|
||||||
ArduinoJson::detail::sizeofObject(N);
|
|
||||||
if(0 >= FragmentRequest.capacity())
|
|
||||||
{
|
|
||||||
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Could not allocate memory for a fragmentation request. Skipping Response"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
size_t FragmentRequestStartOffset = FragmentRequestString.indexOf("{");
|
|
||||||
DeserializationError error = deserializeJson(FragmentRequest, FragmentRequestString.substring(FragmentRequestStartOffset));
|
|
||||||
if(DeserializationError::Ok != error)
|
|
||||||
{
|
|
||||||
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Could not extract json from the fragment request"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!FragmentRequest.containsKey(F("id")))
|
|
||||||
{
|
|
||||||
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a control ID"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
uint16_t ControlId = uint16_t(FragmentRequest[F("id")]);
|
|
||||||
|
|
||||||
if(!FragmentRequest.containsKey(F("offset")))
|
|
||||||
{
|
|
||||||
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a starting offset"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DataOffset = uint16_t(FragmentRequest[F("offset")]);
|
|
||||||
control = ESPUI.getControlNoLock(ControlId);
|
|
||||||
if(nullptr == control)
|
|
||||||
{
|
|
||||||
Serial.println(String(F("ERROR:prepareJSONChunk:Fragmentation:Requested control: ")) + String(ControlId) + F(" does not exist"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serial.println(F("prepareJSONChunk:Fragmentation:disable the control search operation"));
|
|
||||||
currentIndex = 1;
|
|
||||||
startindex = 0;
|
|
||||||
SingleControl = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find a control to send
|
|
||||||
while ((startindex > currentIndex) && (nullptr != control))
|
|
||||||
{
|
|
||||||
// only count active controls
|
|
||||||
if (!control->ToBeDeleted())
|
|
||||||
{
|
|
||||||
if(InUpdateMode)
|
|
||||||
{
|
|
||||||
// In update mode we only count the controls that have been updated.
|
|
||||||
if(control->NeedsSync(CurrentSyncID))
|
|
||||||
{
|
|
||||||
++currentIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// not in update mode. Count all active controls
|
|
||||||
++currentIndex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
control = control->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// any controls left to be processed?
|
|
||||||
if(nullptr == control)
|
|
||||||
{
|
|
||||||
// Serial.println("prepareJSONChunk: No controls to process");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// keep track of the number of elements we have serialised into this
|
|
||||||
// message. Overflow is detected and handled later in this loop
|
|
||||||
// and needs an index to the last item added.
|
|
||||||
while (nullptr != control)
|
|
||||||
{
|
|
||||||
// skip deleted controls or controls that have not been updated
|
|
||||||
if (control->ToBeDeleted() && !SingleControl)
|
|
||||||
{
|
|
||||||
// Serial.println(String("prepareJSONChunk: Ignoring Deleted control: ") + String(control->id));
|
|
||||||
control = control->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(InUpdateMode && !SingleControl)
|
|
||||||
{
|
|
||||||
if(control->NeedsSync(CurrentSyncID))
|
|
||||||
{
|
|
||||||
// dont skip this control
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// control has not been updated. Skip it
|
|
||||||
control = control->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Serial.println(String(F("prepareJSONChunk: MaxMarshaledJsonSize: ")) + String(MaxMarshaledJsonSize));
|
|
||||||
// Serial.println(String(F("prepareJSONChunk: Cur EstimatedUsedMarshaledJsonSize: ")) + String(EstimatedUsedMarshaledJsonSize));
|
|
||||||
|
|
||||||
JsonObject item = AllocateJsonObject(items);
|
|
||||||
elementcount++;
|
|
||||||
uint32_t RemainingSpace = (MaxMarshaledJsonSize - EstimatedUsedMarshaledJsonSize) - 100;
|
|
||||||
// Serial.println(String(F("prepareJSONChunk: RemainingSpace: ")) + String(RemainingSpace));
|
|
||||||
uint32_t SpaceUsedByMarshaledControl = 0;
|
|
||||||
bool ControlIsFragmented = control->MarshalControl(item,
|
|
||||||
InUpdateMode,
|
|
||||||
DataOffset,
|
|
||||||
RemainingSpace,
|
|
||||||
SpaceUsedByMarshaledControl);
|
|
||||||
// Serial.println(String(F("prepareJSONChunk: SpaceUsedByMarshaledControl: ")) + String(SpaceUsedByMarshaledControl));
|
|
||||||
EstimatedUsedMarshaledJsonSize += SpaceUsedByMarshaledControl;
|
|
||||||
// Serial.println(String(F("prepareJSONChunk: New EstimatedUsedMarshaledJsonSize: ")) + String(EstimatedUsedMarshaledJsonSize));
|
|
||||||
// Serial.println(String(F("prepareJSONChunk: ControlIsFragmented: ")) + String(ControlIsFragmented));
|
|
||||||
|
|
||||||
// did the control get added to the doc?
|
|
||||||
if (0 == SpaceUsedByMarshaledControl ||
|
|
||||||
(ESPUI.jsonChunkNumberMax > 0 && (elementcount % ESPUI.jsonChunkNumberMax) == 0))
|
|
||||||
{
|
|
||||||
// Serial.println( String("prepareJSONChunk: too much data in the message. Remove the last entry"));
|
|
||||||
if (1 == elementcount)
|
|
||||||
{
|
|
||||||
// Serial.println(String(F("prepareJSONChunk: Control ")) + String(control->id) + F(" is too large to be sent to the browser."));
|
|
||||||
// Serial.println(String(F("ERROR: prepareJSONChunk: value: ")) + control->value);
|
|
||||||
rootDoc.clear();
|
|
||||||
item = AllocateJsonObject(items);
|
|
||||||
control->MarshalErrorMessage(item);
|
|
||||||
elementcount = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Serial.println(String("prepareJSONChunk: Defering control: ") + String(control->id));
|
|
||||||
// Serial.println(String("prepareJSONChunk: elementcount: ") + String(elementcount));
|
|
||||||
|
|
||||||
items.remove(elementcount);
|
|
||||||
--elementcount;
|
|
||||||
}
|
|
||||||
// exit the loop
|
|
||||||
control = nullptr;
|
|
||||||
}
|
|
||||||
else if ((SingleControl) ||
|
|
||||||
(ControlIsFragmented) ||
|
|
||||||
(MaxMarshaledJsonSize < (EstimatedUsedMarshaledJsonSize + 100)))
|
|
||||||
{
|
|
||||||
// Serial.println("prepareJSONChunk: Doc is Full, Fragmented Control or Single Control. exit loop");
|
|
||||||
control = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Serial.println("prepareJSONChunk: Next Control");
|
|
||||||
control = control->next;
|
|
||||||
}
|
|
||||||
} // end while (control != nullptr)
|
|
||||||
|
|
||||||
} while (false);
|
|
||||||
|
|
||||||
#ifdef ESP32
|
|
||||||
xSemaphoreGive(ESPUI.ControlsSemaphore);
|
|
||||||
#endif // def ESP32
|
|
||||||
|
|
||||||
// Serial.println(String("prepareJSONChunk: END: elementcount: ") + String(elementcount));
|
|
||||||
return elementcount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Convert & Transfer Arduino elements to JSON elements. This function sends a chunk of
|
Convert & Transfer Arduino elements to JSON elements. This function sends a chunk of
|
||||||
JSON describing the controls of the UI, starting from the control at index startidx.
|
JSON describing the controls of the UI, starting from the control at index startidx.
|
||||||
@ -492,7 +285,7 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx, ClientUpdateType_t Tra
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((startidx >= ESPUI.controlCount) && (emptyString.equals(FragmentRequest)))
|
else if ((startidx >= ESPUIcontrolMgr.GetControlCount()) && (emptyString.equals(FragmentRequest)))
|
||||||
{
|
{
|
||||||
// Serial.println(F("ERROR:ESPUIclient:SendControlsToClient: No more controls to send."));
|
// Serial.println(F("ERROR:ESPUIclient:SendControlsToClient: No more controls to send."));
|
||||||
Response = true;
|
Response = true;
|
||||||
@ -514,7 +307,7 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx, ClientUpdateType_t Tra
|
|||||||
// Serial.println(String("ESPUIclient:SendControlsToClient:type: ") + String((uint32_t)document["type"]));
|
// Serial.println(String("ESPUIclient:SendControlsToClient:type: ") + String((uint32_t)document["type"]));
|
||||||
|
|
||||||
// Serial.println("ESPUIclient:SendControlsToClient: Build Controls.");
|
// Serial.println("ESPUIclient:SendControlsToClient: Build Controls.");
|
||||||
if(prepareJSONChunk(startidx, document, ClientUpdateType_t::UpdateNeeded == TransferMode, FragmentRequest))
|
if(ESPUIcontrolMgr.prepareJSONChunk(startidx, document, ClientUpdateType_t::UpdateNeeded == TransferMode, FragmentRequest, CurrentSyncID))
|
||||||
{
|
{
|
||||||
#if defined(DEBUG_ESPUI)
|
#if defined(DEBUG_ESPUI)
|
||||||
if (ESPUI.verbosity >= Verbosity::VerboseJSON)
|
if (ESPUI.verbosity >= Verbosity::VerboseJSON)
|
||||||
|
@ -44,7 +44,6 @@ protected:
|
|||||||
|
|
||||||
bool CanSend();
|
bool CanSend();
|
||||||
void FillInHeader(ArduinoJson::JsonDocument& document);
|
void FillInHeader(ArduinoJson::JsonDocument& document);
|
||||||
uint32_t prepareJSONChunk(uint16_t startindex, JsonDocument& rootDoc, bool InUpdateMode, String value);
|
|
||||||
bool SendControlsToClient(uint16_t startidx, ClientUpdateType_t TransferMode, String FragmentRequest);
|
bool SendControlsToClient(uint16_t startidx, ClientUpdateType_t TransferMode, String FragmentRequest);
|
||||||
|
|
||||||
bool SendClientNotification(ClientUpdateType_t value);
|
bool SendClientNotification(ClientUpdateType_t value);
|
||||||
|
Loading…
Reference in New Issue
Block a user