diff --git a/apps/studio/docs/record-channel.md b/apps/studio/docs/record-channel.md index 2bbe988..e2ab314 100644 --- a/apps/studio/docs/record-channel.md +++ b/apps/studio/docs/record-channel.md @@ -318,7 +318,7 @@ SDK 版本,「由视频重算」前这些提示必须让操作者看到(回 ### 回放界面 回放**与实时是同一套界面**:`ui/playback_dialog.py`、`ui/replay_bar.py` 与深度重算引擎都 -已删除。`replay.py::ReplayController` 只读录制并发信号,主窗口把它接到同一套面板上—— +已删除。`replay.py::ReplayEngine` 只读录制并发信号,主窗口把它接到同一套面板上—— 状态轨的主按钮在回放视图里变成「▶ 回放 / ⏸ 暂停」(`toolbar.set_run_role`),来源槽换成 「选择录制视频…」。布局、单位、看点与关闭流程见 `docs/shell-lifecycle.md` §2 (含「由视频重算」复核模式)。 diff --git a/apps/studio/docs/shell-lifecycle.md b/apps/studio/docs/shell-lifecycle.md index f090dec..03652bd 100644 --- a/apps/studio/docs/shell-lifecycle.md +++ b/apps/studio/docs/shell-lifecycle.md @@ -60,11 +60,14 @@ 同一套图表手势。**唯一的差别是左上的来源槽**——实时是摄像机,回放是一段录制视频。 `ui/replay_bar.py`(进度条 + 录制目录选择)与 `PlaybackDialog` 都已删除。 -- `apps/studio/src/orisys_studio/replay.py::ReplayController(QObject)`:录制读取、游标、 +- `apps/studio/src/orisys_studio/replay.py::ReplayEngine(QObject)`:录制读取、游标、 回放提示(降采样 / 跨版本)。它不画任何东西,只发信号:`position_changed` / `frames_changed` / `status_changed` / `recording_changed`。深度重算引擎 (`DepthRecomputer` / `depth_backends`)已随回放条一起删除——用户不需要这条回放路径, 要复核算法就用「由视频重算」。 + 它叫 *engine* 是因为它只回答「t 时刻是什么」;传输策略(何时开始、播完意味着什么、 + 重算是否在跑)与 2D 渲染属于窗口级的 `ReplayController`(见 + `docs/architecture/studio-architecture.md` 建议 1)。 - **选视频即选录制**:状态轨的「选择录制视频…」(`toolbar.btn_replay_video`)与 「文件 → 打开视频…」都走 `_load_replay_video(path)`——视频所在目录就是录制目录, 于是曲线自动配对同目录的 `forces.csv`。视频与 CSV 仍然同时记录(录制格式不变)。 diff --git a/apps/studio/src/orisys_studio/app_window.py b/apps/studio/src/orisys_studio/app_window.py index bbabe1d..2d30c8f 100644 --- a/apps/studio/src/orisys_studio/app_window.py +++ b/apps/studio/src/orisys_studio/app_window.py @@ -48,7 +48,7 @@ from orisys_app_shared.paths import recordings_dir from orisys_app_shared.record import RecordConfig from orisys_app_shared.record.sample import to_record_sample from orisys_studio.recording import RecordingCoordinator, record_config_from_prefs -from orisys_studio.replay import ReplayController +from orisys_studio.replay import ReplayEngine from orisys_studio.scene3d.prefs import settings_to_prefs from orisys_app_shared.i18n import set_locale, t from orisys_app_shared.logging import report_error @@ -190,8 +190,10 @@ class StudioMainWindow(QMainWindow): self._run_source_label = "" # ---- replay --------------------------------------------------------- # One engine for the history view: the recording reader, the cursor and - # the asynchronous depth recomputation. It renders nothing itself. - self.replay = ReplayController(self) + # the asynchronous depth recomputation. It renders nothing itself; the + # transport policy around it will move into a ReplayController (see + # docs/architecture/studio-architecture.md, suggestion 1). + self.replay = ReplayEngine(self) # ---- record channel ------------------------------------------------- # Fed from the acquisition thread via the worker's sink list, so it does # not depend on the UI refresh rate or on which panels are visible. diff --git a/apps/studio/src/orisys_studio/replay.py b/apps/studio/src/orisys_studio/replay.py index 8324c7a..a88bb81 100644 --- a/apps/studio/src/orisys_studio/replay.py +++ b/apps/studio/src/orisys_studio/replay.py @@ -6,6 +6,12 @@ panel, the curves read the recording through :class:`~orisys_app_shared.force.source.RecordingCurveSource`, and the transport on the chart header drives :meth:`set_position`. +It is an *engine*, not a controller: it answers "what is at t?" and knows nothing about +the transport's policy (when to start, what the end of the timeline means, whether a +recompute pass is running) or about the widgets. That policy lives in +``ReplayController`` (the window-level controller for this view), which is why the two +names are deliberately different — see ``apps/studio/docs/shell-lifecycle.md``. + There is no depth recomputation here: depth is not stored with a recording, the replay view shows the recorded frames, and re-running the pipeline over a video is the acquisition path's job (see the studio's "recompute" mode). @@ -37,7 +43,7 @@ def _sdk_version() -> str: return "" -class ReplayController(QObject): +class ReplayEngine(QObject): """Open one recording and answer "what is at t?" for every view.""" #: The cursor moved; the chart cursor and the 2D panel follow. diff --git a/apps/studio/tools/ui_check.py b/apps/studio/tools/ui_check.py index bef1e12..0d0d0b4 100644 --- a/apps/studio/tools/ui_check.py +++ b/apps/studio/tools/ui_check.py @@ -2972,7 +2972,7 @@ def main() -> int: recorder.on_packet(_fake_packet(index)) recorder.stop() - from orisys_studio.replay import ReplayController + from orisys_studio.replay import ReplayEngine # The replay lives in the main window: one engine, one progress bar, and the # charts read the recording itself. diff --git a/docs/architecture/studio-architecture.md b/docs/architecture/studio-architecture.md index 73f6077..5a8ae2c 100644 --- a/docs/architecture/studio-architecture.md +++ b/docs/architecture/studio-architecture.md @@ -146,7 +146,7 @@ graph TB subgraph SRC["生产者(4 条)"] LIVE["实时 packet.processed_frame + flow + depth"] RECOMP["重算:同一采集链跑在录像上"] - REPLAY["回放:ReplayController.video_frame_bgr() 原始帧"] + REPLAY["回放:ReplayEngine.video_frame_bgr() 原始帧"] PREV["预览:摄像头原始帧"] end IB["image_backend.py(共享)
ImageFrame → plan_image() → render_image()"]