controller: Phase 7 dispatch — set_layout + cell_map (вместо streamselect)
Sync с n7.1-vf-cuda-grid-phase7 filter rework (один cuda_grid + native
runtime layout switching). Изменения:
dispatch._set_layout:
target: layout_filter_target (default cuda_grid@cg, был streamselect@layout)
command: "set_layout <name>" (был "map <index>")
validation: PREDEFINED_LAYOUTS (был inst.layout_map)
dispatch.set_main_cam:
target: main_cam_filter_target (default cuda_grid@cg, был streamselect@main_cam)
command: "cell_map <cell> <pad>" × max_cells
cell 0 = main camera; cells 1..N-1 = identity rotation остальных pads
(исключая main чтобы не дублировать в preview cells)
dispatch.set_mpp_main:
alias к set_main_cam — main_plus_preview тоже использует cell 0 как main.
config.InstanceCfg:
layout_filter_target / main_cam_filter_target / mpp_main_filter_target
default = cuda_grid@cg (Phase 7 single filter)
new max_cells: int = 4 (соответствует filter max_cells option)
layout_map deprecated — оставлен для UI subset visibility (HTTP /layouts/{inst})
http_api.set_layout:
validation против PREDEFINED_LAYOUTS вместо layout_map
Frigate bridge не меняется — set_main_cam подпись та же (instance, cam_index).
Compile-test OK. Pipeline image: gx/cuda-grid-pipeline:phase7. Controller
image rebuild требуется для deploy.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -82,10 +82,11 @@ def create_app(
|
||||
|
||||
@app.post("/layout/{instance}/set")
|
||||
async def set_layout(instance: str, req: LayoutSetReq) -> dict[str, Any]:
|
||||
inst = _check_instance(instance)
|
||||
if req.layout not in inst.layout_map:
|
||||
_check_instance(instance)
|
||||
# Phase 7: validation против built-in PREDEFINED_LAYOUTS (filter ground truth).
|
||||
if req.layout not in PREDEFINED_LAYOUTS:
|
||||
raise HTTPException(
|
||||
400, f"unknown layout '{req.layout}'. Доступны: {list(inst.layout_map.keys())}"
|
||||
400, f"unknown layout '{req.layout}'. Доступны: {PREDEFINED_LAYOUTS}"
|
||||
)
|
||||
await dispatcher.handle(instance, "layout.set", req.layout)
|
||||
return {"ok": True, "instance": instance, "layout": req.layout}
|
||||
@@ -93,9 +94,12 @@ def create_app(
|
||||
@app.get("/layouts/{instance}")
|
||||
async def layouts_for_instance(instance: str) -> dict[str, Any]:
|
||||
inst = _check_instance(instance)
|
||||
# UI shows только то что объявлено в config layout_map (subset). Если пуст —
|
||||
# все доступные filter layouts.
|
||||
ui_layouts = list(inst.layout_map.keys()) if inst.layout_map else PREDEFINED_LAYOUTS
|
||||
return {
|
||||
"instance": instance,
|
||||
"layouts": list(inst.layout_map.keys()),
|
||||
"layouts": ui_layouts,
|
||||
"current": await state.get_layout(instance),
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user