(request)
| 590 | return web.json_response(state.animator.to_list()) |
| 591 | |
| 592 | async def ws_handler(request): |
| 593 | ws = web.WebSocketResponse() |
| 594 | await ws.prepare(request) |
| 595 | print("[ws] Client connected") |
| 596 | |
| 597 | # Send initial frame |
| 598 | try: |
| 599 | frame_data = state.render() |
| 600 | if frame_data: |
| 601 | await ws.send_bytes(frame_data) |
| 602 | print(f"[ws] Sent initial frame ({len(frame_data)} bytes)") |
| 603 | except Exception as e: |
| 604 | print(f"[ws] Error sending initial frame: {e}") |
| 605 | |
| 606 | need_render = False |
| 607 | |
| 608 | async for msg in ws: |
| 609 | if msg.type == web.WSMsgType.TEXT: |
| 610 | data = json.loads(msg.data) |
| 611 | t = data.get("type") |
| 612 | |
| 613 | if t == "orbit": |
| 614 | state.camera.orbit(data["dx"], data["dy"]) |
| 615 | need_render = True |
| 616 | elif t == "pan": |
| 617 | state.camera.pan(data["dx"], data["dy"]) |
| 618 | need_render = True |
| 619 | elif t == "zoom": |
| 620 | state.camera.zoom(data["delta"]) |
| 621 | need_render = True |
| 622 | elif t == "move": |
| 623 | speed = move_speed_base |
| 624 | if data.get("shift"): |
| 625 | speed *= 3.0 |
| 626 | d = data["dir"] |
| 627 | if d == "forward": |
| 628 | state.camera.move_forward(speed) |
| 629 | elif d == "backward": |
| 630 | state.camera.move_forward(-speed) |
| 631 | elif d == "right": |
| 632 | state.camera.move_right(speed) |
| 633 | elif d == "left": |
| 634 | state.camera.move_right(-speed) |
| 635 | elif d == "up": |
| 636 | state.camera.move_up(speed) |
| 637 | elif d == "down": |
| 638 | state.camera.move_up(-speed) |
| 639 | need_render = True |
| 640 | elif t == "set_frame": |
| 641 | state.frame_idx = int(data["value"]) |
| 642 | state._dirty_geometry = True |
| 643 | need_render = True |
| 644 | elif t == "set_display_mode": |
| 645 | state.display_mode = data["value"] |
| 646 | state._dirty_geometry = True |
| 647 | need_render = True |
| 648 | elif t == "set_conf_threshold": |
| 649 | state.conf_threshold = float(data["value"]) |
nothing calls this directly
no test coverage detected