Extract platform policy catalog

This commit is contained in:
2026-06-05 11:39:21 +02:00
parent ab3637af9c
commit b1d71f2621
9 changed files with 401 additions and 100 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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:

View 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 {};
}
}

View 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);
}

View File

@@ -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

View File

@@ -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(

View 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();
}