diff --git a/docs/modernization/build-inventory.md b/docs/modernization/build-inventory.md index 78cb858..fb6e5bc 100644 --- a/docs/modernization/build-inventory.md +++ b/docs/modernization/build-inventory.md @@ -1027,12 +1027,15 @@ Known warnings after the current CMake app build: an SDK import target, or a documented permanent vendored target. - `pp_legacy_assets_io` is an object-library containment boundary for retained ABR, asset/file, binary stream, image, serializer, and settings code. It - should shrink as app I/O consumes `pp_assets` directly. `src/asset.h` now - forward-declares Android asset-manager types and exposes - `Asset::set_android_asset_manager` instead of public mutable Android asset - manager state; concrete Android asset-manager headers remain in `asset.cpp` + should shrink as app I/O consumes `pp_assets` directly. `src/asset.h` is now + Android-SDK-free and exposes `Asset::set_android_asset_manager` with opaque + handles instead of public mutable Android asset-manager state or SDK forward + declarations; concrete Android asset-manager headers remain in `asset.cpp` and the retained Android entrypoint while DEBT-0056 tracks replacing the - static Android asset bridge with injected asset storage. + static Android asset bridge with injected asset storage. A focused legacy + Android object build validates `src/asset.cpp`; the full old Android + `native-lib` target still fails later on unrelated C++ standard/header + modernization issues. - `pp_legacy_paint_document` is an object-library containment boundary for retained action, bezier, brush, canvas, canvas-layer, and event code. It should shrink as app painting and document behavior consume `pp_paint` and diff --git a/docs/modernization/debt.md b/docs/modernization/debt.md index 7fc5f24..04b02a0 100644 --- a/docs/modernization/debt.md +++ b/docs/modernization/debt.md @@ -242,6 +242,13 @@ agent or engineer to remove them without reconstructing context from chat. `plan_asset_file_load` wrapper still performs the retained `stat` probe for mtime platforms until asset/file watching is owned by injected storage services. +- 2026-06-05: DEBT-0056 was narrowed. `src/asset.h` no longer exposes Android + SDK types or forward declarations; retained Android asset-manager and asset + handles are stored as opaque pointers and cast only inside `src/asset.cpp`, + where the concrete `` dependency remains. The + legacy Android `asset.cpp` object compiled under the old Android CMake path; + the full legacy `native-lib` target still fails later on unrelated + pre-modernization C++ standard/header issues. - 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 @@ -311,7 +318,7 @@ agent or engineer to remove them without reconstructing context from chat. | 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`; platform-family reload behavior lives in tested `pp_platform_api::platform_policy` and pure probed planning, but the live wrapper still performs direct `stat` probing for Windows/macOS mtime reload checks until platform storage/file-watch services exist | 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-0056 | Open | Modernization | `src/asset.h` is now Android-SDK-free and uses opaque Android asset handles behind `Asset::set_android_asset_manager`, but retained `Asset` still owns a static Android asset-manager bridge 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`, and the old Android `native-lib` target still has unrelated C++ standard/header modernization failures | Reduce legacy asset I/O header coupling without rewriting Android asset loading before the asset manager/storage boundary exists | Windows app build; `powershell -ExecutionPolicy Bypass -File scripts\automation\platform-build.ps1 -Presets android-arm64 -Targets pp_assets`; legacy Android `CMakeFiles/native-lib.dir/.../src/asset.cpp.o` object compile | 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`; 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 | diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 628b0f7..fa886d5 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -762,11 +762,12 @@ The central `App` header now forward-declares retained platform handles instead of including Objective-C, Android, or GLFW SDK headers; the full platform headers live in the legacy platform adapter until those handles move out of `App` during Phase 6. -The retained `Asset` header now forward-declares Android asset-manager types, -hides the Android asset handles behind `Asset::set_android_asset_manager`, and -keeps concrete Android asset-manager headers in `asset.cpp`/the Android -entrypoint. This reduces legacy asset I/O header coupling while the actual -Android asset-reader implementation remains inside `pp_legacy_assets_io`. +The retained `Asset` header is now Android-SDK-free, hides the Android asset +handles behind opaque pointers and `Asset::set_android_asset_manager`, and keeps +concrete Android asset-manager headers in `asset.cpp`/the Android entrypoint. +This reduces legacy asset I/O header coupling while the static manager bridge +and actual Android asset-reader implementation remain inside retained legacy +asset I/O. Default canvas allocation size now dispatches through `PlatformServices`, so `NodeCanvas` and command-line conversion creation paths preserve the desktop 1536 and WebGL 512 defaults without carrying the old `CANVAS_RES` platform diff --git a/src/asset.cpp b/src/asset.cpp index bac0d88..580cceb 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -11,12 +11,21 @@ #ifdef __ANDROID__ #include #include -AAssetManager* Asset::m_am; +void* Asset::m_android_asset_manager; bool android_create_dir(const std::string& path); -void Asset::set_android_asset_manager(AAssetManager* asset_manager) +namespace { + +[[nodiscard]] AAsset* android_asset_handle(void* asset) { - m_am = asset_manager; + return static_cast(asset); +} + +} + +void Asset::set_android_asset_manager(void* asset_manager) +{ + m_android_asset_manager = asset_manager; } #endif @@ -72,7 +81,7 @@ std::vector Asset::list_files(std::string folder, const std::string #elif __ANDROID__ if (is_asset) { - AAssetDir* dir = AAssetManager_openDir(Asset::m_am, folder.c_str()); + AAssetDir* dir = AAssetManager_openDir(static_cast(Asset::m_android_asset_manager), folder.c_str()); while (const char* name = AAssetDir_getNextFileName(dir)) { //LOG("asset: %s", name); @@ -243,7 +252,10 @@ bool Asset::open(const char* path) #ifdef __ANDROID__ if (is_asset(path)) { - if (!(m_asset = AAssetManager_open(m_am, path, AASSET_MODE_RANDOM))) + if (!(m_android_asset = AAssetManager_open( + static_cast(m_android_asset_manager), + path, + AASSET_MODE_RANDOM))) { LOG("AAssetManager_open failed %s", path); return false; @@ -289,8 +301,8 @@ glm::uint8_t* Asset::read_all() { if (is_asset(m_current_path)) { - m_len = (int)AAsset_getLength(m_asset); - m_data = (uint8_t*)AAsset_getBuffer(m_asset); + m_len = (int)AAsset_getLength(android_asset_handle(m_android_asset)); + m_data = (uint8_t*)AAsset_getBuffer(android_asset_handle(m_android_asset)); } else { @@ -322,9 +334,9 @@ glm::uint8_t* Asset::read_all() void Asset::close() { #ifdef __ANDROID__ - if (m_asset) - AAsset_close(m_asset); - m_asset = nullptr; + if (m_android_asset) + AAsset_close(android_asset_handle(m_android_asset)); + m_android_asset = nullptr; #else if (m_fp) fclose(m_fp); diff --git a/src/asset.h b/src/asset.h index b1c8a60..8e30c73 100644 --- a/src/asset.h +++ b/src/asset.h @@ -1,19 +1,14 @@ #pragma once -#ifdef __ANDROID__ -struct AAsset; -struct AAssetManager; -#endif - class Asset { public: #ifdef __ANDROID__ - static void set_android_asset_manager(AAssetManager* asset_manager); + static void set_android_asset_manager(void* asset_manager); private: - static AAssetManager* m_am; - AAsset* m_asset = nullptr; + static void* m_android_asset_manager; + void* m_android_asset = nullptr; public: #endif