mirror of
				https://github.com/s00500/ESPUI.git
				synced 2025-11-04 09:23:23 +00:00 
			
		
		
		
	Reworked control marshaling code to be aware of and enforce size limits by starting to fragment sooner.
This commit is contained in:
		@@ -41,7 +41,8 @@ platform = espressif32
 | 
				
			|||||||
board = esp32dev
 | 
					board = esp32dev
 | 
				
			||||||
monitor_filters = esp32_exception_decoder
 | 
					monitor_filters = esp32_exception_decoder
 | 
				
			||||||
board_build.flash_mode = dout
 | 
					board_build.flash_mode = dout
 | 
				
			||||||
;build_flags =
 | 
					build_flags =
 | 
				
			||||||
 | 
					    -D TEST_HUGE_TEXT
 | 
				
			||||||
;    -D DEBUG_ESPUI
 | 
					;    -D DEBUG_ESPUI
 | 
				
			||||||
lib_deps =
 | 
					lib_deps =
 | 
				
			||||||
    ${env.lib_deps}
 | 
					    ${env.lib_deps}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -267,10 +267,12 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
				
			|||||||
    xSemaphoreTake(ESPUI.ControlsSemaphore, portMAX_DELAY);
 | 
					    xSemaphoreTake(ESPUI.ControlsSemaphore, portMAX_DELAY);
 | 
				
			||||||
#endif // def ESP32
 | 
					#endif // def ESP32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Serial.println(String("prepareJSONChunk: Start. InUpdateMode: ") + String(InUpdateMode));
 | 
					    // 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;
 | 
					    int elementcount = 0;
 | 
				
			||||||
    uint32_t MaxEstimatedMarshaledJsonSize = (!InUpdateMode) ? ESPUI.jsonInitialDocumentSize: ESPUI.jsonUpdateDocumentSize;
 | 
					    uint32_t MaxMarshaledJsonSize = (!InUpdateMode) ? ESPUI.jsonInitialDocumentSize: ESPUI.jsonUpdateDocumentSize;
 | 
				
			||||||
    uint32_t TotalEstimatedMarshaledJsonSize = 0;
 | 
					    uint32_t EstimatedUsedMarshaledJsonSize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    do // once
 | 
					    do // once
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -388,21 +390,32 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            TotalEstimatedMarshaledJsonSize += control->GetEstimatedMarshaledSize();
 | 
					            // Serial.println(String(F("prepareJSONChunk: MaxMarshaledJsonSize: ")) + String(MaxMarshaledJsonSize));
 | 
				
			||||||
            bool DocWillOverflow = TotalEstimatedMarshaledJsonSize >= MaxEstimatedMarshaledJsonSize;
 | 
					            // Serial.println(String(F("prepareJSONChunk: Cur EstimatedUsedMarshaledJsonSize: ")) + String(EstimatedUsedMarshaledJsonSize));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            JsonObject item = items.createNestedObject();
 | 
					            JsonObject item = items.createNestedObject();
 | 
				
			||||||
            elementcount++;
 | 
					            elementcount++;
 | 
				
			||||||
            if(!DocWillOverflow)
 | 
					            uint32_t RemainingSpace = (MaxMarshaledJsonSize - EstimatedUsedMarshaledJsonSize) - 100;
 | 
				
			||||||
            {
 | 
					            // Serial.println(String(F("prepareJSONChunk: RemainingSpace: ")) + String(RemainingSpace));
 | 
				
			||||||
                control->MarshalControl(item, InUpdateMode, DataOffset);
 | 
					            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));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (DocWillOverflow || (ESPUI.jsonChunkNumberMax > 0 && (elementcount % ESPUI.jsonChunkNumberMax) == 0))
 | 
					            // did the control get added to the doc?
 | 
				
			||||||
 | 
					            if (0 == SpaceUsedByMarshaledControl || 
 | 
				
			||||||
 | 
					                (ESPUI.jsonChunkNumberMax > 0 && (elementcount % ESPUI.jsonChunkNumberMax) == 0))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // String("prepareJSONChunk: too much data in the message. Remove the last entry");
 | 
					                // Serial.println( String("prepareJSONChunk: too much data in the message. Remove the last entry"));
 | 
				
			||||||
                if (1 == elementcount)
 | 
					                if (1 == elementcount)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    Serial.println(String(F("ERROR: prepareJSONChunk: Control ")) + String(control->id) + F(" is too large to be sent to the browser."));
 | 
					                    // 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);
 | 
					                    // Serial.println(String(F("ERROR: prepareJSONChunk: value: ")) + control->value);
 | 
				
			||||||
                    rootDoc.clear();
 | 
					                    rootDoc.clear();
 | 
				
			||||||
                    item = items.createNestedObject();
 | 
					                    item = items.createNestedObject();
 | 
				
			||||||
