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
| 1444 | * this slot collides last. Returns true when a non-empty skeleton was |
| 1445 | * attached; no-op when the project has no missed files. */ |
| 1446 | static bool attach_missed_graph(yyjson_mut_doc *mdoc, yyjson_mut_val *mroot, cbm_store_t *store, |
| 1447 | const char *project, double primary_radius) { |
| 1448 | char covproj[512]; |
| 1449 | cbm_store_coverage_shadow_project(covproj, sizeof(covproj), project); |
| 1450 | cbm_layout_result_t *ml = cbm_layout_compute(store, covproj, CBM_LAYOUT_OVERVIEW, NULL, 0, 0); |
| 1451 | if (!ml) { |
| 1452 | return false; |
| 1453 | } |
| 1454 | if (ml->node_count == 0) { |
| 1455 | cbm_layout_free(ml); |
| 1456 | return false; |
| 1457 | } |
| 1458 | double miss_radius = layout_radius(ml); |
| 1459 | char *mjson = cbm_layout_to_json(ml); |
| 1460 | cbm_layout_free(ml); |
| 1461 | if (!mjson) { |
| 1462 | return false; |
| 1463 | } |
| 1464 | yyjson_doc *mldoc = yyjson_read(mjson, strlen(mjson), 0); |
| 1465 | free(mjson); |
| 1466 | if (!mldoc) { |
| 1467 | return false; |
| 1468 | } |
| 1469 | yyjson_mut_val *entry = yyjson_mut_obj(mdoc); |
| 1470 | yyjson_val *mlroot = yyjson_doc_get_root(mldoc); |
| 1471 | yyjson_val *mn = yyjson_obj_get(mlroot, "nodes"); |
| 1472 | yyjson_val *me = yyjson_obj_get(mlroot, "edges"); |
| 1473 | if (mn) { |
| 1474 | yyjson_mut_obj_add_val(mdoc, entry, "nodes", yyjson_val_mut_copy(mdoc, mn)); |
| 1475 | } |
| 1476 | if (me) { |
| 1477 | yyjson_mut_obj_add_val(mdoc, entry, "edges", yyjson_val_mut_copy(mdoc, me)); |
| 1478 | } |
| 1479 | yyjson_doc_free(mldoc); |
| 1480 | |
| 1481 | double dist = primary_radius + miss_radius + LAYOUT_GALAXY_PAD; |
| 1482 | if (dist < LAYOUT_GALAXY_SPACING) { |
| 1483 | dist = LAYOUT_GALAXY_SPACING; |
| 1484 | } |
| 1485 | yyjson_mut_val *offset = yyjson_mut_obj(mdoc); |
| 1486 | yyjson_mut_obj_add_real(mdoc, offset, "x", 0.0); |
| 1487 | yyjson_mut_obj_add_real(mdoc, offset, "y", -dist); |
| 1488 | yyjson_mut_obj_add_real(mdoc, offset, "z", 0.0); |
| 1489 | yyjson_mut_obj_add_val(mdoc, entry, "offset", offset); |
| 1490 | |
| 1491 | yyjson_mut_obj_add_val(mdoc, mroot, "missed_graph", entry); |
| 1492 | return true; |
| 1493 | } |
| 1494 | |
| 1495 | static void handle_layout(cbm_http_conn_t *c, const cbm_http_req_t *req) { |
| 1496 | char project[256] = {0}; |
no test coverage detected