Attach the missed-graph skeleton (#963) to the primary layout doc as * "missed_graph": {"nodes":[...], "edges":[...], "offset":{x,y,z}} * — the file structure of files the indexer could not fully cover, laid out * as a satellite cluster beside the code galaxy (the UI renders it as a white * skeleton; clicking it re-centers the camera there). The offset sits on the * -Y side: linked-project
| 1316 | * this slot collides last. Returns true when a non-empty skeleton was |
| 1317 | * attached; no-op when the project has no missed files. */ |
| 1318 | static bool attach_missed_graph(yyjson_mut_doc *mdoc, yyjson_mut_val *mroot, cbm_store_t *store, |
| 1319 | const char *project, double primary_radius) { |
| 1320 | char covproj[512]; |
| 1321 | cbm_store_coverage_shadow_project(covproj, sizeof(covproj), project); |
| 1322 | cbm_layout_result_t *ml = cbm_layout_compute(store, covproj, CBM_LAYOUT_OVERVIEW, NULL, 0, 0); |
| 1323 | if (!ml) { |
| 1324 | return false; |
| 1325 | } |
| 1326 | if (ml->node_count == 0) { |
| 1327 | cbm_layout_free(ml); |
| 1328 | return false; |
| 1329 | } |
| 1330 | double miss_radius = layout_radius(ml); |
| 1331 | char *mjson = cbm_layout_to_json(ml); |
| 1332 | cbm_layout_free(ml); |
| 1333 | if (!mjson) { |
| 1334 | return false; |
| 1335 | } |
| 1336 | yyjson_doc *mldoc = yyjson_read(mjson, strlen(mjson), 0); |
| 1337 | free(mjson); |
| 1338 | if (!mldoc) { |
| 1339 | return false; |
| 1340 | } |
| 1341 | yyjson_mut_val *entry = yyjson_mut_obj(mdoc); |
| 1342 | yyjson_val *mlroot = yyjson_doc_get_root(mldoc); |
| 1343 | yyjson_val *mn = yyjson_obj_get(mlroot, "nodes"); |
| 1344 | yyjson_val *me = yyjson_obj_get(mlroot, "edges"); |
| 1345 | if (mn) { |
| 1346 | yyjson_mut_obj_add_val(mdoc, entry, "nodes", yyjson_val_mut_copy(mdoc, mn)); |
| 1347 | } |
| 1348 | if (me) { |
| 1349 | yyjson_mut_obj_add_val(mdoc, entry, "edges", yyjson_val_mut_copy(mdoc, me)); |
| 1350 | } |
| 1351 | yyjson_doc_free(mldoc); |
| 1352 | |
| 1353 | double dist = primary_radius + miss_radius + LAYOUT_GALAXY_PAD; |
| 1354 | if (dist < LAYOUT_GALAXY_SPACING) { |
| 1355 | dist = LAYOUT_GALAXY_SPACING; |
| 1356 | } |
| 1357 | yyjson_mut_val *offset = yyjson_mut_obj(mdoc); |
| 1358 | yyjson_mut_obj_add_real(mdoc, offset, "x", 0.0); |
| 1359 | yyjson_mut_obj_add_real(mdoc, offset, "y", -dist); |
| 1360 | yyjson_mut_obj_add_real(mdoc, offset, "z", 0.0); |
| 1361 | yyjson_mut_obj_add_val(mdoc, entry, "offset", offset); |
| 1362 | |
| 1363 | yyjson_mut_obj_add_val(mdoc, mroot, "missed_graph", entry); |
| 1364 | return true; |
| 1365 | } |
| 1366 | |
| 1367 | static void handle_layout(cbm_http_conn_t *c, const cbm_http_req_t *req) { |
| 1368 | char project[256] = {0}; |
no test coverage detected