Extract platform policy catalog
This commit is contained in:
@@ -234,6 +234,8 @@ add_library(pp_platform_api STATIC
|
||||
src/platform_api/asset_file_load_policy.h
|
||||
src/platform_api/network_tls_policy.cpp
|
||||
src/platform_api/network_tls_policy.h
|
||||
src/platform_api/platform_policy.cpp
|
||||
src/platform_api/platform_policy.h
|
||||
src/platform_api/platform_services.cpp
|
||||
src/platform_api/platform_services.h)
|
||||
target_include_directories(pp_platform_api
|
||||
|
||||
@@ -739,6 +739,14 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p
|
||||
and cloud browse-dialog curl sites now consume the same default platform TLS
|
||||
policy helper in `pp_platform_api` instead of spelling Android branches
|
||||
locally;
|
||||
retained platform-family decisions for exported-image publishing,
|
||||
persistent-storage flushing, document browse roots, working-directory picker
|
||||
availability, prepared-file target planning, work-directory collection export
|
||||
policy, PPBR data-directory override policy, SonarPen availability, live
|
||||
asset reload policy, recording cleanup policy, default canvas resolution, and
|
||||
canvas tip visibility now live in the tested `platform_policy` catalog and
|
||||
are consumed by both `WindowsPlatformServices` and the retained non-Windows
|
||||
fallback;
|
||||
Windows
|
||||
live app execution now uses injected
|
||||
`WindowsPlatformServices` from
|
||||
@@ -908,7 +916,8 @@ powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.p
|
||||
- `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
|
||||
policy, and picker callbacks without platform SDK headers or a window.
|
||||
policy, platform-family export/storage/browse/prepared-file/canvas policies,
|
||||
and picker callbacks without platform SDK headers or a window.
|
||||
- `pp_app_core_document_cloud_tests` covers cloud upload no-canvas,
|
||||
new-document warning, clean publish prompt, and dirty save-before-upload
|
||||
decisions, plus cloud browse no-canvas/show-browser and selected-download
|
||||
@@ -1025,8 +1034,9 @@ Known warnings after the current CMake app build:
|
||||
should shrink as app painting and document behavior consume `pp_paint` and
|
||||
`pp_document` directly. Shared `canvas.h` no longer owns the platform
|
||||
`CANVAS_RES` macro; default canvas allocation now asks `PlatformServices`,
|
||||
preserving the WebGL 512 default in the legacy fallback while DEBT-0057
|
||||
tracks moving that policy into an injected Web platform service.
|
||||
preserving the WebGL 512 default through the tested `pp_platform_api`
|
||||
platform policy while DEBT-0057 tracks moving that policy into an injected
|
||||
Web platform service.
|
||||
- `pp_legacy_engine` intentionally contains retained legacy runtime shell
|
||||
sources for now, so it concentrates existing legacy tablet, video, HMD, log,
|
||||
and low-level utility warnings until those paths move to cleaner component
|
||||
|
||||
@@ -224,6 +224,16 @@ agent or engineer to remove them without reconstructing context from chat.
|
||||
Retained canvas/video export calls, Web prepared-file handoff, picker
|
||||
execution, export-directory creation, and desktop timelapse worker threading
|
||||
remain open.
|
||||
- 2026-06-05: DEBT-0050, DEBT-0051, DEBT-0053, and DEBT-0057 were narrowed.
|
||||
`pp_platform_api` now owns a tested `platform_policy` catalog for retained
|
||||
platform-family decisions covering iOS exported-image publishing, WebGL
|
||||
persistent-storage flushing, iOS document browse Inbox roots, Windows/macOS
|
||||
working-directory picker availability, iOS/Web prepared-file target
|
||||
selection, iOS collection-export working-directory policy, macOS PPBR data
|
||||
directory override, SonarPen availability, WebGL default canvas resolution,
|
||||
live asset reload policy, recording cleanup policy, and canvas tip visibility.
|
||||
`WindowsPlatformServices` and the non-Windows legacy fallback consume those
|
||||
helpers while SDK-specific execution remains open in platform shells.
|
||||
- 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
|
||||
@@ -287,14 +297,14 @@ agent or engineer to remove them without reconstructing context from chat.
|
||||
| DEBT-0047 | Open | Modernization | PPBR brush package export request validation, success-dialog metadata, and execution dispatch now consume pure `pp_app_core` through `App::dialog_ppbr_export`, `pano_cli plan-brush-package-export`, `BrushPackageExportServices`, and `src/legacy_brush_package_export_services.*`; PPBR header/path planning now consumes `pp_assets::brush_package`, and the macOS data-directory override now routes through `PlatformServices`, but the bridge still reads `NodeDialogExportPPBR`, carries the legacy `Image` header object outside the pure request, converts to `NodePanelBrushPreset::PPBRInfo`, calls `NodePanelBrushPreset::export_ppbr`, owns desktop worker-thread dispatch, dialog destruction, and mobile/Web completion directly | Preserve current PPBR export behavior while brush assets, PPBR serialization, picker completion, and UI lifetime move toward asset/storage/UI/platform services | `pp_assets_brush_package_tests`; `pp_app_core_brush_package_export_tests`; `pp_platform_api_tests`; `pano_cli plan-brush-package-export --path D:/Paint/clouds.ppbr --author Artist --dest-path D:/Paint/BrushPreviews --export-data --header-image`; `pano_cli plan-brush-package-export --path D:/Paint/clouds.ppbr`; `pano_cli plan-brush-package-export`; `pano_cli plan-brush-package-export --path clouds`; `pano_cli plan-brush-package-export --path D:/Paint/clouds.ppbr --dest-path D:/Paint/BrushPreviews --no-export-data`; `ctest --preset desktop-fast --build-config Debug`; `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter` | PPBR metadata collection, header-image ownership, serialization, picker-selected path execution, desktop threading, dialog lifetime, and mobile/Web completion are owned by injected brush asset/storage/UI/platform services with `App::dialog_ppbr_export` acting only as a UI adapter |
|
||||
| DEBT-0048 | Open | Modernization | ABR/PPBR brush package import execution now consumes pure `pp_app_core` through document-open confirmation callbacks, `pano_cli plan-brush-package-import`, `BrushPackageImportServices`, and `src/legacy_brush_package_import_services.*`; imported brush tip/pattern target paths now consume `pp_assets::brush_package`, but the bridge still launches detached legacy `NodePanelBrushPreset::import_abr`/`import_ppbr` worker threads and depends on the legacy preset panel as the importer/storage owner | Preserve current brush import behavior while brush package parsing, preset storage, progress/error reporting, and UI refresh move toward asset/paint/UI services | `pp_assets_brush_package_tests`; `pp_app_core_brush_package_import_tests`; `pano_cli plan-brush-package-import --kind ppbr --path D:/Paint/Brushes/clouds.ppbr`; `pano_cli plan-brush-package-import --kind abr --path D:/Paint/Brushes/clouds.abr`; `pano_cli plan-brush-package-import --kind ppbr`; `ctest --preset desktop-fast --build-config Debug`; `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter` | ABR/PPBR parsing, preset creation/storage, import threading/progress, duplicate asset policy, and UI refresh are owned by injected brush asset/paint/UI services with document-open callbacks only confirming user intent |
|
||||
| DEBT-0049 | Open | Modernization | `pp_assets::validate_ppbr_header` intentionally preserves the legacy PPBR version check from `NodePanelBrushPreset::import_ppbr`, which accepts files when either major is `0` or minor is `1` instead of requiring exactly version `0.1` | Avoid rejecting existing brush packages before compatibility fixtures prove the stricter rule is safe | `pp_assets_brush_package_tests`; `pano_cli plan-brush-package-export --path D:/Paint/clouds.ppbr`; `ctest --preset desktop-fast --build-config Debug`; `cmake --build --preset windows-msvc-default --config Debug --target PanoPainter` | Add PPBR compatibility fixtures for accepted/rejected historical package versions, then require canonical `0.1` or an explicit supported-version matrix and update live import accordingly |
|
||||
| DEBT-0050 | Open | Modernization | iOS exported-image photo-library publishing and WebGL persistent-storage flushing now dispatch through `PlatformServices`, but non-Windows execution still lives in `src/platform_legacy/legacy_platform_services.*` and forwards to retained `save_image_library`/`webgl_sync` bridges | Preserve current iOS/Web export and save behavior while the Apple/Web platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; platform package smoke once Apple/Web root builds exist | Exported-image publishing and persistent-storage flushing are owned by injected Apple/Web `pp_platform_*` services with no legacy adapter branch |
|
||||
| DEBT-0051 | Open | Modernization | Document browser search roots and Browse dialog working-directory picker visibility/path formatting now dispatch through `PlatformServices`, but iOS `Inbox` inclusion and macOS directory picker/display-path behavior still live in `src/platform_legacy/legacy_platform_services.*` | Preserve current iOS document import/browse and desktop browse picker behavior while Apple platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Apple package smoke once root Apple builds exist | Document browse roots and browse-directory picker/display formatting are owned by injected Apple and desktop `pp_platform_*` services with no legacy adapter branch |
|
||||
| DEBT-0050 | Open | Modernization | iOS exported-image photo-library publishing and WebGL persistent-storage flushing now dispatch through `PlatformServices`; the iOS/Web policy decision lives in tested `pp_platform_api::platform_policy`, but non-Windows execution still lives in `src/platform_legacy/legacy_platform_services.*` and forwards to retained `save_image_library`/`webgl_sync` bridges | Preserve current iOS/Web export and save behavior while the Apple/Web platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; platform package smoke once Apple/Web root builds exist | Exported-image publishing and persistent-storage flushing are owned by injected Apple/Web `pp_platform_*` services with no legacy adapter branch |
|
||||
| DEBT-0051 | Open | Modernization | Document browser search roots and Browse dialog working-directory picker visibility/path formatting now dispatch through `PlatformServices`; iOS Inbox roots and working-directory picker availability live in tested `pp_platform_api::platform_policy`, but macOS directory picker/display-path execution still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve current iOS document import/browse and desktop browse picker behavior while Apple platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Apple package smoke once root Apple builds exist | Document browse roots and browse-directory picker/display formatting are owned by injected Apple and desktop `pp_platform_*` services with no legacy adapter branch |
|
||||
| DEBT-0052 | Open | Modernization | Native UI/window state saving now dispatches through `PlatformServices`, but macOS execution still lives in `src/platform_legacy/legacy_platform_services.*` and forwards to the retained Objective-C app bridge | Preserve current Windows/macOS UI persistence while platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Windows app build; Apple package smoke once root Apple builds exist | UI/window state persistence is owned by injected platform services with no legacy adapter branch |
|
||||
| DEBT-0053 | Open | Modernization | Prepared-file writable target selection and prepared-file export-dialog policy now dispatch through `PlatformServices`, but iOS/Web target selection still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve mobile/Web export handoff behavior while platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Windows app build; Apple/Web package smoke once root package builds exist | Prepared-file target selection, export-dialog policy, and save/download handoff are owned by injected platform services with no legacy adapter branch |
|
||||
| DEBT-0053 | Open | Modernization | Prepared-file writable target selection and prepared-file export-dialog policy now dispatch through `PlatformServices`; iOS temporary-file and WebGL data-path target planning live in tested `pp_platform_api::platform_policy`, but retained iOS/Web save/download handoff execution still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve mobile/Web export handoff behavior while platform shells are extracted incrementally | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug`; Windows app build; Apple/Web package smoke once root package builds exist | Prepared-file target selection, export-dialog policy, and save/download handoff are owned by injected platform services with no legacy adapter branch |
|
||||
| DEBT-0054 | Open | Modernization | Layout XML file read/reload decisions now consume `pp_platform_api::plan_asset_file_load`, but that helper still encodes the retained compile-time platform policy: Windows/macOS use `stat` mtime reload checks, while other platforms treat already-loaded layouts as successful no-op loads | Preserve current layout hot-reload and mobile/Web single-load behavior while removing platform guards from the shared `LayoutManager` parser | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests`; Windows app build | Layout reload decisions are owned by injected platform storage/file-watch services or an asset manager boundary with platform-specific file watching removed from compile-time helpers |
|
||||
| DEBT-0055 | Open | Modernization | `src/app.h` now forward-declares retained iOS/macOS/Android/Linux/Web platform handles instead of including platform SDK headers, and full SDK includes are isolated in `src/platform_legacy/legacy_platform_services.cpp`, but the `App` singleton still stores those platform handles directly | Reduce central header platform coupling incrementally without rewriting non-Windows platform entrypoints before Phase 6 | Windows app build; Apple/Android/Linux/Web package smoke once platform root builds are active | Platform handles are owned by injected `pp_platform_*` shell state or services, and `App` has no platform SDK handle fields or platform conditional members |
|
||||
| DEBT-0056 | Open | Modernization | `src/asset.h` now forward-declares Android asset-manager types and uses `Asset::set_android_asset_manager` instead of public mutable manager state, but retained `Asset` still stores Android asset handles and `src/asset.cpp` still performs Android `AAssetManager` reads directly; the current `android-arm64` root preset is headless and does not expose `pp_legacy_assets_io` | Reduce legacy asset I/O header coupling without rewriting Android asset loading before the asset manager/storage boundary exists | Windows app build; `cmake --build --preset android-arm64 --target pp_assets`; Android package smoke once package builds consume shared targets | Android asset loading is owned by injected asset storage/platform services or `pp_assets` file providers, with no static Android asset manager on `Asset` |
|
||||
| DEBT-0057 | Open | Modernization | Default canvas allocation size now dispatches through `PlatformServices::default_canvas_resolution`, removing the `CANVAS_RES` platform macro from `src/canvas.h`, but WebGL's retained 512 default still lives in `src/platform_legacy/legacy_platform_services.cpp` until the Web shell owns injected services | Preserve WebGL memory behavior while moving canvas creation policy out of shared canvas headers and into the platform boundary | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests`; Windows app build; WebGL package smoke once root Web build exists | Default canvas resolution is owned by injected `pp_platform_*` services for every supported platform, with no WebGL branch in the legacy fallback |
|
||||
| DEBT-0057 | Open | Modernization | Default canvas allocation size now dispatches through `PlatformServices::default_canvas_resolution`, removing the `CANVAS_RES` platform macro from `src/canvas.h`; WebGL's retained 512 default now lives in tested `pp_platform_api::platform_policy`, but the Web shell still reaches it through the legacy platform fallback until injected Web services own the policy | Preserve WebGL memory behavior while moving canvas creation policy out of shared canvas headers and into the platform boundary | `pp_platform_api_tests`; `ctest --preset desktop-fast --build-config Debug -R pp_platform_api_tests`; Windows app build; WebGL package smoke once root Web build exists | Default canvas resolution is owned by injected `pp_platform_*` services for every supported platform, with no WebGL branch in the legacy fallback |
|
||||
| DEBT-0058 | Open | Modernization | App-level progress/message/input dialog metadata, including message-dialog OK/cancel captions, now consumes pure `pp_app_core` through `App::show_progress`, `App::message_box`, `App::input_box`, `pano_cli plan-app-dialog`, and `pp_app_core_app_dialog_tests`; live execution is centralized in `src/legacy_app_dialog_services.*`, but the bridge still creates retained `NodeProgressBar`, `NodeMessageBox`, and `NodeInputBox` instances and inserts them into the legacy layout tree | Preserve current app-shell dialog behavior while moving shared dialog policy toward UI/app services | `pp_app_core_app_dialog_tests`; `pano_cli plan-app-dialog --kind progress --total -4`; `pano_cli plan-app-dialog --kind message --cancel`; `pano_cli plan-app-dialog --kind input --ok-caption Save`; `ctest --preset desktop-fast --build-config Debug`; Windows app build | Progress/message/input dialog creation, callback wiring, layout insertion, lifetime ownership, and headless automation are owned by injected app/UI services with `App` methods acting only as adapters |
|
||||
| DEBT-0059 | Open | Modernization | iOS root CMake headless builds assign generated bundle identifiers and disable code signing for executable test/tool targets | The current Apple gate is compile validation for shared component targets; signed iOS app/package validation is not migrated to root CMake yet | `powershell -ExecutionPolicy Bypass -File scripts\automation\apple-remote-build.ps1 -Presets macos,ios-simulator,ios-device`; `sh scripts/automation/platform-build.sh "ios-device"` on `panopainter-mac` | Root CMake owns the signed Apple app/package targets, package-smoke validates Apple bundles where signing material is available, and headless iOS test/tool targets are either excluded from signed package builds or use explicit test-runner signing policy |
|
||||
|
||||
|
||||
@@ -1399,6 +1399,14 @@ current headless matrix, and builds `macos`, `ios-simulator`, and `ios-device`.
|
||||
The iOS device compile gate assigns generated bundle identifiers and disables
|
||||
code signing for test/tool executables under DEBT-0059; signed Apple app bundle
|
||||
and package-smoke migration remains open under DEBT-0011.
|
||||
`pp_platform_api` now also owns a tested platform-family policy catalog used by
|
||||
both `WindowsPlatformServices` and the retained non-Windows fallback for
|
||||
exported-image publishing, persistent-storage flushing, document browse roots,
|
||||
working-directory picker availability, prepared-file target planning,
|
||||
work-directory collection export policy, PPBR data-directory override policy,
|
||||
SonarPen availability, live asset reload policy, recording cleanup policy,
|
||||
default canvas resolution, and canvas tip visibility. Platform SDK calls remain
|
||||
in the platform shells while those decisions are headless-testable.
|
||||
|
||||
Implementation tasks:
|
||||
|
||||
|
||||
133
src/platform_api/platform_policy.cpp
Normal file
133
src/platform_api/platform_policy.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
#include "platform_api/platform_policy.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace pp::platform {
|
||||
|
||||
PlatformFamily current_platform_family() noexcept
|
||||
{
|
||||
#if defined(__IOS__)
|
||||
return PlatformFamily::ios;
|
||||
#elif defined(__OSX__)
|
||||
return PlatformFamily::macos;
|
||||
#elif defined(__ANDROID__)
|
||||
return PlatformFamily::android;
|
||||
#elif defined(__LINUX__)
|
||||
return PlatformFamily::linux;
|
||||
#elif defined(__WEB__)
|
||||
return PlatformFamily::webgl;
|
||||
#elif defined(_WIN32)
|
||||
return PlatformFamily::windows;
|
||||
#else
|
||||
return PlatformFamily::generic_desktop;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool platform_deletes_recorded_files_on_clear(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::ios || family == PlatformFamily::macos;
|
||||
}
|
||||
|
||||
bool platform_publishes_exported_images(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::ios;
|
||||
}
|
||||
|
||||
bool platform_flushes_persistent_storage(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::webgl;
|
||||
}
|
||||
|
||||
bool platform_enables_live_asset_reloading(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::windows || family == PlatformFamily::macos;
|
||||
}
|
||||
|
||||
bool platform_supports_working_directory_picker(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::windows || family == PlatformFamily::macos;
|
||||
}
|
||||
|
||||
bool platform_uses_prepared_file_writes(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::ios || family == PlatformFamily::webgl;
|
||||
}
|
||||
|
||||
bool platform_uses_work_directory_document_export_collections(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::ios;
|
||||
}
|
||||
|
||||
bool platform_uses_ppbr_export_data_directory_override(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::macos;
|
||||
}
|
||||
|
||||
bool platform_supports_sonarpen(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::ios;
|
||||
}
|
||||
|
||||
int platform_default_canvas_resolution(PlatformFamily family) noexcept
|
||||
{
|
||||
return family == PlatformFamily::webgl ? 512 : 1536;
|
||||
}
|
||||
|
||||
bool platform_draws_canvas_tip_for_pointer(
|
||||
PlatformFamily family,
|
||||
bool is_mouse,
|
||||
bool is_stylus,
|
||||
bool is_left_button_release) noexcept
|
||||
{
|
||||
if (family == PlatformFamily::ios)
|
||||
return is_mouse && !is_left_button_release;
|
||||
return is_mouse || is_stylus;
|
||||
}
|
||||
|
||||
std::vector<std::string> platform_document_browse_roots(
|
||||
PlatformFamily family,
|
||||
std::string_view work_path,
|
||||
std::string_view data_path)
|
||||
{
|
||||
if (family == PlatformFamily::ios)
|
||||
{
|
||||
return {
|
||||
std::string(work_path),
|
||||
std::string(data_path) + "/Inbox",
|
||||
};
|
||||
}
|
||||
|
||||
return { std::string(work_path) };
|
||||
}
|
||||
|
||||
PreparedFileTarget plan_platform_writable_file(
|
||||
PlatformFamily family,
|
||||
std::string_view type,
|
||||
std::string_view default_name,
|
||||
std::string_view data_path,
|
||||
std::string_view temporary_path)
|
||||
{
|
||||
const std::string name = std::string(default_name) + "." + std::string(type);
|
||||
|
||||
if (family == PlatformFamily::ios)
|
||||
{
|
||||
return {
|
||||
std::string(temporary_path) + "/" + name,
|
||||
name,
|
||||
true,
|
||||
};
|
||||
}
|
||||
|
||||
if (family == PlatformFamily::webgl)
|
||||
{
|
||||
return {
|
||||
std::string(data_path) + "/" + name,
|
||||
name,
|
||||
false,
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
51
src/platform_api/platform_policy.h
Normal file
51
src/platform_api/platform_policy.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "platform_api/platform_services.h"
|
||||
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace pp::platform {
|
||||
|
||||
enum class PlatformFamily {
|
||||
generic_desktop,
|
||||
windows,
|
||||
macos,
|
||||
ios,
|
||||
android,
|
||||
linux,
|
||||
webgl,
|
||||
};
|
||||
|
||||
[[nodiscard]] PlatformFamily current_platform_family() noexcept;
|
||||
|
||||
[[nodiscard]] bool platform_deletes_recorded_files_on_clear(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_publishes_exported_images(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_flushes_persistent_storage(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_enables_live_asset_reloading(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_supports_working_directory_picker(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_uses_prepared_file_writes(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_uses_work_directory_document_export_collections(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_uses_ppbr_export_data_directory_override(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] bool platform_supports_sonarpen(PlatformFamily family) noexcept;
|
||||
[[nodiscard]] int platform_default_canvas_resolution(PlatformFamily family) noexcept;
|
||||
|
||||
[[nodiscard]] bool platform_draws_canvas_tip_for_pointer(
|
||||
PlatformFamily family,
|
||||
bool is_mouse,
|
||||
bool is_stylus,
|
||||
bool is_left_button_release) noexcept;
|
||||
|
||||
[[nodiscard]] std::vector<std::string> platform_document_browse_roots(
|
||||
PlatformFamily family,
|
||||
std::string_view work_path,
|
||||
std::string_view data_path);
|
||||
|
||||
[[nodiscard]] PreparedFileTarget plan_platform_writable_file(
|
||||
PlatformFamily family,
|
||||
std::string_view type,
|
||||
std::string_view default_name,
|
||||
std::string_view data_path,
|
||||
std::string_view temporary_path);
|
||||
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "app_core/document_platform_io.h"
|
||||
#include "log.h"
|
||||
#include "platform_api/network_tls_policy.h"
|
||||
#include "platform_api/platform_policy.h"
|
||||
#include "renderer_gl/opengl_capabilities.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -288,11 +289,8 @@ public:
|
||||
|
||||
[[nodiscard]] bool deletes_recorded_files_on_clear() override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return pp::platform::platform_deletes_recorded_files_on_clear(
|
||||
pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
void clear_recorded_files(std::string_view recording_path) override
|
||||
@@ -306,6 +304,11 @@ public:
|
||||
|
||||
void publish_exported_image(std::string_view path) override
|
||||
{
|
||||
if (!pp::platform::platform_publishes_exported_images(pp::platform::current_platform_family()))
|
||||
{
|
||||
(void)path;
|
||||
return;
|
||||
}
|
||||
#ifdef __IOS__
|
||||
save_image_library(std::string(path));
|
||||
#else
|
||||
@@ -315,6 +318,8 @@ public:
|
||||
|
||||
void flush_persistent_storage() override
|
||||
{
|
||||
if (!pp::platform::platform_flushes_persistent_storage(pp::platform::current_platform_family()))
|
||||
return;
|
||||
#ifdef __WEB__
|
||||
webgl_sync();
|
||||
#endif
|
||||
@@ -324,15 +329,10 @@ public:
|
||||
std::string_view work_path,
|
||||
std::string_view data_path) override
|
||||
{
|
||||
#ifdef __IOS__
|
||||
return {
|
||||
std::string(work_path),
|
||||
std::string(data_path) + "/Inbox",
|
||||
};
|
||||
#else
|
||||
(void)data_path;
|
||||
return { std::string(work_path) };
|
||||
#endif
|
||||
return pp::platform::platform_document_browse_roots(
|
||||
pp::platform::current_platform_family(),
|
||||
work_path,
|
||||
data_path);
|
||||
}
|
||||
|
||||
void save_ui_state() override
|
||||
@@ -344,11 +344,8 @@ public:
|
||||
|
||||
[[nodiscard]] bool enables_live_asset_reloading() override
|
||||
{
|
||||
#if defined(__OSX__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return pp::platform::platform_enables_live_asset_reloading(
|
||||
pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
void update_platform_frame(float delta_time_seconds) override
|
||||
@@ -455,11 +452,8 @@ public:
|
||||
|
||||
[[nodiscard]] bool supports_working_directory_picker() override
|
||||
{
|
||||
#if defined(__OSX__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return pp::platform::platform_supports_working_directory_picker(
|
||||
pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string format_working_directory_path(std::string_view path) override
|
||||
@@ -474,20 +468,14 @@ public:
|
||||
|
||||
[[nodiscard]] bool uses_prepared_file_writes() override
|
||||
{
|
||||
#if __IOS__ || __WEB__
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return pp::platform::platform_uses_prepared_file_writes(
|
||||
pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
[[nodiscard]] bool uses_work_directory_document_export_collections() override
|
||||
{
|
||||
#if __IOS__
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return pp::platform::platform_uses_work_directory_document_export_collections(
|
||||
pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
[[nodiscard]] bool disables_network_tls_verification() override
|
||||
@@ -497,20 +485,13 @@ public:
|
||||
|
||||
[[nodiscard]] bool uses_ppbr_export_data_directory_override() override
|
||||
{
|
||||
#if defined(__OSX__)
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return pp::platform::platform_uses_ppbr_export_data_directory_override(
|
||||
pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
[[nodiscard]] bool supports_sonarpen() override
|
||||
{
|
||||
#if __IOS__
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
return pp::platform::platform_supports_sonarpen(pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
void start_sonarpen() override
|
||||
@@ -522,11 +503,8 @@ public:
|
||||
|
||||
[[nodiscard]] int default_canvas_resolution() override
|
||||
{
|
||||
#if __WEB__
|
||||
return 512;
|
||||
#else
|
||||
return 1536;
|
||||
#endif
|
||||
return pp::platform::platform_default_canvas_resolution(
|
||||
pp::platform::current_platform_family());
|
||||
}
|
||||
|
||||
[[nodiscard]] bool draws_canvas_tip_for_pointer(
|
||||
@@ -534,13 +512,11 @@ public:
|
||||
bool is_stylus,
|
||||
bool is_left_button_release) override
|
||||
{
|
||||
#if defined(__IOS__)
|
||||
(void)is_stylus;
|
||||
return is_mouse && !is_left_button_release;
|
||||
#else
|
||||
(void)is_left_button_release;
|
||||
return is_mouse || is_stylus;
|
||||
#endif
|
||||
return pp::platform::platform_draws_canvas_tip_for_pointer(
|
||||
pp::platform::current_platform_family(),
|
||||
is_mouse,
|
||||
is_stylus,
|
||||
is_left_button_release);
|
||||
}
|
||||
|
||||
[[nodiscard]] float adjust_canvas_input_pressure(float pressure) override
|
||||
@@ -554,26 +530,12 @@ public:
|
||||
std::string_view data_path,
|
||||
std::string_view temporary_path) override
|
||||
{
|
||||
const std::string name = std::string(default_name) + "." + std::string(type);
|
||||
#ifdef __IOS__
|
||||
(void)data_path;
|
||||
return {
|
||||
std::string(temporary_path) + "/" + name,
|
||||
name,
|
||||
true,
|
||||
};
|
||||
#elif __WEB__
|
||||
(void)temporary_path;
|
||||
return {
|
||||
std::string(data_path) + "/" + name,
|
||||
name,
|
||||
false,
|
||||
};
|
||||
#else
|
||||
(void)data_path;
|
||||
(void)temporary_path;
|
||||
return {};
|
||||
#endif
|
||||
return pp::platform::plan_platform_writable_file(
|
||||
pp::platform::current_platform_family(),
|
||||
type,
|
||||
default_name,
|
||||
data_path,
|
||||
temporary_path);
|
||||
}
|
||||
|
||||
void display_file(std::string_view path) override
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "platform_api/network_tls_policy.h"
|
||||
#include "platform_api/platform_policy.h"
|
||||
#include "renderer_gl/opengl_capabilities.h"
|
||||
|
||||
#include <deque>
|
||||
@@ -368,7 +369,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool deletes_recorded_files_on_clear() override
|
||||
{
|
||||
return false;
|
||||
return pp::platform::platform_deletes_recorded_files_on_clear(pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
void clear_recorded_files(std::string_view recording_path) override
|
||||
@@ -378,19 +379,28 @@ public:
|
||||
|
||||
void publish_exported_image(std::string_view path) override
|
||||
{
|
||||
if (!pp::platform::platform_publishes_exported_images(pp::platform::PlatformFamily::windows))
|
||||
{
|
||||
(void)path;
|
||||
return;
|
||||
}
|
||||
(void)path;
|
||||
}
|
||||
|
||||
void flush_persistent_storage() override
|
||||
{
|
||||
if (!pp::platform::platform_flushes_persistent_storage(pp::platform::PlatformFamily::windows))
|
||||
return;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::vector<std::string> document_browse_roots(
|
||||
std::string_view work_path,
|
||||
std::string_view data_path) override
|
||||
{
|
||||
(void)data_path;
|
||||
return { std::string(work_path) };
|
||||
return pp::platform::platform_document_browse_roots(
|
||||
pp::platform::PlatformFamily::windows,
|
||||
work_path,
|
||||
data_path);
|
||||
}
|
||||
|
||||
void save_ui_state() override
|
||||
@@ -400,7 +410,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool enables_live_asset_reloading() override
|
||||
{
|
||||
return true;
|
||||
return pp::platform::platform_enables_live_asset_reloading(pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
void update_platform_frame(float delta_time_seconds) override
|
||||
@@ -466,7 +476,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool supports_working_directory_picker() override
|
||||
{
|
||||
return true;
|
||||
return pp::platform::platform_supports_working_directory_picker(pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string format_working_directory_path(std::string_view path) override
|
||||
@@ -484,12 +494,13 @@ public:
|
||||
|
||||
[[nodiscard]] bool uses_prepared_file_writes() override
|
||||
{
|
||||
return false;
|
||||
return pp::platform::platform_uses_prepared_file_writes(pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool uses_work_directory_document_export_collections() override
|
||||
{
|
||||
return false;
|
||||
return pp::platform::platform_uses_work_directory_document_export_collections(
|
||||
pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool disables_network_tls_verification() override
|
||||
@@ -499,12 +510,13 @@ public:
|
||||
|
||||
[[nodiscard]] bool uses_ppbr_export_data_directory_override() override
|
||||
{
|
||||
return false;
|
||||
return pp::platform::platform_uses_ppbr_export_data_directory_override(
|
||||
pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool supports_sonarpen() override
|
||||
{
|
||||
return false;
|
||||
return pp::platform::platform_supports_sonarpen(pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
void start_sonarpen() override
|
||||
@@ -513,7 +525,7 @@ public:
|
||||
|
||||
[[nodiscard]] int default_canvas_resolution() override
|
||||
{
|
||||
return 1536;
|
||||
return pp::platform::platform_default_canvas_resolution(pp::platform::PlatformFamily::windows);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool draws_canvas_tip_for_pointer(
|
||||
@@ -521,8 +533,11 @@ public:
|
||||
bool is_stylus,
|
||||
bool is_left_button_release) override
|
||||
{
|
||||
(void)is_left_button_release;
|
||||
return is_mouse || is_stylus;
|
||||
return pp::platform::platform_draws_canvas_tip_for_pointer(
|
||||
pp::platform::PlatformFamily::windows,
|
||||
is_mouse,
|
||||
is_stylus,
|
||||
is_left_button_release);
|
||||
}
|
||||
|
||||
[[nodiscard]] float adjust_canvas_input_pressure(float pressure) override
|
||||
@@ -539,11 +554,12 @@ public:
|
||||
std::string_view data_path,
|
||||
std::string_view temporary_path) override
|
||||
{
|
||||
(void)type;
|
||||
(void)default_name;
|
||||
(void)data_path;
|
||||
(void)temporary_path;
|
||||
return {};
|
||||
return pp::platform::plan_platform_writable_file(
|
||||
pp::platform::PlatformFamily::windows,
|
||||
type,
|
||||
default_name,
|
||||
data_path,
|
||||
temporary_path);
|
||||
}
|
||||
|
||||
void save_prepared_file(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "platform_api/asset_file_load_policy.h"
|
||||
#include "platform_api/network_tls_policy.h"
|
||||
#include "platform_api/platform_policy.h"
|
||||
#include "platform_api/platform_services.h"
|
||||
|
||||
#include <filesystem>
|
||||
@@ -853,6 +854,104 @@ void platform_services_dispatch_canvas_input_policy(pp::tests::Harness& harness)
|
||||
PP_EXPECT(harness, fake.canvas_pressure_adjustments == 1);
|
||||
}
|
||||
|
||||
void platform_policy_preserves_recording_and_export_storage_rules(pp::tests::Harness& harness)
|
||||
{
|
||||
PP_EXPECT(harness, pp::platform::platform_deletes_recorded_files_on_clear(pp::platform::PlatformFamily::ios));
|
||||
PP_EXPECT(harness, pp::platform::platform_deletes_recorded_files_on_clear(pp::platform::PlatformFamily::macos));
|
||||
PP_EXPECT(harness, !pp::platform::platform_deletes_recorded_files_on_clear(pp::platform::PlatformFamily::windows));
|
||||
PP_EXPECT(harness, pp::platform::platform_publishes_exported_images(pp::platform::PlatformFamily::ios));
|
||||
PP_EXPECT(harness, !pp::platform::platform_publishes_exported_images(pp::platform::PlatformFamily::macos));
|
||||
PP_EXPECT(harness, pp::platform::platform_flushes_persistent_storage(pp::platform::PlatformFamily::webgl));
|
||||
PP_EXPECT(harness, !pp::platform::platform_flushes_persistent_storage(pp::platform::PlatformFamily::windows));
|
||||
}
|
||||
|
||||
void platform_policy_preserves_document_browse_roots(pp::tests::Harness& harness)
|
||||
{
|
||||
const auto ios_roots = pp::platform::platform_document_browse_roots(
|
||||
pp::platform::PlatformFamily::ios,
|
||||
"D:/Paint/work",
|
||||
"D:/Paint");
|
||||
const auto desktop_roots = pp::platform::platform_document_browse_roots(
|
||||
pp::platform::PlatformFamily::windows,
|
||||
"D:/Paint/work",
|
||||
"D:/Paint");
|
||||
|
||||
PP_EXPECT(harness, ios_roots.size() == 2);
|
||||
PP_EXPECT(harness, ios_roots[0] == "D:/Paint/work");
|
||||
PP_EXPECT(harness, ios_roots[1] == "D:/Paint/Inbox");
|
||||
PP_EXPECT(harness, desktop_roots.size() == 1);
|
||||
PP_EXPECT(harness, desktop_roots[0] == "D:/Paint/work");
|
||||
}
|
||||
|
||||
void platform_policy_preserves_picker_and_prepared_file_rules(pp::tests::Harness& harness)
|
||||
{
|
||||
PP_EXPECT(harness, pp::platform::platform_supports_working_directory_picker(pp::platform::PlatformFamily::windows));
|
||||
PP_EXPECT(harness, pp::platform::platform_supports_working_directory_picker(pp::platform::PlatformFamily::macos));
|
||||
PP_EXPECT(harness, !pp::platform::platform_supports_working_directory_picker(pp::platform::PlatformFamily::ios));
|
||||
PP_EXPECT(harness, pp::platform::platform_uses_prepared_file_writes(pp::platform::PlatformFamily::ios));
|
||||
PP_EXPECT(harness, pp::platform::platform_uses_prepared_file_writes(pp::platform::PlatformFamily::webgl));
|
||||
PP_EXPECT(harness, !pp::platform::platform_uses_prepared_file_writes(pp::platform::PlatformFamily::windows));
|
||||
PP_EXPECT(harness, pp::platform::platform_uses_work_directory_document_export_collections(pp::platform::PlatformFamily::ios));
|
||||
PP_EXPECT(harness, !pp::platform::platform_uses_work_directory_document_export_collections(pp::platform::PlatformFamily::webgl));
|
||||
|
||||
const auto ios_target = pp::platform::plan_platform_writable_file(
|
||||
pp::platform::PlatformFamily::ios,
|
||||
"mp4",
|
||||
"timelapse",
|
||||
"/PanoPainter",
|
||||
"/tmp");
|
||||
PP_EXPECT(harness, ios_target.path == "/tmp/timelapse.mp4");
|
||||
PP_EXPECT(harness, ios_target.suggested_name == "timelapse.mp4");
|
||||
PP_EXPECT(harness, ios_target.write_on_background_thread);
|
||||
|
||||
const auto web_target = pp::platform::plan_platform_writable_file(
|
||||
pp::platform::PlatformFamily::webgl,
|
||||
"png",
|
||||
"export",
|
||||
"/PanoPainter",
|
||||
"/tmp");
|
||||
PP_EXPECT(harness, web_target.path == "/PanoPainter/export.png");
|
||||
PP_EXPECT(harness, web_target.suggested_name == "export.png");
|
||||
PP_EXPECT(harness, !web_target.write_on_background_thread);
|
||||
|
||||
const auto desktop_target = pp::platform::plan_platform_writable_file(
|
||||
pp::platform::PlatformFamily::windows,
|
||||
"png",
|
||||
"export",
|
||||
"/PanoPainter",
|
||||
"/tmp");
|
||||
PP_EXPECT(harness, desktop_target.path.empty());
|
||||
PP_EXPECT(harness, desktop_target.suggested_name.empty());
|
||||
}
|
||||
|
||||
void platform_policy_preserves_ui_asset_and_input_rules(pp::tests::Harness& harness)
|
||||
{
|
||||
PP_EXPECT(harness, pp::platform::platform_enables_live_asset_reloading(pp::platform::PlatformFamily::windows));
|
||||
PP_EXPECT(harness, pp::platform::platform_enables_live_asset_reloading(pp::platform::PlatformFamily::macos));
|
||||
PP_EXPECT(harness, !pp::platform::platform_enables_live_asset_reloading(pp::platform::PlatformFamily::ios));
|
||||
PP_EXPECT(harness, pp::platform::platform_uses_ppbr_export_data_directory_override(pp::platform::PlatformFamily::macos));
|
||||
PP_EXPECT(harness, !pp::platform::platform_uses_ppbr_export_data_directory_override(pp::platform::PlatformFamily::windows));
|
||||
PP_EXPECT(harness, pp::platform::platform_supports_sonarpen(pp::platform::PlatformFamily::ios));
|
||||
PP_EXPECT(harness, !pp::platform::platform_supports_sonarpen(pp::platform::PlatformFamily::android));
|
||||
PP_EXPECT(harness, pp::platform::platform_default_canvas_resolution(pp::platform::PlatformFamily::webgl) == 512);
|
||||
PP_EXPECT(harness, pp::platform::platform_default_canvas_resolution(pp::platform::PlatformFamily::windows) == 1536);
|
||||
PP_EXPECT(harness, pp::platform::platform_draws_canvas_tip_for_pointer(
|
||||
pp::platform::PlatformFamily::ios,
|
||||
true,
|
||||
false,
|
||||
false));
|
||||
PP_EXPECT(harness, !pp::platform::platform_draws_canvas_tip_for_pointer(
|
||||
pp::platform::PlatformFamily::ios,
|
||||
true,
|
||||
false,
|
||||
true));
|
||||
PP_EXPECT(harness, pp::platform::platform_draws_canvas_tip_for_pointer(
|
||||
pp::platform::PlatformFamily::windows,
|
||||
false,
|
||||
true,
|
||||
true));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -894,5 +993,15 @@ int main()
|
||||
harness.run("platform services dispatch sonarpen policy and start", platform_services_dispatch_sonarpen_policy_and_start);
|
||||
harness.run("platform services dispatch default canvas resolution", platform_services_dispatch_default_canvas_resolution);
|
||||
harness.run("platform services dispatch canvas input policy", platform_services_dispatch_canvas_input_policy);
|
||||
harness.run(
|
||||
"platform policy preserves recording and export storage rules",
|
||||
platform_policy_preserves_recording_and_export_storage_rules);
|
||||
harness.run("platform policy preserves document browse roots", platform_policy_preserves_document_browse_roots);
|
||||
harness.run(
|
||||
"platform policy preserves picker and prepared file rules",
|
||||
platform_policy_preserves_picker_and_prepared_file_rules);
|
||||
harness.run(
|
||||
"platform policy preserves UI asset and input rules",
|
||||
platform_policy_preserves_ui_asset_and_input_rules);
|
||||
return harness.finish();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user