@@ -420,13 +433,16 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
				
			|||||||
                // exit the loop
 | 
					                // exit the loop
 | 
				
			||||||
                control = nullptr;
 | 
					                control = nullptr;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else if (SingleControl)
 | 
					            else if ((SingleControl) || 
 | 
				
			||||||
 | 
					                     (ControlIsFragmented) ||
 | 
				
			||||||
 | 
					                     (MaxMarshaledJsonSize < (EstimatedUsedMarshaledJsonSize + 100)))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                // Serial.println("prepareJSONChunk: exit loop");
 | 
					                // Serial.println("prepareJSONChunk: Doc is Full, Fragmented Control or Single Control. exit loop");
 | 
				
			||||||
                control = nullptr;
 | 
					                control = nullptr;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                // Serial.println("prepareJSONChunk: Next Control");
 | 
				
			||||||
                control = control->next;
 | 
					                control = control->next;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } // end while (control != nullptr)
 | 
					        } // end while (control != nullptr)
 | 
				
			||||||
@@ -437,7 +453,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
 | 
				
			|||||||
    xSemaphoreGive(ESPUI.ControlsSemaphore);
 | 
					    xSemaphoreGive(ESPUI.ControlsSemaphore);
 | 
				
			||||||
#endif // def ESP32
 | 
					#endif // def ESP32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Serial.println(String("prepareJSONChunk: elementcount: ") + String(elementcount));
 | 
					    // Serial.println(String("prepareJSONChunk: END: elementcount: ") + String(elementcount));
 | 
				
			||||||
    return elementcount;
 | 
					    return elementcount;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,6 @@ Control::Control(ControlType type, const char* label, std::function<void(Control
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    id = ++idCounter;
 | 
					    id = ++idCounter;
 | 
				
			||||||
    ControlChangeID = 1;
 | 
					    ControlChangeID = 1;
 | 
				
			||||||
    EstimateMarshaledSize();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Control::Control(const Control& Control)
 | 
					Control::Control(const Control& Control)
 | 
				
			||||||
@@ -32,8 +31,7 @@ Control::Control(const Control& Control)
 | 
				
			|||||||
        visible(Control.visible),
 | 
					        visible(Control.visible),
 | 
				
			||||||
        parentControl(Control.parentControl),
 | 
					        parentControl(Control.parentControl),
 | 
				
			||||||
        next(Control.next),
 | 
					        next(Control.next),
 | 
				
			||||||
        ControlChangeID(Control.ControlChangeID),
 | 
					        ControlChangeID(Control.ControlChangeID)
 | 
				
			||||||
        EstimatedMarshaledSize(Control.EstimatedMarshaledSize)
 | 
					 | 
				
			||||||
{ }
 | 
					{ }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Control::SendCallback(int type)
 | 
					void Control::SendCallback(int type)
 | 
				
			||||||
@@ -50,20 +48,70 @@ void Control::DeleteControl()
 | 
				
			|||||||
    callback = nullptr;
 | 
					    callback = nullptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t StartingOffset)
 | 
					bool Control::MarshalControl(JsonObject & _item, 
 | 
				
			||||||
 | 
					                             bool refresh, 
 | 
				
			||||||
 | 
					                             uint32_t StartingOffset, 
 | 
				
			||||||
 | 
					                             uint32_t AvailMarshaledLength,
 | 
				
			||||||
 | 
					                             uint32_t &EstimatedMarshaledLength)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    JsonObject & item = _item;
 | 
					    // this code assumes MaxMarshaledLength > JsonMarshalingRatio
 | 
				
			||||||
    uint32_t length = value.length();
 | 
					    // Serial.println(String("MarshalControl:           StartingOffset: ") + String(StartingOffset));
 | 
				
			||||||
    uint32_t maxLength = uint32_t(double(ESPUI.jsonInitialDocumentSize) * 0.75);
 | 
					    // Serial.println(String("MarshalControl:     AvailMarshaledLength: ") + String(AvailMarshaledLength));
 | 
				
			||||||
    if((length > maxLength) || StartingOffset)
 | 
					    // Serial.println(String("MarshalControl:               Control ID: ") + String(id));
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    	/*
 | 
					 | 
				
			||||||
        Serial.println(String("MarshalControl:Start Fragment Processing"));
 | 
					 | 
				
			||||||
        Serial.println(String("MarshalControl:id:                ") + String(id));
 | 
					 | 
				
			||||||
        Serial.println(String("MarshalControl:length:            ") + String(length));
 | 
					 | 
				
			||||||
        Serial.println(String("MarshalControl:StartingOffset:    ") + String(StartingOffset));
 | 
					 | 
				
			||||||
        Serial.println(String("MarshalControl:maxLength:         ") + String(maxLength));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool ControlIsFragmented = false;
 | 
				
			||||||
 | 
					    // create a new item in the response document
 | 
				
			||||||
 | 
					    JsonObject & item = _item;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // how much space do we expect to use?
 | 
				
			||||||
 | 
					    uint32_t ValueMarshaledLength   = (value.length() - StartingOffset) * JsonMarshalingRatio;
 | 
				
			||||||
 | 
					    uint32_t LabelMarshaledLength   = strlen(label) * JsonMarshalingRatio;
 | 
				
			||||||
 | 
					    uint32_t MinimumMarshaledLength = LabelMarshaledLength + JsonMarshaledOverhead;
 | 
				
			||||||
 | 
					    uint32_t MaximumMarshaledLength = ValueMarshaledLength + MinimumMarshaledLength;
 | 
				
			||||||
 | 
					    uint32_t SpaceForMarshaledValue = AvailMarshaledLength - MinimumMarshaledLength;
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:           value.length(): ") + String(value.length()));
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:     ValueMarshaledLength: ") + String(ValueMarshaledLength));
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:     LabelMarshaledLength: ") + String(LabelMarshaledLength));
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:   MaximumMarshaledLength: ") + String(MaximumMarshaledLength));
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:   MinimumMarshaledLength: ") + String(MinimumMarshaledLength));
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:   SpaceForMarshaledValue: ") + String(SpaceForMarshaledValue));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // will the item fit in the remaining space? Fragment if not
 | 
				
			||||||
 | 
					    if (AvailMarshaledLength < MinimumMarshaledLength)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Serial.println(String("MarshalControl: Cannot Marshal control. Not enough space for basic headers."));
 | 
				
			||||||
 | 
					        EstimatedMarshaledLength = 0;
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t MaxValueLength = (SpaceForMarshaledValue / JsonMarshalingRatio);
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:           MaxValueLength: ") + String(MaxValueLength));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t ValueLenToSend = min((value.length() - StartingOffset), MaxValueLength);
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:           ValueLenToSend: ") + String(ValueLenToSend));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t AdjustedMarshaledLength = (ValueLenToSend * JsonMarshalingRatio) + MinimumMarshaledLength;
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:  AdjustedMarshaledLength: ") + String(AdjustedMarshaledLength));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool NeedToFragment = (ValueLenToSend < value.length());
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:           NeedToFragment: ") + String(NeedToFragment));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if ((AdjustedMarshaledLength > AvailMarshaledLength) && (0 != ValueLenToSend))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Serial.println(String("MarshalControl: Cannot Marshal control. Not enough space for marshaled control."));
 | 
				
			||||||
 | 
					        EstimatedMarshaledLength = 0;
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    EstimatedMarshaledLength = AdjustedMarshaledLength;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // are we fragmenting?
 | 
				
			||||||
 | 
					    if(NeedToFragment || StartingOffset)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Serial.println(String("MarshalControl:Start Fragment Processing"));
 | 
				
			||||||
 | 
					        // Serial.println(String("MarshalControl:id:                ") + String(id));
 | 
				
			||||||
 | 
					        // Serial.println(String("MarshalControl:StartingOffset:    ") + String(StartingOffset));
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
        if(0 == StartingOffset)
 | 
					        if(0 == StartingOffset)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Serial.println(String("MarshalControl: New control to fragement. ID: ") + String(id));
 | 
					            Serial.println(String("MarshalControl: New control to fragement. ID: ") + String(id));
 | 
				
			||||||
@@ -72,17 +120,18 @@ void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t Starting
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Serial.println(String("MarshalControl: Next fragement. ID: ") + String(id));
 | 
					            Serial.println(String("MarshalControl: Next fragement. ID: ") + String(id));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
		*/
 | 
					*/
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // indicate that no additional controls should be sent
 | 
					        // indicate that no additional controls should be sent
 | 
				
			||||||
 | 
					        ControlIsFragmented = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // fill in the fragment header
 | 
				
			||||||
        _item[F("type")] = uint32_t(ControlType::Fragment);
 | 
					        _item[F("type")] = uint32_t(ControlType::Fragment);
 | 
				
			||||||
        _item[F("id")]   = id;
 | 
					        _item[F("id")]   = id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        length = min((length - StartingOffset), maxLength);
 | 
					 | 
				
			||||||
        // Serial.println(String("MarshalControl:Final length:      ") + String(length));
 | 
					        // Serial.println(String("MarshalControl:Final length:      ") + String(length));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        _item[F("offset")] = StartingOffset;
 | 
					        _item[F("offset")] = StartingOffset;
 | 
				
			||||||
        _item[F("length")] = length;
 | 
					        _item[F("length")] = ValueLenToSend;
 | 
				
			||||||
        _item[F("total")] = value.length();
 | 
					        _item[F("total")] = value.length();
 | 
				
			||||||
        item = _item.createNestedObject(F("control"));
 | 
					        item = _item.createNestedObject(F("control"));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -99,7 +148,7 @@ void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t Starting
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    item[F("label")]   = label;
 | 
					    item[F("label")]   = label;
 | 
				
			||||||
    item[F ("value")]  = (ControlType::Password == type) ? F ("--------") : value.substring(StartingOffset, length + StartingOffset);
 | 
					    item[F ("value")]  = (ControlType::Password == type) ? F ("--------") : value.substring(StartingOffset, StartingOffset + ValueLenToSend);
 | 
				
			||||||
    item[F("visible")] = visible;
 | 
					    item[F("visible")] = visible;
 | 
				
			||||||
    item[F("color")]   = (int)color;
 | 
					    item[F("color")]   = (int)color;
 | 
				
			||||||
    item[F("enabled")] = enabled;
 | 
					    item[F("enabled")] = enabled;
 | 
				
			||||||
@@ -132,6 +181,9 @@ void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t Starting
 | 
				
			|||||||
            item[F("selected")] = "";
 | 
					            item[F("selected")] = "";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Serial.println(String("MarshalControl:Done"));
 | 
				
			||||||
 | 
					    return ControlIsFragmented;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Control::MarshalErrorMessage(JsonObject & item)
 | 
					void Control::MarshalErrorMessage(JsonObject & item)
 | 
				
			||||||
@@ -282,10 +334,3 @@ void Control::onWsEvent(String & cmd, String& data)
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    } while (false);
 | 
					    } while (false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
void Control::EstimateMarshaledSize()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    EstimatedMarshaledSize = MarshalingOverhead + (JsonMarshalingRatio * (strlen(label) + value.length()));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // EstimateSerializedSize
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -83,26 +83,23 @@ public:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void SendCallback(int type);
 | 
					    void SendCallback(int type);
 | 
				
			||||||
    bool HasCallback() { return (nullptr != callback); }
 | 
					    bool HasCallback() { return (nullptr != callback); }
 | 
				
			||||||
    void MarshalControl(ArduinoJson::JsonObject& item, bool refresh, uint32_t DataOffset);
 | 
					    bool MarshalControl(ArduinoJson::JsonObject& item, bool refresh, uint32_t DataOffset, uint32_t MaxLength, uint32_t & EstimmatedUsedSpace);
 | 
				
			||||||
    void MarshalErrorMessage(ArduinoJson::JsonObject& item);
 | 
					    void MarshalErrorMessage(ArduinoJson::JsonObject& item);
 | 
				
			||||||
    void DeleteControl();
 | 
					    void DeleteControl();
 | 
				
			||||||
    void onWsEvent(String& cmd, String& data);
 | 
					    void onWsEvent(String& cmd, String& data);
 | 
				
			||||||
    inline bool ToBeDeleted() { return _ToBeDeleted; }
 | 
					    inline bool ToBeDeleted() { return _ToBeDeleted; }
 | 
				
			||||||
    inline bool NeedsSync(uint32_t lastControlChangeID) {return (false == _ToBeDeleted) && (lastControlChangeID < ControlChangeID);}
 | 
					    inline bool NeedsSync(uint32_t lastControlChangeID) {return (false == _ToBeDeleted) && (lastControlChangeID < ControlChangeID);}
 | 
				
			||||||
    void    SetControlChangedId(uint32_t value) {ControlChangeID = value; EstimateMarshaledSize();}
 | 
					    void    SetControlChangedId(uint32_t value) {ControlChangeID = value;}
 | 
				
			||||||
    uint32_t GetEstimatedMarshaledSize() {return EstimatedMarshaledSize;}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
    bool _ToBeDeleted = false;
 | 
					    bool _ToBeDeleted = false;
 | 
				
			||||||
    uint32_t ControlChangeID = 0;
 | 
					    uint32_t ControlChangeID = 0;
 | 
				
			||||||
    uint32_t EstimatedMarshaledSize = 0;
 | 
					 | 
				
			||||||
    String OldValue = emptyString;
 | 
					    String OldValue = emptyString;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // multiplier for converting a typical controller label and value to a Json object
 | 
					    // multiplier for converting a typical controller label or value to a Json object
 | 
				
			||||||
    #define JsonMarshalingRatio 6
 | 
					    #define JsonMarshalingRatio 3
 | 
				
			||||||
    // estimated number of bytes for the fixed portion of a control rendered as Json
 | 
					    // Marshaed Control overhead length
 | 
				
			||||||
    #define MarshalingOverhead 90
 | 
					    #define JsonMarshaledOverhead 64
 | 
				
			||||||
    void EstimateMarshaledSize();
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UI_TITLE            ControlType::Title
 | 
					#define UI_TITLE            ControlType::Title
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user