feat: camera-restore + LauncherUI UX 개선 + player fallback 강화 (#15)

camera-restore:
- IEngineStateProvider.SetCamera 반사 쓰기 (HmegDirectStateProvider)
- POST /camera/restore (BridgeHttpServer, StateRouter)
- Recorder --sidecar-url + camera_snapshot 캡처
- UiaPlayerHost.TryRestoreCamera, PlayerEngine 재생 전 복원
- 149 tests

LauncherUI (#15):
- Sidecar URL 체크박스 + 입력란 (녹화/재생 모두 연동)
- 재생 속도 슬라이더 (0.25x~4.0x, 기본 1.0x)
- 빌드 타임스탬프 타이틀바 표시
- 녹화 완료 후 RecordNameBox 초기화
- UiAnalysisWindow 추가

PlayerEngine (#15):
- CancellationToken 지원 (중단 버튼 동작)
- Focus 스텝 early return (no-op, issue #11)
- Type/Drag unresolvable UIA path fallback
- SpeedMultiplier 옵션

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
minsung
2026-04-13 18:37:13 +09:00
parent 6bc71afd32
commit 11eb92b2b2
32 changed files with 1658 additions and 46 deletions

View File

@@ -15,6 +15,12 @@ public interface IEngineStateProvider
CameraSnapshot GetCamera();
SceneSnapshot GetScene();
bool GetRenderComplete();
/// <summary>
/// Restore the camera state in the live SUT. Best-effort: implementations
/// that cannot write the camera (reflection fallback, null provider) must
/// swallow any exception and return silently.
/// </summary>
void SetCamera(CameraSnapshot snapshot);
}
public sealed record CameraSnapshot(double[] Eye, double[] Target, double[] Up, double Fov);
@@ -34,4 +40,5 @@ public sealed class NullEngineStateProvider : IEngineStateProvider
45.0);
public SceneSnapshot GetScene() => new(0, null);
public bool GetRenderComplete() => true;
public void SetCamera(CameraSnapshot snapshot) { /* no-op */ }
}