FastLED 3.10.6
Loading...
Searching...
No Matches

◆ parseV2SegmentArray()

static bool fl::parseV2SegmentArray ( const fl::json & segmentsArr,
fl::flat_map< string, ScreenMap > * segmentMaps,
string * err )
static

Definition at line 137 of file screenmap.cpp.hpp.

139 {
140 if (!segmentsArr.has_value() || !segmentsArr.is_array()) {
141 *err = "v2 'segments' is not an array";
142 return false;
143 }
144
145 auto arrPtr = segmentsArr.as_array();
146 if (!arrPtr) {
147 *err = "v2 'segments' array could not be read";
148 return false;
149 }
150
151 for (const auto& elem : *arrPtr) {
152 if (!elem) {
153 *err = "v2 segment is null";
154 return false;
155 }
156 fl::json segVal(elem);
157 if (!segVal.has_value() || !segVal.is_object()) {
158 *err = "v2 segment is not an object";
159 return false;
160 }
161
162 // Required: id
163 if (!segVal.contains("id") || !segVal["id"].has_value()) {
164 *err = "v2 segment missing 'id'";
165 return false;
166 }
167 auto idOpt = segVal["id"].as_string();
168 if (!idOpt) {
169 *err = "v2 segment 'id' is not a string";
170 return false;
171 }
172 string id = *idOpt;
173
174 // Required: x
175 if (!segVal.contains("x") || !segVal["x"].has_value() || !segVal["x"].is_array()) {
176 *err = "v2 segment '" + id + "' missing or invalid 'x' array";
177 return false;
178 }
179 fl::vector<float> x_array = jsonArrayToFloatVector(segVal["x"]);
180
181 // Required: y
182 if (!segVal.contains("y") || !segVal["y"].has_value() || !segVal["y"].is_array()) {
183 *err = "v2 segment '" + id + "' missing or invalid 'y' array";
184 return false;
185 }
186 fl::vector<float> y_array = jsonArrayToFloatVector(segVal["y"]);
187
188 string type = "led_strip";
189 if (segVal.contains("type") && segVal["type"].has_value()) {
190 auto typeOpt = segVal["type"].as_string();
191 if (!typeOpt) { *err = "v2 segment '" + id + "' has invalid 'type'"; return false; }
192 type = *typeOpt;
193 }
194 const bool isWire = type == "el_wire";
195 const bool isPanel = type == "el_panel";
196 if (type != "led_strip" && !isWire && !isPanel) {
197 *err = "v2 segment '" + id + "' has unsupported type '" + type + "'";
198 return false;
199 }
200 if (x_array.size() != y_array.size()) {
201 *err = "v2 segment '" + id + "' has mismatched x/y lengths";
202 return false;
203 }
204 const size_t minVertices = isWire ? 2 : isPanel ? 3 : 0;
205 if ((isWire || isPanel) && x_array.size() < minVertices) {
206 *err = "v2 segment '" + id + "' has too few vertices";
207 return false;
208 }
209 float thickness = 0.0f;
210 if (isWire) {
211 if (!segVal.contains("thickness") || !segVal["thickness"].has_value()) {
212 *err = "v2 el_wire segment '" + id + "' missing thickness";
213 return false;
214 }
215 auto thicknessOpt = segVal["thickness"].as_float();
216 if (!thicknessOpt || *thicknessOpt <= 0.0f) {
217 *err = "v2 el_wire segment '" + id + "' requires positive thickness";
218 return false;
219 }
220 thickness = static_cast<float>(*thicknessOpt);
221 } else if (segVal.contains("thickness")) {
222 *err = "v2 segment '" + id + "' thickness is only valid for el_wire";
223 return false;
224 }
225
226 // Optional: diameter (not in canonical v2 but accepted as a backward-compat
227 // hint when present; otherwise the per-group `diameter` could be wired here
228 // in a future iteration).
229 float diameter = -1.0f;
230 if (segVal.contains("diameter") && segVal["diameter"].has_value()) {
231 auto diameterOpt = segVal["diameter"].as_float();
232 if (diameterOpt) {
233 diameter = static_cast<float>(*diameterOpt);
234 }
235 }
236
237 auto n = fl::min(x_array.size(), y_array.size());
238 ScreenMap segment_map(isWire || isPanel ? 1 : static_cast<u32>(n), diameter);
239 if (isWire || isPanel) {
240 fl::vector<vec2f> vertices;
241 vertices.reserve(n);
242 for (size_t i = 0; i < n; i++) vertices.push_back({x_array[i], y_array[i]});
243 segment_map.setShape(0, isWire ? ScreenMap::Shape::EL_WIRE : ScreenMap::Shape::EL_PANEL, vertices.data(), static_cast<u32>(n), thickness);
244 }
245 if (!isWire && !isPanel) {
246 for (size_t i = 0; i < n; i++) {
247 segment_map.set(static_cast<u16>(i), vec2f{x_array[i], y_array[i]});
248 }
249 }
250 (*segmentMaps)[id] = fl::move(segment_map);
251 }
252 return true;
253}
bool has_value() const FL_NO_EXCEPT
Definition json.h:819
bool is_array() const FL_NO_EXCEPT
Definition json.h:389
const json_array * as_array() const FL_NO_EXCEPT
Definition json.h:448
fl::size size() const FL_NO_EXCEPT
void reserve(fl::size n) FL_NO_EXCEPT
Definition vector.h:591
T * data() FL_NO_EXCEPT
Definition vector.h:619
void push_back(const T &value) FL_NO_EXCEPT
Definition vector.h:624
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:28
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NO_EXCEPT
Definition math.h:71
vec2< float > vec2f
Definition geometry.h:333
fl::vector< float > jsonArrayToFloatVector(const fl::json &jsonArray)

References fl::json::as_float(), fl::json::as_string(), fl::json::contains(), fl::vector< T >::data(), fl::ScreenMap::Shape::EL_PANEL, fl::ScreenMap::Shape::EL_WIRE, FL_NO_EXCEPT, fl::json::has_value(), fl::json::is_array(), fl::json::is_object(), jsonArrayToFloatVector(), min(), move(), fl::vector< T >::push_back(), fl::vector< T >::reserve(), fl::ScreenMap::set(), fl::ScreenMap::setShape(), and fl::vector_basic::size().

Referenced by fl::ScreenMap::ParseJson().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: