Commit 70cd5ee
UI modernization PR 8: extract CaptureEngine from CameraViewController (#129)
* Extract CaptureEngine from CameraViewController (UI modernization PR 8)
Mechanical extraction, no behavior or threading changes. CaptureEngine
(non-UI, NSObject, the AVCapturePhotoCaptureDelegate) now owns the
capture session, device/lens/zoom discovery, capabilities gathering,
flash/torch intent, quality/format/aspect configuration, and still
capture + crop math.
CameraViewController (~1,670 → ~960 lines) keeps the preview layer,
overlays, permissions, lifecycle, and the recording/sample-buffer
pipeline (queued for a later PR), reaching the session through
engine-exposed properties. Engine-to-UI seams: onPicture (relayed to
the actor system by the VC), onStatusChanged, and
rotateOutputs(orientation:) — the VC still rotates the preview-layer
connection, preserving the original method's exact shape.
CropRectTests re-point to CaptureEngine.cropRect (assertions
unchanged); adds 4 CaptureEngineTests for session-free logic.
376/376 tests pass (372 existing + 4 new), verified in two independent
full runs.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Add back-to-back camera-control round-trip tests
Five more loopback happy paths now that the fake camera sits behind the
CameraControlling seam:
- toggle flash: the flipped mode value crosses back in the response
- toggle camera: response carries fresh non-nil capabilities
- set zoom: factor and zoom range echo through the FlatBuffers round trip
- switch lens: telephoto request in, confirmation out
- video recording: full 3-step stop protocol (StopRecordingVideo -> Ack
-> Resp) across both state machines, camera back to .camera, monitor
back to .monitor
LoopbackFakeCamera completes a stopped recording by injecting
StopRecordingVideoResp, the way the real pipeline's completion does.
Also documents (Docs/UI_MODERNIZATION.md) a latent bug found while
wiring the video test: the success StartRecordingVideoAck carrying
recordingStartTime is dropped on the phone path (no state forwards it
to the peer); only the error-ack path reaches the monitor. Left for its
own fix PR with a failing test.
381/381 tests pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Fix dropped StartRecordingVideoAck on the phone path
The recording pipeline sends the success StartRecordingVideoAck
(carrying recordingStartTime for the monitor's timer sync) to the local
session actor, but cameraShootingVideo had no case for it — the ack
died in Theater's unhandled-message log and the monitor's recording
timer never synced the actual start time. The watch path handles the
ack explicitly, which masked the phone-path gap.
Fix: forward the ack to the peer from cameraShootingVideo. Caught by
the new loopback video-protocol test (asserted red before the fix,
green after).
381/381 tests pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Harden onPicture delivery and fix a doc claim
Capture the session ActorRef directly in the engine's onPicture closure
instead of going through weak self, so an in-flight capture still reaches
the actor if the VC deallocates before the photo delegate fires (master
had this guarantee implicitly via the VC being the retained delegate).
Also correct the PR 8 worklog line: CaptureEngine does import UIKit —
orientation enums plus UIImage for still cropping.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent ebf633b commit 70cd5ee
9 files changed
Lines changed: 1216 additions & 833 deletions
File tree
- Docs
- RemoteCamTests
- RemoteCam
- RemoteShutter.xcodeproj
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
124 | 124 | | |
125 | 125 | | |
126 | 126 | | |
127 | | - | |
| 127 | + | |
128 | 128 | | |
129 | 129 | | |
130 | 130 | | |
| |||
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
143 | | - | |
144 | | - | |
145 | | - | |
146 | | - | |
147 | | - | |
148 | | - | |
149 | | - | |
150 | | - | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
151 | 154 | | |
152 | 155 | | |
153 | 156 | | |
| |||
252 | 255 | | |
253 | 256 | | |
254 | 257 | | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
57 | 57 | | |
58 | 58 | | |
59 | 59 | | |
60 | | - | |
| 60 | + | |
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
46 | 46 | | |
47 | 47 | | |
48 | 48 | | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
49 | 55 | | |
50 | 56 | | |
51 | 57 | | |
| |||
0 commit comments