Merge branch 'json-mapping' into mdev

This commit is contained in:
Ewowi
2022-10-01 12:17:11 +02:00

View File

@@ -472,69 +472,69 @@ uint16_t Segment::nrOfVStrips() const {
} }
//WLEDSR jMap //WLEDSR jMap
struct XandY {
uint8_t x;
uint8_t y;
};
struct ArrayAndSize {
uint8_t size;
XandY *array;
};
class JMapC { class JMapC {
public: public:
char previousSegmentName[50] = ""; char previousSegmentName[50] = "";
~JMapC() { ~JMapC() {
Serial.println("~JMapC"); Serial.println("~JMapC");
if (jMapDoc) { deletejVectorMap();
delete jMapDoc; jMapDoc = nullptr; }
void deletejVectorMap() {
if (jVectorMap.size() > 0) {
Serial.println("delete jVectorMap");
for (int i=0; i<jVectorMap.size(); i++)
delete jVectorMap[i].array;
jVectorMap.clear();
} }
} }
uint16_t length() { uint16_t length() {
updatejMapDoc(); updatejMapDoc();
if (jMapDoc) size_t size = jVectorMap.size();
return jMapDoc->size(); if (size > 0)
return size;
else else
return SEGMENT.virtualWidth() * SEGMENT.virtualHeight(); //pixels return SEGMENT.virtualWidth() * SEGMENT.virtualHeight(); //pixels
} }
void setPixelColor(uint16_t i, uint32_t col) { void setPixelColor(uint16_t i, uint32_t col) {
updatejMapDoc(); updatejMapDoc();
if (jMapDoc) { if (jVectorMap.size() > i) {
if (i==0) { if (i==0) {
SEGMENT.fadeToBlackBy(10); //as not all pixels used SEGMENT.fadeToBlackBy(10); //as not all pixels used
} }
//get itH element of jMap and use x and y to sPCXY call (or multiple calls if tuples) for (int j=0; j<jVectorMap[i].size; j++) {
JsonArray outerArray = jMapDoc->as<JsonArray>(); SEGMENT.setPixelColorXY(jVectorMap[i].array[j].x * scale, jVectorMap[i].array[j].y * scale, col);
if (outerArray[i][0].is<JsonArray>()){
for (JsonVariant innerElement: outerArray[i].as<JsonArray>()) {
SEGMENT.setPixelColorXY(innerElement[0].as<uint16_t>() * scale, innerElement[1].as<uint16_t>() * scale, col);
}
}
else {
SEGMENT.setPixelColorXY(outerArray[i][0].as<uint16_t>() * scale, outerArray[i][1].as<uint16_t>() * scale, col);
// SEGMENT.drawLine(outerArray[i][0].as<uint16_t>()*scale, outerArray[i-1][0].as<uint16_t>()*scale, outerArray[i-1][0].as<uint16_t>()*scale, outerArray[i][1].as<uint16_t>()*scale, col);
} }
} }
} }
uint32_t getPixelColor(uint16_t i) { uint32_t getPixelColor(uint16_t i) {
updatejMapDoc(); updatejMapDoc();
if (jMapDoc) { if (jVectorMap.size() > 0)
JsonArray outerArray = jMapDoc->as<JsonArray>(); return SEGMENT.getPixelColorXY(jVectorMap[i].array[0].x * scale, jVectorMap[i].array[0].y * scale);
if (outerArray[i][0].is<JsonArray>()) else
return SEGMENT.getPixelColorXY(outerArray[i][0][0].as<uint16_t>() * scale, outerArray[i][0][1].as<uint16_t>() * scale); return 0;
else
return SEGMENT.getPixelColorXY(outerArray[i][0].as<uint16_t>() * scale, outerArray[i][1].as<uint16_t>() * scale);
}
return 0;
} }
private: private:
PSRAMDynamicJsonDocument *jMapDoc = nullptr; std::vector<ArrayAndSize> jVectorMap;
StaticJsonDocument<4096> docChunk; //must fit forks with about 32 points each
uint8_t scale; uint8_t scale;
void updatejMapDoc() { void updatejMapDoc() {
if (jMapDoc && SEGMENT.name == nullptr) { if (SEGMENT.name == nullptr && jVectorMap.size() > 0) {
Serial.println("Delete jMapDoc"); deletejVectorMap();
delete jMapDoc; jMapDoc = nullptr;
} }
else if (SEGMENT.name != nullptr && strcmp(SEGMENT.name, previousSegmentName) != 0) {
if (!jMapDoc && SEGMENT.name != nullptr && SEGMENT.map1D2D == M12_jMap) { uint32_t dataSize = 0;
Serial.println("Create jMapDoc"); deletejVectorMap();
jMapDoc = new PSRAMDynamicJsonDocument(5*4096); Serial.print("New "); Serial.println(SEGMENT.name);
}
if (jMapDoc && SEGMENT.name != nullptr && strcmp(SEGMENT.name, previousSegmentName) != 0) {
Serial.println("New name");
char jMapFileName[50]; char jMapFileName[50];
strcpy(jMapFileName, "/"); strcpy(jMapFileName, "/");
strcat(jMapFileName, SEGMENT.name); strcat(jMapFileName, SEGMENT.name);
@@ -542,35 +542,62 @@ class JMapC {
File jMapFile; File jMapFile;
jMapFile = WLED_FS.open(jMapFileName, "r"); jMapFile = WLED_FS.open(jMapFileName, "r");
DeserializationError err = deserializeJson(*jMapDoc, jMapFile);
if (err)
{
Serial.printf("deserializeJson() of parseTree failed with code %s\n", err.c_str());
delete[] SEGMENT.name; SEGMENT.name = nullptr; //need to clear the name as otherwise continuously loaded
return;
}
//get the width and height of the jMap
uint8_t maxWidth = 0; uint8_t maxWidth = 0;
uint8_t maxHeight = 0; uint8_t maxHeight = 0;
JsonArray outerArray = jMapDoc->as<JsonArray>();
for (JsonVariant outerElement: outerArray) { //https://arduinojson.org/v6/how-to/deserialize-a-very-large-document/
if (outerElement[0].is<JsonArray>()){ jMapFile.find("[");
for (JsonVariant innerElement: outerElement.as<JsonArray>()) { do {
maxWidth = MAX(maxWidth, innerElement[0].as<uint16_t>()); DeserializationError err = deserializeJson(docChunk, jMapFile);
maxHeight = MAX(maxHeight, innerElement[1].as<uint16_t>()); // serializeJson(docChunk, Serial); Serial.println();
// Serial.printf("docChunk %u / %u%% (%u %u %u) %u\n", (unsigned int)docChunk.memoryUsage(), 100 * docChunk.memoryUsage() / docChunk.capacity(), (unsigned int)docChunk.size(), docChunk.overflowed(), (unsigned int)docChunk.nesting(), jMapFile.size());
if (err)
{
Serial.printf("deserializeJson() of parseTree failed with code %s\n", err.c_str());
delete[] SEGMENT.name; SEGMENT.name = nullptr; //need to clear the name as otherwise continuously loaded
return;
}
if (docChunk.is<JsonArray>()) { //each item is or an array of arrays (fork) or an array of x,y (no fork)
//fill the vector with arrays and get the width and height of the jMap
JsonArray arrayChunk = docChunk.as<JsonArray>();
ArrayAndSize arrayAndSize;
arrayAndSize.size = 0;
if (arrayChunk[0].is<JsonArray>()) { //if array of arrays
arrayAndSize.array = new XandY[arrayChunk.size()];
for (JsonVariant arrayElement: arrayChunk) {
maxWidth = MAX(maxWidth, arrayElement[0].as<uint8_t>());
maxHeight = MAX(maxHeight, arrayElement[1].as<uint8_t>());
arrayAndSize.array[arrayAndSize.size].x = arrayElement[0].as<uint8_t>();
arrayAndSize.array[arrayAndSize.size].y = arrayElement[1].as<uint8_t>();
arrayAndSize.size++;
dataSize += sizeof(XandY);
}
} }
else { // if array (of x and y)
arrayAndSize.array = new XandY[1];
maxWidth = MAX(maxWidth, arrayChunk[0].as<uint8_t>());
maxHeight = MAX(maxHeight, arrayChunk[1].as<uint8_t>());
arrayAndSize.array[arrayAndSize.size].x = arrayChunk[0].as<uint8_t>();
arrayAndSize.array[arrayAndSize.size].y = arrayChunk[1].as<uint8_t>();
arrayAndSize.size++;
dataSize += sizeof(XandY);
}
jVectorMap.push_back(arrayAndSize);
dataSize += sizeof(arrayAndSize);
} }
else {
maxWidth = MAX(maxWidth, outerElement[0].as<uint16_t>()); } while (jMapFile.findUntil(",", "]"));
maxHeight = MAX(maxHeight, outerElement[1].as<uint16_t>());
}
}
maxWidth++; maxHeight++; maxWidth++; maxHeight++;
scale = MIN(SEGMENT.virtualWidth() / maxWidth, SEGMENT.virtualHeight() / maxHeight); scale = MIN(SEGMENT.virtualWidth() / maxWidth, SEGMENT.virtualHeight() / maxHeight);
Serial.printf("jMapDoc %u / %u%% (%u %u %u)\n", (unsigned int)jMapDoc->memoryUsage(), 100 * jMapDoc->memoryUsage() / jMapDoc->capacity(), (unsigned int)jMapDoc->size(), jMapDoc->overflowed(), (unsigned int)jMapDoc->nesting()); dataSize += sizeof(jVectorMap);
Serial.print("dataSize ");
Serial.print(dataSize);
Serial.print(" scale ");
Serial.println(scale); Serial.println(scale);
// serializeJson(*jMapDoc, Serial); Serial.println();
strcpy(previousSegmentName, SEGMENT.name); strcpy(previousSegmentName, SEGMENT.name);
} }
} //updatejMapDoc } //updatejMapDoc