Route app frame decisions through app core
This commit is contained in:
@@ -240,6 +240,7 @@ target_link_libraries(pp_platform_api
|
||||
|
||||
add_library(pp_app_core STATIC
|
||||
src/app_core/about_menu.h
|
||||
src/app_core/app_frame.h
|
||||
src/app_core/app_preferences.h
|
||||
src/app_core/app_status.h
|
||||
src/app_core/app_startup.h
|
||||
|
||||
@@ -241,6 +241,11 @@ Known local toolchain state:
|
||||
retained shader loading, asset initialization, layout creation, title updates,
|
||||
UI render-target creation, recording startup, VR-controller state mutation,
|
||||
settings writes, and license-warning dialogs remain legacy execution.
|
||||
- `src/app_core/app_frame.h` owns the current initial surface, update-gating,
|
||||
and draw-pass decisions consumed by `App::create`, `App::update`,
|
||||
`App::draw`, and `pano_cli plan-app-frame`; retained layout traversal,
|
||||
toolbar widget writes, canvas stroke drawing, VR UI render-target drawing,
|
||||
main target binding, and OpenGL/UI drawing remain in the legacy app.
|
||||
- `src/legacy_app_preference_services.*` is the current app-shell bridge for
|
||||
options-menu preference execution. It keeps UI scale, viewport scale, RTL,
|
||||
VR mode, VR-controller, auto-timelapse, and canvas cursor-mode callbacks on
|
||||
@@ -824,6 +829,9 @@ Known local toolchain state:
|
||||
planning, optional auto-timelapse/license/VR-controller decisions, negative
|
||||
and overflow run-counter rejection, stable full startup dispatch ordering,
|
||||
split persistence/runtime dispatch, and malformed startup-plan rejection.
|
||||
- `pp_app_core_app_frame_tests` covers the legacy initial surface default,
|
||||
idle/redraw/animation update gating, canvas-stroke draw eligibility, VR UI
|
||||
visibility, main UI suppression in VR-only mode, and redraw reset planning.
|
||||
- `pp_platform_api_tests` covers service dispatch for clipboard read/write,
|
||||
empty clipboard writes, cursor visibility, virtual-keyboard visibility,
|
||||
external file display, file sharing, VR lifecycle, layout/asset file load
|
||||
|
||||
@@ -20,7 +20,7 @@ agent or engineer to remove them without reconstructing context from chat.
|
||||
|
||||
- 2026-06-04: DEBT-0009 was narrowed. `platform-build.ps1` and
|
||||
`platform-build.sh` now include the current headless component/test matrix,
|
||||
including brush-package coverage and the app-core startup/file/document/
|
||||
including brush-package coverage and the app-core startup/frame/file/document/
|
||||
brush/canvas/history/grid/toolbar/tools/about/preferences/status automation
|
||||
tests, and `panopainter_platform_build_target_matrix_self_test` now verifies
|
||||
the wrapper defaults against the current CMake test executables. On
|
||||
@@ -91,6 +91,12 @@ agent or engineer to remove them without reconstructing context from chat.
|
||||
the retained OpenGL startup task in place, then delegates startup resources
|
||||
and runtime side effects through the startup bridge. `pano_cli
|
||||
plan-app-startup-resources` exposes the resource path for automation.
|
||||
- 2026-06-05: DEBT-0003 was narrowed. Initial surface sizing, redraw/animation
|
||||
update gating, canvas-stroke draw eligibility, VR UI pass selection, main UI
|
||||
pass selection, and redraw reset are now tested `pp_app_core` frame plans
|
||||
consumed by `App::create`, `App::update`, `App::draw`, and
|
||||
`pano_cli plan-app-frame`; retained layout traversal, toolbar widget writes,
|
||||
and OpenGL/UI drawing remain in the legacy app.
|
||||
- 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
|
||||
|
||||
@@ -198,6 +198,11 @@ and floating-point render targets; `App::title_update`,
|
||||
`App::update_memory_usage`, `App::update_rec_frames`, resolution helpers,
|
||||
`App::initLayout`, and `pano_cli plan-app-status` consume those contracts while
|
||||
legacy UI nodes still render the strings and status lights.
|
||||
Frame-level app decisions for the initial surface size, redraw/animation update
|
||||
gating, canvas-stroke drawing, VR UI drawing, main UI drawing, and redraw reset
|
||||
now live in `pp_app_core`; `App::create`, `App::update`, `App::draw`, and
|
||||
`pano_cli plan-app-frame` consume those plans while retained layout traversal
|
||||
and OpenGL/UI drawing stay in the legacy app.
|
||||
`panopainter_app` is now a real static target that owns app orchestration
|
||||
sources, app version metadata, and version-header generation.
|
||||
`pp_panopainter_ui` now owns app-specific modal, dialog, panel, canvas,
|
||||
@@ -1286,7 +1291,7 @@ standard x64/arm64, Android Quest arm64, Android Focus/Wave arm64,
|
||||
Emscripten/WebGL, macOS, iOS device, and iOS simulator. `platform-build`
|
||||
automation now builds the current headless component matrix, including
|
||||
`pp_platform_api`, `pp_app_core`, platform API tests, brush-package tests, and
|
||||
the current app-core startup/file/document/brush/canvas/history/grid/toolbar/
|
||||
the current app-core startup/frame/file/document/brush/canvas/history/grid/toolbar/
|
||||
tools/about/preferences/status automation tests. The PowerShell wrapper also
|
||||
normalizes comma-separated `-Presets` and `-Targets` values for reliable
|
||||
machine-driven partial matrix checks. `panopainter_platform_build_target_matrix_self_test`
|
||||
@@ -1643,6 +1648,11 @@ Results:
|
||||
`pano_cli_plan_app_startup_rejects_negative_counter`, with startup resource
|
||||
sequencing also covered by `pano_cli_plan_app_startup_resources_smoke` and
|
||||
`pano_cli_plan_app_startup_resources_rejects_bad_size`.
|
||||
- `PanoPainter`, `pp_app_core_app_frame_tests`, and `pano_cli` built after
|
||||
app frame surface/update/draw-pass decisions moved into `pp_app_core`.
|
||||
- Focused frame CTest coverage passed for `pp_app_core_app_frame_tests`,
|
||||
`pano_cli_plan_app_frame_vr_smoke`, and
|
||||
`pano_cli_plan_app_frame_idle_missing_canvas_smoke`.
|
||||
- `PanoPainter`, `pp_app_core_brush_package_export_tests`, and `pano_cli` built
|
||||
after PPBR brush package export request validation and dispatch moved behind
|
||||
app-core brush package services.
|
||||
|
||||
@@ -42,6 +42,7 @@ param(
|
||||
"pp_ui_core_layout_xml_tests",
|
||||
"pp_app_core_about_menu_tests",
|
||||
"pp_app_core_app_preferences_tests",
|
||||
"pp_app_core_app_frame_tests",
|
||||
"pp_app_core_app_startup_tests",
|
||||
"pp_app_core_app_status_tests",
|
||||
"pp_app_core_brush_package_export_tests",
|
||||
@@ -49,6 +50,7 @@ param(
|
||||
"pp_app_core_brush_ui_tests",
|
||||
"pp_app_core_canvas_hotkey_tests",
|
||||
"pp_app_core_canvas_tool_ui_tests",
|
||||
"pp_app_core_canvas_view_tests",
|
||||
"pp_app_core_document_animation_tests",
|
||||
"pp_app_core_document_canvas_tests",
|
||||
"pp_app_core_document_cloud_tests",
|
||||
|
||||
@@ -3,7 +3,7 @@ set -u
|
||||
|
||||
presets="${1:-android-arm64 android-x64 android-quest-arm64 android-focus-arm64}"
|
||||
shift || true
|
||||
targets="${*:-pp_foundation pp_assets pp_paint pp_document pp_renderer_api pp_renderer_gl pp_paint_renderer pp_ui_core pp_platform_api pp_app_core pano_cli pp_foundation_binary_stream_tests pp_foundation_event_tests pp_foundation_log_tests pp_foundation_parse_tests pp_foundation_task_queue_tests pp_foundation_trace_tests pp_assets_brush_package_tests pp_assets_image_format_tests pp_assets_image_metadata_tests pp_assets_image_pixels_tests pp_assets_ppi_header_tests pp_assets_settings_document_tests pp_paint_brush_tests pp_paint_blend_tests pp_paint_stroke_tests pp_paint_stroke_script_tests pp_document_tests pp_document_ppi_import_tests pp_document_ppi_export_tests pp_renderer_api_tests pp_renderer_gl_capabilities_tests pp_renderer_gl_command_plan_tests pp_paint_renderer_compositor_tests pp_platform_api_tests pp_ui_core_color_tests pp_ui_core_layout_value_tests pp_ui_core_layout_xml_tests pp_app_core_about_menu_tests pp_app_core_app_preferences_tests pp_app_core_app_startup_tests pp_app_core_app_status_tests pp_app_core_brush_package_export_tests pp_app_core_brush_package_import_tests pp_app_core_brush_ui_tests pp_app_core_canvas_hotkey_tests pp_app_core_canvas_tool_ui_tests pp_app_core_document_animation_tests pp_app_core_document_canvas_tests pp_app_core_document_cloud_tests pp_app_core_document_export_tests pp_app_core_document_import_tests pp_app_core_document_layer_tests pp_app_core_document_platform_io_tests pp_app_core_document_recording_tests pp_app_core_document_resize_tests pp_app_core_document_route_tests pp_app_core_document_sharing_tests pp_app_core_document_session_tests pp_app_core_file_menu_tests pp_app_core_grid_ui_tests pp_app_core_history_ui_tests pp_app_core_main_toolbar_tests pp_app_core_quick_ui_tests pp_app_core_tools_menu_tests}"
|
||||
targets="${*:-pp_foundation pp_assets pp_paint pp_document pp_renderer_api pp_renderer_gl pp_paint_renderer pp_ui_core pp_platform_api pp_app_core pano_cli pp_foundation_binary_stream_tests pp_foundation_event_tests pp_foundation_log_tests pp_foundation_parse_tests pp_foundation_task_queue_tests pp_foundation_trace_tests pp_assets_brush_package_tests pp_assets_image_format_tests pp_assets_image_metadata_tests pp_assets_image_pixels_tests pp_assets_ppi_header_tests pp_assets_settings_document_tests pp_paint_brush_tests pp_paint_blend_tests pp_paint_stroke_tests pp_paint_stroke_script_tests pp_document_tests pp_document_ppi_import_tests pp_document_ppi_export_tests pp_renderer_api_tests pp_renderer_gl_capabilities_tests pp_renderer_gl_command_plan_tests pp_paint_renderer_compositor_tests pp_platform_api_tests pp_ui_core_color_tests pp_ui_core_layout_value_tests pp_ui_core_layout_xml_tests pp_app_core_about_menu_tests pp_app_core_app_preferences_tests pp_app_core_app_frame_tests pp_app_core_app_startup_tests pp_app_core_app_status_tests pp_app_core_brush_package_export_tests pp_app_core_brush_package_import_tests pp_app_core_brush_ui_tests pp_app_core_canvas_hotkey_tests pp_app_core_canvas_tool_ui_tests pp_app_core_canvas_view_tests pp_app_core_document_animation_tests pp_app_core_document_canvas_tests pp_app_core_document_cloud_tests pp_app_core_document_export_tests pp_app_core_document_import_tests pp_app_core_document_layer_tests pp_app_core_document_platform_io_tests pp_app_core_document_recording_tests pp_app_core_document_resize_tests pp_app_core_document_route_tests pp_app_core_document_sharing_tests pp_app_core_document_session_tests pp_app_core_file_menu_tests pp_app_core_grid_ui_tests pp_app_core_history_ui_tests pp_app_core_main_toolbar_tests pp_app_core_quick_ui_tests pp_app_core_tools_menu_tests}"
|
||||
start="$(date +%s)"
|
||||
|
||||
overall_exit=0
|
||||
|
||||
32
src/app.cpp
32
src/app.cpp
@@ -5,6 +5,7 @@
|
||||
#include "node_dialog_open.h"
|
||||
#include "node_progress_bar.h"
|
||||
#include "mp4enc.h"
|
||||
#include "app_core/app_frame.h"
|
||||
#include "app_core/app_status.h"
|
||||
#include "app_core/app_startup.h"
|
||||
#include "app_core/canvas_tool_ui.h"
|
||||
@@ -182,8 +183,9 @@ bool App::ui_running = false;
|
||||
|
||||
void App::create()
|
||||
{
|
||||
width = 1920/2;
|
||||
height = 1080/2;
|
||||
const auto initial_surface = pp::app::plan_app_initial_surface();
|
||||
width = initial_surface.width;
|
||||
height = initial_surface.height;
|
||||
}
|
||||
|
||||
void App::open_document(std::string path)
|
||||
@@ -540,13 +542,20 @@ bool App::update_ui_observer(Node *n)
|
||||
|
||||
void App::draw(float dt)
|
||||
{
|
||||
const auto draw_plan = pp::app::plan_app_frame_draw(
|
||||
canvas != nullptr,
|
||||
canvas && canvas->m_canvas,
|
||||
vr_active,
|
||||
ui_visible,
|
||||
vr_only);
|
||||
|
||||
// update offscreen stuff
|
||||
if (canvas && canvas->m_canvas)
|
||||
if (draw_plan.draw_canvas_stroke)
|
||||
canvas->m_canvas->stroke_draw();
|
||||
|
||||
auto observer = std::bind(&App::update_ui_observer, this, std::placeholders::_1);
|
||||
|
||||
if (vr_active && ui_visible)
|
||||
if (draw_plan.draw_vr_ui)
|
||||
{
|
||||
uirtt.bindFramebuffer();
|
||||
uirtt.clear();
|
||||
@@ -564,7 +573,7 @@ void App::draw(float dt)
|
||||
uirtt.unbindFramebuffer();
|
||||
}
|
||||
|
||||
if (!vr_only)
|
||||
if (draw_plan.draw_main_ui)
|
||||
{
|
||||
bind_main_render_target();
|
||||
apply_app_viewport(pp::renderer::gl::OpenGlViewportRect {
|
||||
@@ -582,7 +591,8 @@ void App::draw(float dt)
|
||||
apply_app_scissor_test(false);
|
||||
}
|
||||
|
||||
redraw = false;
|
||||
if (draw_plan.reset_redraw)
|
||||
redraw = false;
|
||||
}
|
||||
|
||||
void App::update(float dt)
|
||||
@@ -592,15 +602,19 @@ void App::update(float dt)
|
||||
// avoid multiple threads to update the scene
|
||||
//std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
if (!(redraw || animate))
|
||||
const auto update_plan = pp::app::plan_app_frame_update(redraw, animate);
|
||||
if (!update_plan.update_frame)
|
||||
return;
|
||||
|
||||
if (auto* main = layout[main_id])
|
||||
if (auto* main = layout[main_id]; update_plan.update_layouts && main)
|
||||
main->update(width, height, zoom);
|
||||
|
||||
if (auto* main = layout_designer[main_id])
|
||||
if (auto* main = layout_designer[main_id]; update_plan.update_layouts && main)
|
||||
main->update(width, height, zoom);
|
||||
|
||||
if (!update_plan.refresh_canvas_toolbar)
|
||||
return;
|
||||
|
||||
{
|
||||
auto mode = Canvas::I->m_current_mode;
|
||||
|
||||
|
||||
56
src/app_core/app_frame.h
Normal file
56
src/app_core/app_frame.h
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
namespace pp::app {
|
||||
|
||||
struct AppInitialSurfacePlan {
|
||||
float width = 960.0F;
|
||||
float height = 540.0F;
|
||||
};
|
||||
|
||||
struct AppFrameUpdatePlan {
|
||||
bool update_frame = false;
|
||||
bool update_layouts = false;
|
||||
bool refresh_canvas_toolbar = false;
|
||||
};
|
||||
|
||||
struct AppFrameDrawPlan {
|
||||
bool draw_canvas_stroke = false;
|
||||
bool draw_vr_ui = false;
|
||||
bool draw_main_ui = true;
|
||||
bool reset_redraw = true;
|
||||
};
|
||||
|
||||
[[nodiscard]] constexpr AppInitialSurfacePlan plan_app_initial_surface() noexcept
|
||||
{
|
||||
return AppInitialSurfacePlan {
|
||||
.width = 1920.0F / 2.0F,
|
||||
.height = 1080.0F / 2.0F,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr AppFrameUpdatePlan plan_app_frame_update(bool redraw, bool animate) noexcept
|
||||
{
|
||||
const bool update_frame = redraw || animate;
|
||||
return AppFrameUpdatePlan {
|
||||
.update_frame = update_frame,
|
||||
.update_layouts = update_frame,
|
||||
.refresh_canvas_toolbar = update_frame,
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr AppFrameDrawPlan plan_app_frame_draw(
|
||||
bool has_canvas_node,
|
||||
bool has_canvas_document,
|
||||
bool vr_active,
|
||||
bool ui_visible,
|
||||
bool vr_only) noexcept
|
||||
{
|
||||
return AppFrameDrawPlan {
|
||||
.draw_canvas_stroke = has_canvas_node && has_canvas_document,
|
||||
.draw_vr_ui = vr_active && ui_visible,
|
||||
.draw_main_ui = !vr_only,
|
||||
.reset_redraw = true,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace pp::app
|
||||
@@ -555,6 +555,16 @@ add_test(NAME pp_app_core_app_startup_tests COMMAND pp_app_core_app_startup_test
|
||||
set_tests_properties(pp_app_core_app_startup_tests PROPERTIES
|
||||
LABELS "app;desktop-fast;fuzz")
|
||||
|
||||
add_executable(pp_app_core_app_frame_tests
|
||||
app_core/app_frame_tests.cpp)
|
||||
target_link_libraries(pp_app_core_app_frame_tests PRIVATE
|
||||
pp_app_core
|
||||
pp_test_harness)
|
||||
|
||||
add_test(NAME pp_app_core_app_frame_tests COMMAND pp_app_core_app_frame_tests)
|
||||
set_tests_properties(pp_app_core_app_frame_tests PROPERTIES
|
||||
LABELS "app;desktop-fast;fuzz")
|
||||
|
||||
add_executable(pp_app_core_document_sharing_tests
|
||||
app_core/document_sharing_tests.cpp)
|
||||
target_link_libraries(pp_app_core_document_sharing_tests PRIVATE
|
||||
@@ -947,6 +957,18 @@ if(TARGET pano_cli)
|
||||
WILL_FAIL TRUE
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-startup-resources\".*\"message\":\"startup resource dimensions")
|
||||
|
||||
add_test(NAME pano_cli_plan_app_frame_vr_smoke
|
||||
COMMAND pano_cli plan-app-frame --redraw --vr-active)
|
||||
set_tests_properties(pano_cli_plan_app_frame_vr_smoke PROPERTIES
|
||||
LABELS "app;integration;desktop-fast"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"surface\":\\{\"width\":960,\"height\":540\\}.*\"updateFrame\":true.*\"updateLayouts\":true.*\"refreshCanvasToolbar\":true.*\"drawCanvasStroke\":true.*\"drawVrUi\":true.*\"drawMainUi\":true.*\"resetRedraw\":true")
|
||||
|
||||
add_test(NAME pano_cli_plan_app_frame_idle_missing_canvas_smoke
|
||||
COMMAND pano_cli plan-app-frame --no-canvas --ui-hidden --vr-only)
|
||||
set_tests_properties(pano_cli_plan_app_frame_idle_missing_canvas_smoke PROPERTIES
|
||||
LABELS "app;integration;desktop-fast;fuzz"
|
||||
PASS_REGULAR_EXPRESSION "\"command\":\"plan-app-frame\".*\"updateFrame\":false.*\"drawCanvasStroke\":false.*\"drawVrUi\":false.*\"drawMainUi\":false.*\"resetRedraw\":true")
|
||||
|
||||
add_test(NAME pano_cli_plan_brush_package_import_ppbr_smoke
|
||||
COMMAND pano_cli plan-brush-package-import
|
||||
--kind ppbr
|
||||
|
||||
78
tests/app_core/app_frame_tests.cpp
Normal file
78
tests/app_core/app_frame_tests.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "app_core/app_frame.h"
|
||||
#include "test_harness.h"
|
||||
|
||||
namespace {
|
||||
|
||||
void initial_surface_matches_legacy_default(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto plan = pp::app::plan_app_initial_surface();
|
||||
|
||||
PP_EXPECT(harness, plan.width == 960.0F);
|
||||
PP_EXPECT(harness, plan.height == 540.0F);
|
||||
}
|
||||
|
||||
void update_plan_skips_idle_frames(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto plan = pp::app::plan_app_frame_update(false, false);
|
||||
|
||||
PP_EXPECT(harness, !plan.update_frame);
|
||||
PP_EXPECT(harness, !plan.update_layouts);
|
||||
PP_EXPECT(harness, !plan.refresh_canvas_toolbar);
|
||||
}
|
||||
|
||||
void update_plan_refreshes_redraw_or_animated_frames(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto redraw = pp::app::plan_app_frame_update(true, false);
|
||||
const auto animated = pp::app::plan_app_frame_update(false, true);
|
||||
|
||||
PP_EXPECT(harness, redraw.update_frame);
|
||||
PP_EXPECT(harness, redraw.update_layouts);
|
||||
PP_EXPECT(harness, redraw.refresh_canvas_toolbar);
|
||||
PP_EXPECT(harness, animated.update_frame);
|
||||
PP_EXPECT(harness, animated.update_layouts);
|
||||
PP_EXPECT(harness, animated.refresh_canvas_toolbar);
|
||||
}
|
||||
|
||||
void draw_plan_selects_canvas_and_ui_passes(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto plan = pp::app::plan_app_frame_draw(true, true, true, true, false);
|
||||
|
||||
PP_EXPECT(harness, plan.draw_canvas_stroke);
|
||||
PP_EXPECT(harness, plan.draw_vr_ui);
|
||||
PP_EXPECT(harness, plan.draw_main_ui);
|
||||
PP_EXPECT(harness, plan.reset_redraw);
|
||||
}
|
||||
|
||||
void draw_plan_skips_missing_canvas_document(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto missing_node = pp::app::plan_app_frame_draw(false, true, false, true, false);
|
||||
const auto missing_document = pp::app::plan_app_frame_draw(true, false, false, true, false);
|
||||
|
||||
PP_EXPECT(harness, !missing_node.draw_canvas_stroke);
|
||||
PP_EXPECT(harness, !missing_document.draw_canvas_stroke);
|
||||
}
|
||||
|
||||
void draw_plan_respects_vr_visibility_modes(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto hidden_vr_ui = pp::app::plan_app_frame_draw(true, true, true, false, false);
|
||||
const auto vr_only = pp::app::plan_app_frame_draw(true, true, false, true, true);
|
||||
|
||||
PP_EXPECT(harness, !hidden_vr_ui.draw_vr_ui);
|
||||
PP_EXPECT(harness, hidden_vr_ui.draw_main_ui);
|
||||
PP_EXPECT(harness, !vr_only.draw_vr_ui);
|
||||
PP_EXPECT(harness, !vr_only.draw_main_ui);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int main()
|
||||
{
|
||||
pp::tests::Harness harness;
|
||||
harness.run("initial surface matches legacy default", initial_surface_matches_legacy_default);
|
||||
harness.run("update plan skips idle frames", update_plan_skips_idle_frames);
|
||||
harness.run("update plan refreshes redraw or animated frames", update_plan_refreshes_redraw_or_animated_frames);
|
||||
harness.run("draw plan selects canvas and UI passes", draw_plan_selects_canvas_and_ui_passes);
|
||||
harness.run("draw plan skips missing canvas document", draw_plan_skips_missing_canvas_document);
|
||||
harness.run("draw plan respects VR visibility modes", draw_plan_respects_vr_visibility_modes);
|
||||
return harness.finish();
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "app_core/about_menu.h"
|
||||
#include "app_core/app_preferences.h"
|
||||
#include "app_core/app_frame.h"
|
||||
#include "app_core/app_status.h"
|
||||
#include "app_core/app_startup.h"
|
||||
#include "app_core/brush_package_import.h"
|
||||
@@ -245,6 +246,16 @@ struct PlanAppStartupResourcesArgs {
|
||||
bool bad_size = false;
|
||||
};
|
||||
|
||||
struct PlanAppFrameArgs {
|
||||
bool redraw = false;
|
||||
bool animate = false;
|
||||
bool has_canvas_node = true;
|
||||
bool has_canvas_document = true;
|
||||
bool vr_active = false;
|
||||
bool ui_visible = true;
|
||||
bool vr_only = false;
|
||||
};
|
||||
|
||||
struct PlanBrushPackageExportArgs {
|
||||
std::string path;
|
||||
std::string author;
|
||||
@@ -2010,6 +2021,7 @@ void print_help()
|
||||
<< " 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"
|
||||
<< " plan-app-frame [--redraw] [--animate] [--no-canvas] [--no-canvas-document] [--vr-active] [--ui-hidden] [--vr-only]\n"
|
||||
<< " plan-app-status [--doc-name NAME] [--unsaved] [--resolution N] [--resolution-index N] [--zoom N] [--history-bytes N] [--recording-running] [--encoder-available] [--encoded-frames N] [--framebuffer-fetch] [--float32] [--float32-linear] [--float16]\n"
|
||||
<< " plan-brush-package-import --kind abr|ppbr --path FILE\n"
|
||||
<< " plan-brush-package-export --path FILE [--author NAME] [--email EMAIL] [--url URL] [--description TEXT] [--dest-path DIR] [--export-data|--no-export-data] [--header-image]\n"
|
||||
@@ -3715,6 +3727,68 @@ int plan_app_startup_resources(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_app_frame_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
PlanAppFrameArgs& args)
|
||||
{
|
||||
for (int i = 2; i < argc; ++i) {
|
||||
const std::string_view key(argv[i]);
|
||||
if (key == "--redraw") {
|
||||
args.redraw = true;
|
||||
} else if (key == "--animate") {
|
||||
args.animate = true;
|
||||
} else if (key == "--no-canvas") {
|
||||
args.has_canvas_node = false;
|
||||
args.has_canvas_document = false;
|
||||
} else if (key == "--no-canvas-document") {
|
||||
args.has_canvas_document = false;
|
||||
} else if (key == "--vr-active") {
|
||||
args.vr_active = true;
|
||||
} else if (key == "--ui-hidden") {
|
||||
args.ui_visible = false;
|
||||
} else if (key == "--vr-only") {
|
||||
args.vr_only = true;
|
||||
} else {
|
||||
return pp::foundation::Status::invalid_argument("unknown option");
|
||||
}
|
||||
}
|
||||
|
||||
return pp::foundation::Status::success();
|
||||
}
|
||||
|
||||
int plan_app_frame(int argc, char** argv)
|
||||
{
|
||||
PlanAppFrameArgs args;
|
||||
const auto status = parse_plan_app_frame_args(argc, argv, args);
|
||||
if (!status.ok()) {
|
||||
print_error("plan-app-frame", status.message);
|
||||
return 2;
|
||||
}
|
||||
|
||||
const auto surface = pp::app::plan_app_initial_surface();
|
||||
const auto update = pp::app::plan_app_frame_update(args.redraw, args.animate);
|
||||
const auto draw = pp::app::plan_app_frame_draw(
|
||||
args.has_canvas_node,
|
||||
args.has_canvas_document,
|
||||
args.vr_active,
|
||||
args.ui_visible,
|
||||
args.vr_only);
|
||||
|
||||
std::cout << "{\"ok\":true,\"command\":\"plan-app-frame\""
|
||||
<< ",\"surface\":{\"width\":" << surface.width
|
||||
<< ",\"height\":" << surface.height
|
||||
<< "},\"update\":{\"updateFrame\":" << json_bool(update.update_frame)
|
||||
<< ",\"updateLayouts\":" << json_bool(update.update_layouts)
|
||||
<< ",\"refreshCanvasToolbar\":" << json_bool(update.refresh_canvas_toolbar)
|
||||
<< "},\"draw\":{\"drawCanvasStroke\":" << json_bool(draw.draw_canvas_stroke)
|
||||
<< ",\"drawVrUi\":" << json_bool(draw.draw_vr_ui)
|
||||
<< ",\"drawMainUi\":" << json_bool(draw.draw_main_ui)
|
||||
<< ",\"resetRedraw\":" << json_bool(draw.reset_redraw)
|
||||
<< "}}\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
pp::foundation::Status parse_plan_brush_package_import_args(
|
||||
int argc,
|
||||
char** argv,
|
||||
@@ -9962,6 +10036,10 @@ int main(int argc, char** argv)
|
||||
return plan_app_startup_resources(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-app-frame") {
|
||||
return plan_app_frame(argc, argv);
|
||||
}
|
||||
|
||||
if (command == "plan-brush-package-import") {
|
||||
return plan_brush_package_import(argc, argv);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user