diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index d2a9553..8f1a857 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -817,7 +817,8 @@ Known local toolchain state: animation MP4/timelapse paths, and empty video-path rejection. - `pp_app_core_document_recording_tests` covers recording start/stop, clear, platform recorded-file cleanup, frame-count reset, export progress totals, - and oversized progress-total clamping. + oversized progress-total clamping, and recording-worker encode-wake + eligibility when recording, encoder, and canvas-document state vary. - `pp_app_core_document_sharing_tests` covers saved-path gating before platform share execution. - `pp_app_core_document_platform_io_tests` covers empty selected-path filtering diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 23a86eb..0d6283c 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -130,6 +130,11 @@ agent or engineer to remove them without reconstructing context from chat. planning consumed by `App::cmd_convert` and `pano_cli plan-command-convert`; retained OpenGL state dispatch and legacy `Canvas` project open/export execution remain in the legacy app. +- 2026-06-05: DEBT-0003 was narrowed again. Recording worker encode-wake + eligibility now goes through tested `pp_app_core` planning consumed by + `App::rec_loop` and `pano_cli plan-recording-session`; retained PBO + equirect generation, dirty-stroke mutation, MP4 encoder calls, and frame + label rendering remain in the legacy app/canvas/video path. - 2026-06-04: DEBT-0036 was narrowed again. Canvas stroke commit, thumbnail, and object-draw history paths now query saved blend state through tested `pp_renderer_gl` capability-state dispatch; CanvasLayer equirect @@ -148,7 +153,7 @@ agent or engineer to remove them without reconstructing context from chat. | --- | --- | --- | --- | --- | --- | --- | | DEBT-0001 | Open | Modernization | Existing platform build files remain alongside new CMake | Required for incremental migration without losing platform coverage | Existing platform builds plus new CMake configure | Remove after all platform builds consume shared CMake targets | | DEBT-0002 | Open | Modernization | Vendored SDK and patched libraries retained initially | Some dependencies are SDK-only, patched, or have platform-specific binaries | Dependency inventory and platform build smoke tests | Replace with vcpkg packages or document permanent vendored status after triplet evaluation | -| DEBT-0003 | Open | Modernization | Existing singletons remain during initial split; `App::open_document`, `App::request_close`, `App::share_file`, `App::cloud_upload`, `App::cloud_upload_all`, `App::cloud_browse`, `App::rec_start`, `App::rec_stop`, `App::rec_clear`, `App::rec_export`, `App::render_task*`, `App::ui_task*`, `App::render_thread_*`, `App::ui_thread_*`, file-menu save actions, `NodeCanvas` canvas hotkeys, new/open/browse dirty-document workflow prompts, new-document target/resolution/overwrite decisions, save-as document file naming and overwrite decisions, save-version target decisions, export start/menu/target naming/path decisions, share-file saved-path decisions, file/image/save/directory picker selected-path decisions, display-file external-open decisions, virtual-keyboard visibility decisions, recording lifecycle/export progress decisions, cloud-upload prompt/save-before-upload decisions, cloud-browse availability and selected-download decisions, bulk cloud-upload progress decisions, tools/options app preference decisions, app status/display and renderer diagnostic decisions, app thread/task orchestration decisions, document resize decisions, layer rename/menu decisions, Tools menu/panel decisions, About menu/diagnostic decisions, main toolbar/status decisions, `pano_cli classify-open`, `pano_cli plan-open-route`, `pano_cli plan-file-menu`, `pano_cli plan-new-document`, `pano_cli plan-document-file`, `pano_cli plan-document-version`, `pano_cli plan-export-start`, `pano_cli plan-export-menu`, `pano_cli plan-export-target`, `pano_cli plan-recording-session`, `pano_cli plan-app-preferences`, `pano_cli plan-app-status`, `pano_cli plan-app-thread`, `pano_cli plan-tools-menu`, `pano_cli plan-tools-panel`, `pano_cli plan-about-menu`, `pano_cli plan-main-toolbar`, `pano_cli plan-document-resize`, `pano_cli plan-layer-rename`, `pano_cli plan-layer-menu`, `pano_cli plan-canvas-hotkey`, `pano_cli plan-share-file`, `pano_cli plan-picked-path`, `pano_cli plan-display-file`, `pano_cli plan-keyboard-visibility`, `pano_cli plan-cloud-upload`, `pano_cli plan-cloud-browse`, `pano_cli plan-cloud-upload-all`, and `pano_cli simulate-app-session` now consume pure `pp_app_core` route/session/export/recording/preferences/status/thread/share/platform-I/O/display/keyboard/cloud/resize/layer/tools/about/toolbar/canvas-command contracts, but document creation/loading, brush import execution, saving, export execution, tools/options UI execution, Tools panel creation/execution, About dialog/diagnostic execution, toolbar/status dialog/history/canvas execution, status/display UI rendering, renderer diagnostic capability adaptation, app task/thread execution, document resize execution, layer rename/menu execution, settings persistence, platform share service execution, picker service execution, display-file service execution, keyboard service execution, recording/MP4 execution, cloud upload execution, and cloud browse/download execution still reach legacy `Canvas::I`/UI/network/video/platform singletons | Avoid behavior changes while introducing component boundaries | App launch and component tests; `pp_app_core_document_route_tests`; `pp_app_core_file_menu_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_recording_tests`; `pp_app_core_app_preferences_tests`; `pp_app_core_app_status_tests`; `pp_app_core_app_thread_tests`; `pp_app_core_tools_menu_tests`; `pp_app_core_about_menu_tests`; `pp_app_core_main_toolbar_tests`; `pp_app_core_document_resize_tests`; `pp_app_core_document_layer_tests`; `pp_app_core_document_sharing_tests`; `pp_app_core_document_platform_io_tests`; `pp_app_core_document_cloud_tests`; `pp_app_core_document_session_tests`; `pp_app_core_canvas_hotkey_tests`; `pano_cli classify-open --path D:/Paint/demo.ppi`; `pano_cli plan-open-route --path D:/Paint/demo.ppi --unsaved`; `pano_cli plan-file-menu --command save-as`; `pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3 --target-exists`; `pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists`; `pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi`; `pano_cli plan-export-start --requires-license --demo`; `pano_cli plan-export-menu --kind animation-mp4 --demo`; `pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png`; `pano_cli plan-recording-session --running --frame-count 12`; `pano_cli plan-app-preferences --ui-scale 1.5 --display-density 2 --current-scale 1.6 --scale-option 1 --scale-option 1.5 --rtl`; `pano_cli plan-app-status --doc-name demo --unsaved --resolution 2048 --resolution-index 3 --zoom 1.25 --history-bytes 1572864 --recording-running --encoder-available --encoded-frames 12 --framebuffer-fetch --float32 --float32-linear --float16`; `pano_cli plan-app-thread --kind ui-loop --live-reload`; `pano_cli plan-tools-menu --command shortcuts`; `pano_cli plan-tools-panel --panel layers`; `pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7`; `pano_cli plan-main-toolbar --command undo --undo-count 2`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint`; `pano_cli plan-canvas-hotkey --event key-up --key z --ctrl --undo-count 2`; `pano_cli plan-share-file --path D:/Paint/demo.ppi`; `pano_cli plan-picked-path --path D:/Paint/demo.ppi`; `pano_cli plan-display-file --path D:/Paint/export.png`; `pano_cli plan-keyboard-visibility --visible`; `pano_cli plan-cloud-upload --new-document --unsaved`; `pano_cli plan-cloud-browse --selected-file demo.ppi`; `pano_cli plan-cloud-upload-all --file-count 3`; `pano_cli simulate-app-session --unsaved --save-intent save-dirty-version`; `pano_cli simulate-app-session --no-canvas`; `ctest --preset desktop-fast --build-config Debug` | Replace singleton reaches with context/service injection at component boundaries | +| DEBT-0003 | Open | Modernization | Existing singletons remain during initial split; `App::open_document`, `App::request_close`, `App::share_file`, `App::cloud_upload`, `App::cloud_upload_all`, `App::cloud_browse`, `App::rec_start`, `App::rec_stop`, `App::rec_clear`, `App::rec_export`, `App::rec_loop`, `App::render_task*`, `App::ui_task*`, `App::render_thread_*`, `App::ui_thread_*`, file-menu save actions, `NodeCanvas` canvas hotkeys, new/open/browse dirty-document workflow prompts, new-document target/resolution/overwrite decisions, save-as document file naming and overwrite decisions, save-version target decisions, export start/menu/target naming/path decisions, share-file saved-path decisions, file/image/save/directory picker selected-path decisions, display-file external-open decisions, virtual-keyboard visibility decisions, recording lifecycle/export progress/worker decisions, cloud-upload prompt/save-before-upload decisions, cloud-browse availability and selected-download decisions, bulk cloud-upload progress decisions, tools/options app preference decisions, app status/display and renderer diagnostic decisions, app thread/task orchestration decisions, document resize decisions, layer rename/menu decisions, Tools menu/panel decisions, About menu/diagnostic decisions, main toolbar/status decisions, `pano_cli classify-open`, `pano_cli plan-open-route`, `pano_cli plan-file-menu`, `pano_cli plan-new-document`, `pano_cli plan-document-file`, `pano_cli plan-document-version`, `pano_cli plan-export-start`, `pano_cli plan-export-menu`, `pano_cli plan-export-target`, `pano_cli plan-recording-session`, `pano_cli plan-app-preferences`, `pano_cli plan-app-status`, `pano_cli plan-app-thread`, `pano_cli plan-tools-menu`, `pano_cli plan-tools-panel`, `pano_cli plan-about-menu`, `pano_cli plan-main-toolbar`, `pano_cli plan-document-resize`, `pano_cli plan-layer-rename`, `pano_cli plan-layer-menu`, `pano_cli plan-canvas-hotkey`, `pano_cli plan-share-file`, `pano_cli plan-picked-path`, `pano_cli plan-display-file`, `pano_cli plan-keyboard-visibility`, `pano_cli plan-cloud-upload`, `pano_cli plan-cloud-browse`, `pano_cli plan-cloud-upload-all`, and `pano_cli simulate-app-session` now consume pure `pp_app_core` route/session/export/recording/preferences/status/thread/share/platform-I/O/display/keyboard/cloud/resize/layer/tools/about/toolbar/canvas-command contracts, but document creation/loading, brush import execution, saving, export execution, tools/options UI execution, Tools panel creation/execution, About dialog/diagnostic execution, toolbar/status dialog/history/canvas execution, status/display UI rendering, renderer diagnostic capability adaptation, app task/thread execution, document resize execution, layer rename/menu execution, settings persistence, platform share service execution, picker service execution, display-file service execution, keyboard service execution, recording/MP4/PBO execution, cloud upload execution, and cloud browse/download execution still reach legacy `Canvas::I`/UI/network/video/platform singletons | Avoid behavior changes while introducing component boundaries | App launch and component tests; `pp_app_core_document_route_tests`; `pp_app_core_file_menu_tests`; `pp_app_core_document_export_tests`; `pp_app_core_document_recording_tests`; `pp_app_core_app_preferences_tests`; `pp_app_core_app_status_tests`; `pp_app_core_app_thread_tests`; `pp_app_core_tools_menu_tests`; `pp_app_core_about_menu_tests`; `pp_app_core_main_toolbar_tests`; `pp_app_core_document_resize_tests`; `pp_app_core_document_layer_tests`; `pp_app_core_document_sharing_tests`; `pp_app_core_document_platform_io_tests`; `pp_app_core_document_cloud_tests`; `pp_app_core_document_session_tests`; `pp_app_core_canvas_hotkey_tests`; `pano_cli classify-open --path D:/Paint/demo.ppi`; `pano_cli plan-open-route --path D:/Paint/demo.ppi --unsaved`; `pano_cli plan-file-menu --command save-as`; `pano_cli plan-new-document --work-dir D:/Paint --name demo --resolution-index 3 --target-exists`; `pano_cli plan-document-file --work-dir D:/Paint --name demo --target-exists`; `pano_cli plan-document-version --directory D:/Paint --doc-name demo.01 --existing-path D:/Paint/demo.02.ppi`; `pano_cli plan-export-start --requires-license --demo`; `pano_cli plan-export-menu --kind animation-mp4 --demo`; `pano_cli plan-export-target --kind file --work-dir D:/Paint --doc-name demo --extension .png`; `pano_cli plan-recording-session --running --frame-count 12`; `pano_cli plan-recording-session --running --no-encoder`; `pano_cli plan-app-preferences --ui-scale 1.5 --display-density 2 --current-scale 1.6 --scale-option 1 --scale-option 1.5 --rtl`; `pano_cli plan-app-status --doc-name demo --unsaved --resolution 2048 --resolution-index 3 --zoom 1.25 --history-bytes 1572864 --recording-running --encoder-available --encoded-frames 12 --framebuffer-fetch --float32 --float32-linear --float16`; `pano_cli plan-app-thread --kind ui-loop --live-reload`; `pano_cli plan-tools-menu --command shortcuts`; `pano_cli plan-tools-panel --panel layers`; `pano_cli plan-about-menu --command news --version-major 2 --version-minor 5 --version-fix 7`; `pano_cli plan-main-toolbar --command undo --undo-count 2`; `pano_cli plan-document-resize --current-resolution 2048 --selected-resolution-index 4`; `pano_cli plan-layer-rename --old-name Base --new-name Paint`; `pano_cli plan-layer-menu --command merge --current-index 2 --lower-name Paint`; `pano_cli plan-canvas-hotkey --event key-up --key z --ctrl --undo-count 2`; `pano_cli plan-share-file --path D:/Paint/demo.ppi`; `pano_cli plan-picked-path --path D:/Paint/demo.ppi`; `pano_cli plan-display-file --path D:/Paint/export.png`; `pano_cli plan-keyboard-visibility --visible`; `pano_cli plan-cloud-upload --new-document --unsaved`; `pano_cli plan-cloud-browse --selected-file demo.ppi`; `pano_cli plan-cloud-upload-all --file-count 3`; `pano_cli simulate-app-session --unsaved --save-intent save-dirty-version`; `pano_cli simulate-app-session --no-canvas`; `ctest --preset desktop-fast --build-config Debug` | Replace singleton reaches with context/service injection at component boundaries | | DEBT-0004 | Open | Modernization | Android, Linux, WebGL, Apple, and AppX build files remain platform-specific until root CMake alignment reaches them | Prevent platform regressions during incremental migration; raw Windows `.sln/.vcxproj` files were removed on 2026-05-31 by user decision | `cmake --preset windows-msvc-default`; platform-specific configure/build smoke checks as each platform is migrated | Root CMake owns every platform source list and package path | | DEBT-0005 | Open | Modernization | Temporary local CTest harness is used before Catch2 is wired through vcpkg | `vcpkg` is not currently on PATH, but headless tests need to run now | `ctest --preset desktop-fast --build-config Debug` | Replace `tests/test_harness.h` tests with Catch2 tests once vcpkg toolchain/presets are validated | | DEBT-0007 | Open | Modernization | `vcpkg.json` and `windows-msvc-vcpkg-headless` are validated for the headless Windows component matrix, but app targets still use vendored libraries and Android/Apple triplets are not proven | Dependency migration must stay incremental while SDK/patched/vendor dependencies remain in use | `$env:VCPKG_ROOT="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\vcpkg"; cmake --preset windows-msvc-vcpkg-headless`; `ctest --preset desktop-fast-vcpkg --build-config Debug` | Component targets consume vcpkg packages where reliable and desktop app, Android, and Apple triplets are validated or explicitly documented as permanent vendor exceptions | diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index a73f0c4..5bd648a 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -1750,11 +1750,14 @@ Results: tests. - `pp_app_core_document_recording_tests` passed, covering recording start/stop, clear, platform recorded-file cleanup, frame-count reset, export progress - totals, and oversized progress-total clamping. + totals, oversized progress-total clamping, and recording-worker encode-wake + eligibility. - `pano_cli_plan_recording_session_stopped_smoke`, `pano_cli_plan_recording_session_running_smoke`, and `pano_cli_plan_recording_session_platform_cleanup_smoke` passed and expose - app-core recording lifecycle/export decisions as JSON. + app-core recording lifecycle/export decisions as JSON. On 2026-06-05, + `pano_cli_plan_recording_session_missing_encoder_smoke` was added for the + worker no-encode path. - `pp_app_core_document_resize_tests` passed, covering resize dialog state, unknown current-resolution labeling, selected-resolution mapping, square canvas sizing, history-clearing intent, invalid selection rejection, service diff --git a/src/app.cpp b/src/app.cpp index 84ceb0c..024709a 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -783,21 +783,30 @@ void App::rec_loop() { std::unique_lock lock(rec_mutex); rec_cv.wait(lock/*, [this] { return !(rec_frames.empty() && rec_running); }*/); - if (!rec_running) + auto* legacy_canvas = Canvas::I; + auto* canvas_document = canvas ? canvas->m_canvas.get() : nullptr; + auto* encoder = legacy_canvas ? legacy_canvas->m_encoder.get() : nullptr; + const auto plan = pp::app::plan_recording_worker_iteration( + rec_running, + encoder != nullptr, + legacy_canvas != nullptr && canvas_document != nullptr); + if (!plan.continue_running) break; - if (Canvas::I->m_encoder) + if (plan.encode_frame && legacy_canvas && canvas_document && encoder) { - canvas->m_canvas->m_dirty_stroke = false; - PBO equirect = Canvas::I->m_layers_merge.gen_equirect_pbo( - Canvas::I->m_encoder->frame_size()); + if (plan.clear_dirty_stroke) + canvas_document->m_dirty_stroke = false; + PBO equirect = legacy_canvas->m_layers_merge.gen_equirect_pbo( + encoder->frame_size()); std::this_thread::yield(); ImageRef img; img.create(equirect.width, equirect.height, equirect.map()); - Canvas::I->m_encoder->encode(img); + encoder->encode(img); equirect.unmap(); LOG("rec frame encoded"); - update_rec_frames(); + if (plan.update_frame_label) + update_rec_frames(); } } } diff --git a/src/app_core/document_recording.h b/src/app_core/document_recording.h index 0439ca4..bd313e6 100644 --- a/src/app_core/document_recording.h +++ b/src/app_core/document_recording.h @@ -29,6 +29,13 @@ struct RecordingExportPlan { int progress_total = 0; }; +struct RecordingWorkerIterationPlan { + bool continue_running = true; + bool encode_frame = false; + bool clear_dirty_stroke = false; + bool update_frame_label = false; +}; + class RecordingServices { public: virtual ~RecordingServices() = default; @@ -77,6 +84,20 @@ public: }; } +[[nodiscard]] constexpr RecordingWorkerIterationPlan plan_recording_worker_iteration( + bool is_running_after_wake, + bool has_encoder, + bool has_canvas_document) noexcept +{ + const bool encode = is_running_after_wake && has_encoder && has_canvas_document; + return { + .continue_running = is_running_after_wake, + .encode_frame = encode, + .clear_dirty_stroke = encode, + .update_frame_label = encode, + }; +} + [[nodiscard]] inline pp::foundation::Status execute_recording_start_action( RecordingStartAction action, RecordingServices& services) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cf3b64d..31a5f6e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -934,7 +934,7 @@ if(TARGET pano_cli) COMMAND pano_cli plan-recording-session --running --frame-count 12) set_tests_properties(pano_cli_plan_recording_session_running_smoke PROPERTIES LABELS "app;integration;desktop-fast" - PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"running\":true.*\"startDecision\":\"no-op-already-running\".*\"stopDecision\":\"stop-thread\".*\"stopRunningRecording\":true.*\"progressTotal\":12") + PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"running\":true.*\"startDecision\":\"no-op-already-running\".*\"stopDecision\":\"stop-thread\".*\"stopRunningRecording\":true.*\"progressTotal\":12.*\"worker\":\\{\"continueRunning\":true,\"encodeFrame\":true,\"clearDirtyStroke\":true,\"updateFrameLabel\":true\\}") add_test(NAME pano_cli_plan_recording_session_platform_cleanup_smoke COMMAND pano_cli plan-recording-session --platform-deletes-recorded-files) @@ -942,6 +942,12 @@ if(TARGET pano_cli) LABELS "app;integration;desktop-fast;fuzz" PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"platformDeletesRecordedFiles\":true.*\"deleteRecordedFiles\":true.*\"frameCountAfterClear\":0") + add_test(NAME pano_cli_plan_recording_session_missing_encoder_smoke + COMMAND pano_cli plan-recording-session --running --no-encoder) + set_tests_properties(pano_cli_plan_recording_session_missing_encoder_smoke PROPERTIES + LABELS "app;integration;desktop-fast;fuzz" + PASS_REGULAR_EXPRESSION "\"command\":\"plan-recording-session\".*\"running\":true.*\"encoderAvailable\":false.*\"worker\":\\{\"continueRunning\":true,\"encodeFrame\":false,\"clearDirtyStroke\":false,\"updateFrameLabel\":false\\}") + add_test(NAME pano_cli_plan_app_preferences_smoke COMMAND pano_cli plan-app-preferences --ui-scale 1.5 diff --git a/tests/app_core/document_recording_tests.cpp b/tests/app_core/document_recording_tests.cpp index b78b9ec..55d13e0 100644 --- a/tests/app_core/document_recording_tests.cpp +++ b/tests/app_core/document_recording_tests.cpp @@ -119,6 +119,25 @@ void recording_export_clamps_progress_total(pp::tests::Harness& harness) PP_EXPECT(harness, plan.progress_total == std::numeric_limits::max()); } +void recording_worker_iteration_encodes_only_when_ready(pp::tests::Harness& harness) +{ + const auto encode = pp::app::plan_recording_worker_iteration(true, true, true); + const auto stopped = pp::app::plan_recording_worker_iteration(false, true, true); + const auto missing_encoder = pp::app::plan_recording_worker_iteration(true, false, true); + const auto missing_canvas = pp::app::plan_recording_worker_iteration(true, true, false); + + PP_EXPECT(harness, encode.continue_running); + PP_EXPECT(harness, encode.encode_frame); + PP_EXPECT(harness, encode.clear_dirty_stroke); + PP_EXPECT(harness, encode.update_frame_label); + PP_EXPECT(harness, !stopped.continue_running); + PP_EXPECT(harness, !stopped.encode_frame); + PP_EXPECT(harness, missing_encoder.continue_running); + PP_EXPECT(harness, !missing_encoder.encode_frame); + PP_EXPECT(harness, missing_canvas.continue_running); + PP_EXPECT(harness, !missing_canvas.encode_frame); +} + void executor_dispatches_recording_lifecycle(pp::tests::Harness& harness) { FakeRecordingServices services; @@ -180,6 +199,7 @@ int main() recording_clear_resets_frames_and_preserves_platform_delete_flag); harness.run("recording export tracks frame count", recording_export_tracks_frame_count); harness.run("recording export clamps progress total", recording_export_clamps_progress_total); + harness.run("recording worker iteration encodes only when ready", recording_worker_iteration_encodes_only_when_ready); harness.run("executor dispatches recording lifecycle", executor_dispatches_recording_lifecycle); harness.run("executor dispatches recording clear and export", executor_dispatches_recording_clear_and_export); return harness.finish(); diff --git a/tools/pano_cli/main.cpp b/tools/pano_cli/main.cpp index 7246839..c6761ea 100644 --- a/tools/pano_cli/main.cpp +++ b/tools/pano_cli/main.cpp @@ -198,6 +198,8 @@ struct PlanRecordingSessionArgs { bool running = false; std::uint32_t frame_count = 0; bool platform_deletes_recorded_files = false; + bool encoder_available = true; + bool has_canvas = true; }; struct PlanShareFileArgs { @@ -2090,7 +2092,7 @@ void print_help() << " plan-cloud-upload [--no-canvas] [--new-document] [--unsaved]\n" << " plan-cloud-browse [--no-canvas] [--selected-file FILE]\n" << " plan-cloud-upload-all [--file-count N] [--no-progress-ui]\n" - << " plan-recording-session [--running] [--frame-count N] [--platform-deletes-recorded-files]\n" + << " plan-recording-session [--running] [--frame-count N] [--platform-deletes-recorded-files] [--no-encoder] [--no-canvas]\n" << " plan-app-preferences [--ui-scale N] [--display-density N] [--current-scale N] [--scale-option N] [--viewport-scale N] [--rtl] [--timelapse-disabled] [--recording-running] [--vr-controllers-disabled] [--cursor-mode N]\n" << " plan-app-startup [--run-counter N] [--auto-timelapse-disabled] [--vr-controllers-disabled] [--license-invalid]\n" << " plan-app-startup-resources [--width N] [--height N] [--bad-size]\n" @@ -3539,6 +3541,10 @@ pp::foundation::Status parse_plan_recording_session_args( args.frame_count = value.value(); } else if (key == "--platform-deletes-recorded-files") { args.platform_deletes_recorded_files = true; + } else if (key == "--no-encoder") { + args.encoder_available = false; + } else if (key == "--no-canvas") { + args.has_canvas = false; } else { return pp::foundation::Status::invalid_argument("unknown option"); } @@ -3562,10 +3568,16 @@ int plan_recording_session(int argc, char** argv) args.running, args.platform_deletes_recorded_files); const auto export_plan = pp::app::plan_recording_export(args.frame_count); + const auto worker = pp::app::plan_recording_worker_iteration( + args.running, + args.encoder_available, + args.has_canvas); std::cout << "{\"ok\":true,\"command\":\"plan-recording-session\"" << ",\"state\":{\"running\":" << json_bool(args.running) << ",\"frameCount\":" << args.frame_count << ",\"platformDeletesRecordedFiles\":" << json_bool(args.platform_deletes_recorded_files) + << ",\"encoderAvailable\":" << json_bool(args.encoder_available) + << ",\"hasCanvas\":" << json_bool(args.has_canvas) << "},\"startDecision\":\"" << recording_start_action_name(start) << "\",\"stopDecision\":\"" << recording_stop_action_name(stop) << "\",\"clear\":{\"stopRunningRecording\":" << json_bool(clear.stop_running_recording) @@ -3573,6 +3585,10 @@ int plan_recording_session(int argc, char** argv) << ",\"frameCountAfterClear\":" << clear.frame_count_after_clear << "},\"export\":{\"frameCount\":" << export_plan.frame_count << ",\"progressTotal\":" << export_plan.progress_total + << "},\"worker\":{\"continueRunning\":" << json_bool(worker.continue_running) + << ",\"encodeFrame\":" << json_bool(worker.encode_frame) + << ",\"clearDirtyStroke\":" << json_bool(worker.clear_dirty_stroke) + << ",\"updateFrameLabel\":" << json_bool(worker.update_frame_label) << "}}\n"; return 0; }