diff --git a/PanoPainter-OSX/main.cpp b/PanoPainter-OSX/main.cpp index 9cac041f..23ebcce3 100644 --- a/PanoPainter-OSX/main.cpp +++ b/PanoPainter-OSX/main.cpp @@ -7,7 +7,7 @@ #include "app.h" #include "keymap.h" #include "main.h" -#include "platform_legacy/legacy_platform_state.h" +#include "platform_apple/apple_platform_services.h" #include "settings.h" #include #include @@ -534,7 +534,7 @@ NSString* keyCodeToString(NSUInteger keyCode, NSUInteger mods) view = [[View alloc] initWithFrame:r]; controller = [[Controller alloc] initWithWindow:window]; - pp::platform::legacy::set_legacy_apple_state(view, nullptr); + pp::platform::apple::set_legacy_apple_state(view, nullptr); float z = (float)window.backingScaleFactor; App::I->zoom = Settings::value_or("ui-scale", (z > 0.f) ? z : 1.f); @@ -633,7 +633,7 @@ int main(int argc, const char * argv[]) return 0; AppOSX* app = [AppOSX sharedApplication]; - pp::platform::legacy::set_legacy_apple_state(nullptr, app); + pp::platform::apple::set_legacy_apple_state(nullptr, app); [app run]; return 0; diff --git a/PanoPainter/GameViewController.m b/PanoPainter/GameViewController.m index 75d8442a..4c68a5c3 100644 --- a/PanoPainter/GameViewController.m +++ b/PanoPainter/GameViewController.m @@ -10,7 +10,7 @@ #import "GameViewController.h" #import #include "app.h" -#include "platform_legacy/legacy_platform_state.h" +#include "platform_apple/apple_platform_services.h" #include "settings.h" #import "objc_utils.h" #import @@ -577,7 +577,7 @@ bool is_tap = true; [super viewDidLoad]; input_enabled = NO; App::I = new App; - pp::platform::legacy::set_legacy_apple_state( + pp::platform::apple::set_legacy_apple_state( self, (AppDelegate*)[[UIApplication sharedApplication] delegate]); App::I->initLog(); diff --git a/cmake/PanoPainterSources.cmake b/cmake/PanoPainterSources.cmake index 9f4f5d37..c3c7dbc1 100644 --- a/cmake/PanoPainterSources.cmake +++ b/cmake/PanoPainterSources.cmake @@ -118,6 +118,7 @@ set(PP_PLATFORM_LINUX_SOURCES ) set(PP_PLATFORM_APPLE_SOURCES + src/platform_apple/apple_platform_state.cpp src/platform_apple/apple_platform_services.cpp src/platform_apple/apple_platform_services.h ) diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index c70b069b..5f03371c 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -92,6 +92,16 @@ Current hotspot files: Latest slice: +- The retained Apple document bridge/state pocket no longer lives in + `src/platform_legacy/legacy_platform_state.*`; it now lives in the Apple-owned + `src/platform_apple/apple_platform_state.cpp` plus + `src/platform_apple/apple_platform_services.*`, and the macOS/iOS entrypoints + now seed that state through `pp::platform::apple::set_legacy_apple_state(...)` + instead of the legacy namespace. +- `src/platform_legacy/legacy_platform_services.cpp` now consumes the + Apple-owned retained provider through `pp::platform::apple::...` call-throughs + instead of constructing or caching Apple retained bridge state inside the + legacy platform layer. - The Win32 stylus and pointer-input path no longer reaches `WacomTablet::I` directly inside `src/platform_windows/windows_window_shell.cpp` or diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index ecb234d3..cd225415 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -47,6 +47,10 @@ Completed, blocked, and superseded task history moved to reporting now uses an injected callback, but retained Apple bridging and broader platform-to-app singleton reach are still open in `platform_legacy` + - Apple retained bridge/state ownership now lives in + `src/platform_apple/apple_platform_state.cpp` and + `src/platform_apple/apple_platform_services.*`, but the legacy platform + facade still routes a broad Apple service surface instead of disappearing - `platform_legacy` is still part of the live app shell - The app runtime boundary is not finished: - render/UI queues are static `App` state @@ -1205,6 +1209,15 @@ Why now: platform-handle state on `App`, which blocks a real `pp_platform_*` shell split. Current slice: +- The retained Apple document bridge/state pocket no longer lives in + `src/platform_legacy/legacy_platform_state.*`; it now lives in the + Apple-owned `src/platform_apple/apple_platform_state.cpp` and + `src/platform_apple/apple_platform_services.*`, and the macOS/iOS + entrypoints now seed that state through `pp::platform::apple`. +- `src/platform_legacy/legacy_platform_services.cpp` now consumes the + Apple-owned retained provider/factory through `pp::platform::apple::...` + call-throughs instead of constructing or caching Apple retained bridge + state in the legacy layer. - The Win32 stylus and pointer-input path no longer reaches `WacomTablet::I` directly in `src/platform_windows/windows_window_shell.cpp` or diff --git a/src/platform_apple/apple_platform_services.cpp b/src/platform_apple/apple_platform_services.cpp index 2a709360..2e55f5b0 100644 --- a/src/platform_apple/apple_platform_services.cpp +++ b/src/platform_apple/apple_platform_services.cpp @@ -7,6 +7,7 @@ #include namespace pp::platform::apple { + namespace { [[nodiscard]] std::vector apple_image_file_types() diff --git a/src/platform_apple/apple_platform_services.h b/src/platform_apple/apple_platform_services.h index 8df0dc42..af41c945 100644 --- a/src/platform_apple/apple_platform_services.h +++ b/src/platform_apple/apple_platform_services.h @@ -8,8 +8,28 @@ #include #include +#if defined(__OBJC__) && defined(__IOS__) +@class GameViewController; +@class AppDelegate; +#endif + +#if defined(__OBJC__) && defined(__OSX__) +@class View; +@class AppOSX; +#endif + namespace pp::platform::apple { +struct RetainedLegacyAppleState final { +#if defined(__OBJC__) && defined(__IOS__) + GameViewController* ios_view = nullptr; + AppDelegate* ios_app = nullptr; +#elif defined(__OBJC__) && defined(__OSX__) + View* osx_view = nullptr; + AppOSX* osx_app = nullptr; +#endif +}; + struct AppleDocumentPickerBridge { std::function pick_image; std::function file_types, PickedPathCallback callback)> pick_file; @@ -74,4 +94,19 @@ private: AppleDocumentPickerBridge bridge_; }; +[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state(); +[[nodiscard]] AppleDocumentPlatformServices& +active_legacy_apple_document_platform_services(); +[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths(); +void set_legacy_apple_state( +#if defined(__OBJC__) && defined(__IOS__) + GameViewController* ios_view, + AppDelegate* ios_app +#elif defined(__OBJC__) && defined(__OSX__) + View* osx_view, + AppOSX* osx_app +#endif +); +[[nodiscard]] pp::platform::PlatformFamily legacy_apple_platform_family(); + } diff --git a/src/platform_apple/apple_platform_state.cpp b/src/platform_apple/apple_platform_state.cpp new file mode 100644 index 00000000..d1e44917 --- /dev/null +++ b/src/platform_apple/apple_platform_state.cpp @@ -0,0 +1,267 @@ +#include "platform_apple/apple_platform_services.h" +#include "platform_legacy/legacy_platform_state.h" + +#include + +#if defined(__APPLE__) +#include +#include "objc_utils.h" +#endif + +namespace pp::platform::apple { +namespace { + +#if defined(__IOS__) || defined(__OSX__) +struct RetainedLegacyAppleDocumentPlatformState final { + std::unique_ptr services; +}; + +[[nodiscard]] NSMutableArray* apple_file_types_array(const std::vector& file_types) +{ + NSMutableArray* types = [NSMutableArray arrayWithCapacity:file_types.size()]; + for (const auto& type : file_types) + { + [types addObject:[NSString stringWithCString:type.c_str() encoding:NSUTF8StringEncoding]]; + } + return types; +} + +[[nodiscard]] RetainedLegacyAppleDocumentPlatformState& retained_legacy_apple_document_platform_state() +{ + static RetainedLegacyAppleDocumentPlatformState state; + return state; +} + +#ifdef __IOS__ +[[nodiscard]] AppleDocumentPickerBridge make_legacy_apple_document_picker_bridge() +{ + const auto& apple_state = active_legacy_apple_state(); + auto* const ios_view = apple_state.ios_view; + auto* const ios_app = apple_state.ios_app; + + AppleDocumentPickerBridge bridge; + bridge.clipboard_text = [ios_view] { + return [ios_view clipboard_get_string]; + }; + bridge.set_clipboard_text = [ios_view](std::string_view text) { + const std::string value(text); + return [ios_view clipboard_set_string:value]; + }; + bridge.set_virtual_keyboard_visible = [ios_view](bool visible) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (visible) + [ios_view show_keyboard]; + else + [ios_view hide_keyboard]; + }); + }; + bridge.trigger_crash_test = [ios_view] { + [ios_view crash]; + }; + bridge.start_sonarpen = [ios_app] { + [ios_app sonarpen_start]; + }; + bridge.acquire_render_context = [ios_view] { + [ios_view async_lock]; + }; + bridge.release_render_context = [ios_view] { + [ios_view async_unlock]; + }; + bridge.present_render_context = [ios_view] { + [ios_view async_swap]; + }; + bridge.bind_main_render_target = [ios_view] { + [ios_view->glview bindDrawable]; + }; + bridge.display_file = [ios_view](std::string path) { + dispatch_async(dispatch_get_main_queue(), ^{ + [ios_view display_file:path]; + }); + }; + bridge.share_file = [ios_view](std::string path) { + dispatch_async(dispatch_get_main_queue(), ^{ + [ios_view share_file:[NSString stringWithUTF8String:path.c_str()]]; + }); + }; + bridge.pick_image = [ios_view](PickedPathCallback callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + [ios_view pick_photo:callback]; + }); + }; + bridge.pick_file = [ios_view]( + std::vector file_types, + PickedPathCallback callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + [ios_view pick_file:apple_file_types_array(file_types) then:callback]; + }); + }; + bridge.save_prepared_file = [ios_view]( + std::string path, + std::string suggested_name, + PreparedFileCallback callback) { + (void)suggested_name; + dispatch_async(dispatch_get_main_queue(), ^{ + [ios_view pick_file_save:path]; + }); + callback(path, true); + }; + return bridge; +} +#elif defined(__OSX__) +[[nodiscard]] AppleDocumentPickerBridge make_legacy_apple_document_picker_bridge() +{ + const auto& apple_state = active_legacy_apple_state(); + auto* const osx_view = apple_state.osx_view; + auto* const osx_app = apple_state.osx_app; + + AppleDocumentPickerBridge bridge; + bridge.clipboard_text = [osx_view] { + return [osx_view clipboard_get_string]; + }; + bridge.set_clipboard_text = [osx_view](std::string_view text) { + const std::string value(text); + return [osx_view clipboard_set_string:value]; + }; + bridge.share_file = [osx_view](std::string path) { + dispatch_async(dispatch_get_main_queue(), ^{ + [osx_view share_file:[NSString stringWithUTF8String:path.c_str()]]; + }); + }; + bridge.trigger_crash_test = [osx_view] { + [osx_view hockeyapp_crash]; + }; + bridge.request_app_close = [osx_view] { + dispatch_async(dispatch_get_main_queue(), ^{ + [osx_view close]; + }); + }; + bridge.acquire_render_context = [osx_view] { + [osx_view async_lock]; + }; + bridge.release_render_context = [osx_view] { + [osx_view async_unlock]; + }; + bridge.present_render_context = [osx_view] { + [osx_view async_swap]; + }; + bridge.set_cursor_visible = [osx_view](bool visible) { + [osx_view show_cursor:visible]; + }; + bridge.save_ui_state = [osx_app] { + [osx_app save_ui_state]; + }; + bridge.pick_file = [osx_view]( + std::vector file_types, + PickedPathCallback callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + const std::string path = [osx_view pick_file:apple_file_types_array(file_types)]; + callback(path); + }); + }; + bridge.pick_save_file = [osx_view]( + std::vector file_types, + PickedPathCallback callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + const std::string path = [osx_view pick_file_save:apple_file_types_array(file_types)]; + callback(path); + }); + }; + bridge.pick_directory = [osx_view](PickedPathCallback callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + const std::string path = [osx_view pick_dir]; + callback(path); + }); + }; + bridge.format_working_directory_path = [](std::string_view path) { + char path_buffer[4096] = {}; + if (realpath(std::string(path).c_str(), path_buffer)) + return std::string(path_buffer); + return std::string(path); + }; + return bridge; +} +#endif +#endif + +} + +#if defined(__IOS__) || defined(__OSX__) +[[nodiscard]] PlatformFamily legacy_apple_platform_family() +{ +#ifdef __IOS__ + return PlatformFamily::ios; +#else + return PlatformFamily::macos; +#endif +} + +[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state() +{ + static RetainedLegacyAppleState state; + return state; +} + +[[nodiscard]] AppleDocumentPlatformServices& active_legacy_apple_document_platform_services() +{ + auto& retained = retained_legacy_apple_document_platform_state(); + if (!retained.services) + { + retained.services = std::make_unique( + legacy_apple_platform_family(), + make_legacy_apple_document_picker_bridge()); + } + return *retained.services; +} + +[[nodiscard]] PlatformStoragePaths prepare_legacy_apple_storage_paths() +{ + const auto& apple_state = active_legacy_apple_state(); +#ifdef __IOS__ + [apple_state.ios_view init_dirs]; +#elif defined(__OSX__) + [apple_state.osx_app init_dirs]; +#endif + return pp::platform::legacy::active_legacy_storage_paths(); +} + +void set_legacy_apple_state( +#ifdef __IOS__ + GameViewController* ios_view, + AppDelegate* ios_app +#elif defined(__OSX__) + View* osx_view, + AppOSX* osx_app +#endif +) +{ + auto& retained = active_legacy_apple_state(); + bool changed = false; +#ifdef __IOS__ + if (ios_view) + { + changed = changed || retained.ios_view != ios_view; + retained.ios_view = ios_view; + } + if (ios_app) + { + changed = changed || retained.ios_app != ios_app; + retained.ios_app = ios_app; + } +#elif defined(__OSX__) + if (osx_view) + { + changed = changed || retained.osx_view != osx_view; + retained.osx_view = osx_view; + } + if (osx_app) + { + changed = changed || retained.osx_app != osx_app; + retained.osx_app = osx_app; + } +#endif + if (changed) + retained_legacy_apple_document_platform_state().services.reset(); +} +#endif + +} diff --git a/src/platform_legacy/legacy_platform_services.cpp b/src/platform_legacy/legacy_platform_services.cpp index 18a67c4d..0e7a67f9 100644 --- a/src/platform_legacy/legacy_platform_services.cpp +++ b/src/platform_legacy/legacy_platform_services.cpp @@ -49,9 +49,9 @@ public: [[nodiscard]] pp::platform::PlatformStoragePaths prepare_storage_paths() override { #if defined(__IOS__) - return pp::platform::legacy::prepare_legacy_apple_storage_paths(); + return pp::platform::apple::prepare_legacy_apple_storage_paths(); #elif defined(__OSX__) - return pp::platform::legacy::prepare_legacy_apple_storage_paths(); + return pp::platform::apple::prepare_legacy_apple_storage_paths(); #elif __LINUX__ const std::string data_path = linux_home_path() + "/PanoPainter"; mkpath(data_path + "/brushes"); @@ -97,9 +97,9 @@ public: void trigger_crash_test() override { #ifdef __IOS__ - pp::platform::legacy::active_legacy_apple_document_platform_services().trigger_crash_test(); + pp::platform::apple::active_legacy_apple_document_platform_services().trigger_crash_test(); #elif __OSX__ - pp::platform::legacy::active_legacy_apple_document_platform_services().trigger_crash_test(); + pp::platform::apple::active_legacy_apple_document_platform_services().trigger_crash_test(); #elif defined(__ANDROID__) int *x = nullptr; *x = 42; LOG("%d", *x); @@ -111,7 +111,7 @@ public: #if defined(__IOS__) || defined(__OSX__) const auto family = pp::platform::current_platform_family(); if (family == pp::platform::PlatformFamily::ios || family == pp::platform::PlatformFamily::macos) - return pp::platform::legacy::active_legacy_apple_document_platform_services().clipboard_text(); + return pp::platform::apple::active_legacy_apple_document_platform_services().clipboard_text(); #endif #ifdef __ANDROID__ return android_get_clipboard(); @@ -125,7 +125,7 @@ public: #if defined(__IOS__) || defined(__OSX__) const auto family = pp::platform::current_platform_family(); if (family == pp::platform::PlatformFamily::ios || family == pp::platform::PlatformFamily::macos) - return pp::platform::legacy::active_legacy_apple_document_platform_services().set_clipboard_text(text); + return pp::platform::apple::active_legacy_apple_document_platform_services().set_clipboard_text(text); #endif const std::string value(text); #ifdef __ANDROID__ @@ -139,7 +139,7 @@ public: void set_cursor_visible(bool visible) override { #if defined(__IOS__) || defined(__OSX__) - pp::platform::legacy::active_legacy_apple_document_platform_services().set_cursor_visible(visible); + pp::platform::apple::active_legacy_apple_document_platform_services().set_cursor_visible(visible); #else (void)visible; #endif @@ -148,7 +148,7 @@ public: void set_virtual_keyboard_visible(bool visible) override { #ifdef __IOS__ - pp::platform::legacy::active_legacy_apple_document_platform_services().set_virtual_keyboard_visible(visible); + pp::platform::apple::active_legacy_apple_document_platform_services().set_virtual_keyboard_visible(visible); #elif __ANDROID__ displayKeyboard(visible); #else @@ -173,7 +173,7 @@ public: void acquire_render_context() override { #if defined(__IOS__) || defined(__OSX__) - pp::platform::legacy::active_legacy_apple_document_platform_services().acquire_render_context(); + pp::platform::apple::active_legacy_apple_document_platform_services().acquire_render_context(); #elif __ANDROID__ android_async_lock(); #elif __LINUX__ || __WEB__ @@ -184,7 +184,7 @@ public: void release_render_context() override { #if defined(__IOS__) || defined(__OSX__) - pp::platform::legacy::active_legacy_apple_document_platform_services().release_render_context(); + pp::platform::apple::active_legacy_apple_document_platform_services().release_render_context(); #elif __ANDROID__ android_async_unlock(); #endif @@ -193,7 +193,7 @@ public: void present_render_context() override { #if defined(__IOS__) || defined(__OSX__) - pp::platform::legacy::active_legacy_apple_document_platform_services().present_render_context(); + pp::platform::apple::active_legacy_apple_document_platform_services().present_render_context(); #elif __ANDROID__ android_async_swap(); #elif __LINUX__ || __WEB__ @@ -211,7 +211,7 @@ public: void bind_main_render_target() override { #if __IOS__ - pp::platform::legacy::active_legacy_apple_document_platform_services().bind_main_render_target(); + pp::platform::apple::active_legacy_apple_document_platform_services().bind_main_render_target(); #else bind_default_render_target(); #endif @@ -293,7 +293,7 @@ public: std::string_view data_path) override { #if defined(__IOS__) || defined(__OSX__) - return pp::platform::legacy::active_legacy_apple_document_platform_services().document_browse_roots(work_path, data_path); + return pp::platform::apple::active_legacy_apple_document_platform_services().document_browse_roots(work_path, data_path); #else return pp::platform::platform_document_browse_roots( pp::platform::current_platform_family(), @@ -307,7 +307,7 @@ public: if (!pp::platform::platform_saves_native_ui_state(pp::platform::current_platform_family())) return; #if defined(__IOS__) || defined(__OSX__) - pp::platform::legacy::active_legacy_apple_document_platform_services().save_ui_state(); + pp::platform::apple::active_legacy_apple_document_platform_services().save_ui_state(); #endif } @@ -334,9 +334,9 @@ public: void pick_image(pp::platform::PickedPathCallback callback) override { #ifdef __IOS__ - pp::platform::legacy::active_legacy_apple_document_platform_services().pick_image(std::move(callback)); + pp::platform::apple::active_legacy_apple_document_platform_services().pick_image(std::move(callback)); #elif __OSX__ - pp::platform::legacy::active_legacy_apple_document_platform_services().pick_image(std::move(callback)); + pp::platform::apple::active_legacy_apple_document_platform_services().pick_image(std::move(callback)); #elif __ANDROID__ android_pick_file(callback); #elif __LINUX__ @@ -352,9 +352,9 @@ public: void pick_file(std::vector file_types, pp::platform::PickedPathCallback callback) override { #ifdef __IOS__ - pp::platform::legacy::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback)); + pp::platform::apple::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback)); #elif __OSX__ - pp::platform::legacy::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback)); + pp::platform::apple::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback)); #elif __ANDROID__ android_pick_file(callback); #elif __LINUX__ @@ -371,7 +371,7 @@ public: void pick_save_file(std::vector file_types, pp::platform::PickedPathCallback callback) override { #if __OSX__ - pp::platform::legacy::active_legacy_apple_document_platform_services().pick_save_file(std::move(file_types), std::move(callback)); + pp::platform::apple::active_legacy_apple_document_platform_services().pick_save_file(std::move(file_types), std::move(callback)); #elif __ANDROID__ android_pick_file_save(callback); #else @@ -385,7 +385,7 @@ public: #ifdef __IOS__ (void)callback; #elif __OSX__ - pp::platform::legacy::active_legacy_apple_document_platform_services().pick_directory(std::move(callback)); + pp::platform::apple::active_legacy_apple_document_platform_services().pick_directory(std::move(callback)); #elif __ANDROID__ (void)callback; #else @@ -396,7 +396,7 @@ public: [[nodiscard]] bool supports_working_directory_picker() override { #if defined(__IOS__) || defined(__OSX__) - return pp::platform::legacy::active_legacy_apple_document_platform_services().supports_working_directory_picker(); + return pp::platform::apple::active_legacy_apple_document_platform_services().supports_working_directory_picker(); #else return pp::platform::platform_supports_working_directory_picker( pp::platform::current_platform_family()); @@ -406,7 +406,7 @@ public: [[nodiscard]] std::string format_working_directory_path(std::string_view path) override { #if defined(__IOS__) || defined(__OSX__) - return pp::platform::legacy::active_legacy_apple_document_platform_services().format_working_directory_path(path); + return pp::platform::apple::active_legacy_apple_document_platform_services().format_working_directory_path(path); #endif return std::string(path); } @@ -442,7 +442,7 @@ public: void start_sonarpen() override { #if __IOS__ - pp::platform::legacy::active_legacy_apple_document_platform_services().start_sonarpen(); + pp::platform::apple::active_legacy_apple_document_platform_services().start_sonarpen(); #endif } @@ -488,7 +488,7 @@ public: void display_file(std::string_view path) override { #if defined(__IOS__) || defined(__OSX__) - pp::platform::legacy::active_legacy_apple_document_platform_services().display_file(path); + pp::platform::apple::active_legacy_apple_document_platform_services().display_file(path); #else (void)path; #endif @@ -497,7 +497,7 @@ public: void share_file(std::string_view path) override { #if defined(__IOS__) || defined(__OSX__) - pp::platform::legacy::active_legacy_apple_document_platform_services().share_file(path); + pp::platform::apple::active_legacy_apple_document_platform_services().share_file(path); #else (void)path; #endif @@ -506,7 +506,7 @@ public: void request_app_close() override { #ifdef __OSX__ - pp::platform::legacy::active_legacy_apple_document_platform_services().request_app_close(); + pp::platform::apple::active_legacy_apple_document_platform_services().request_app_close(); #elif __LINUX__ pp::platform::legacy::active_legacy_glfw_window_hooks().request_app_close(); #endif @@ -539,7 +539,7 @@ public: const std::string value(path); const std::string name(suggested_name); #ifdef __IOS__ - pp::platform::legacy::active_legacy_apple_document_platform_services().save_prepared_file( + pp::platform::apple::active_legacy_apple_document_platform_services().save_prepared_file( value, name, std::move(callback)); @@ -559,5 +559,4 @@ PlatformServices& platform_services() static LegacyPlatformServices services; return services; } - } diff --git a/src/platform_legacy/legacy_platform_state.cpp b/src/platform_legacy/legacy_platform_state.cpp index 58a10949..24e35516 100644 --- a/src/platform_legacy/legacy_platform_state.cpp +++ b/src/platform_legacy/legacy_platform_state.cpp @@ -1,10 +1,6 @@ #include "pch.h" #include "platform_legacy/legacy_platform_state.h" - -#if defined(__APPLE__) -#include -#include "objc_utils.h" -#endif +#include "platform_api/platform_policy.h" #if defined(__LINUX__) || defined(__WEB__) #include @@ -29,187 +25,6 @@ struct RetainedLegacyStoragePaths final { return state; } -#if defined(__IOS__) || defined(__OSX__) -struct RetainedLegacyAppleDocumentPlatformState final { - std::unique_ptr services; -}; - -[[nodiscard]] NSMutableArray* apple_file_types_array(const std::vector& file_types) -{ - NSMutableArray* types = [NSMutableArray arrayWithCapacity:file_types.size()]; - for (const auto& type : file_types) - { - [types addObject:[NSString stringWithCString:type.c_str() encoding:NSUTF8StringEncoding]]; - } - return types; -} - -[[nodiscard]] RetainedLegacyAppleDocumentPlatformState& retained_legacy_apple_document_platform_state() -{ - static RetainedLegacyAppleDocumentPlatformState state; - return state; -} - -#ifdef __IOS__ -[[nodiscard]] pp::platform::apple::AppleDocumentPickerBridge make_legacy_apple_document_picker_bridge() -{ - const auto& apple_state = active_legacy_apple_state(); - auto* const ios_view = apple_state.ios_view; - auto* const ios_app = apple_state.ios_app; - - pp::platform::apple::AppleDocumentPickerBridge bridge; - bridge.clipboard_text = [ios_view] { - return [ios_view clipboard_get_string]; - }; - bridge.set_clipboard_text = [ios_view](std::string_view text) { - const std::string value(text); - return [ios_view clipboard_set_string:value]; - }; - bridge.set_virtual_keyboard_visible = [ios_view](bool visible) { - dispatch_async(dispatch_get_main_queue(), ^{ - if (visible) - [ios_view show_keyboard]; - else - [ios_view hide_keyboard]; - }); - }; - bridge.trigger_crash_test = [ios_view] { - [ios_view crash]; - }; - bridge.start_sonarpen = [ios_app] { - [ios_app sonarpen_start]; - }; - bridge.acquire_render_context = [ios_view] { - [ios_view async_lock]; - }; - bridge.release_render_context = [ios_view] { - [ios_view async_unlock]; - }; - bridge.present_render_context = [ios_view] { - [ios_view async_swap]; - }; - bridge.bind_main_render_target = [ios_view] { - [ios_view->glview bindDrawable]; - }; - bridge.display_file = [ios_view](std::string path) { - dispatch_async(dispatch_get_main_queue(), ^{ - [ios_view display_file:path]; - }); - }; - bridge.share_file = [ios_view](std::string path) { - dispatch_async(dispatch_get_main_queue(), ^{ - [ios_view share_file:[NSString stringWithUTF8String:path.c_str()]]; - }); - }; - bridge.pick_image = [ios_view](pp::platform::PickedPathCallback callback) { - dispatch_async(dispatch_get_main_queue(), ^{ - [ios_view pick_photo:callback]; - }); - }; - bridge.pick_file = [ios_view]( - std::vector file_types, - pp::platform::PickedPathCallback callback) { - dispatch_async(dispatch_get_main_queue(), ^{ - [ios_view pick_file:apple_file_types_array(file_types) then:callback]; - }); - }; - bridge.save_prepared_file = [ios_view]( - std::string path, - std::string suggested_name, - pp::platform::PreparedFileCallback callback) { - (void)suggested_name; - dispatch_async(dispatch_get_main_queue(), ^{ - [ios_view pick_file_save:path]; - }); - callback(path, true); - }; - return bridge; -} -#elif defined(__OSX__) -[[nodiscard]] pp::platform::apple::AppleDocumentPickerBridge make_legacy_apple_document_picker_bridge() -{ - const auto& apple_state = active_legacy_apple_state(); - auto* const osx_view = apple_state.osx_view; - auto* const osx_app = apple_state.osx_app; - - pp::platform::apple::AppleDocumentPickerBridge bridge; - bridge.clipboard_text = [osx_view] { - return [osx_view clipboard_get_string]; - }; - bridge.set_clipboard_text = [osx_view](std::string_view text) { - const std::string value(text); - return [osx_view clipboard_set_string:value]; - }; - bridge.share_file = [osx_view](std::string path) { - dispatch_async(dispatch_get_main_queue(), ^{ - [osx_view share_file:[NSString stringWithUTF8String:path.c_str()]]; - }); - }; - bridge.trigger_crash_test = [osx_view] { - [osx_view hockeyapp_crash]; - }; - bridge.request_app_close = [osx_view] { - dispatch_async(dispatch_get_main_queue(), ^{ - [osx_view close]; - }); - }; - bridge.acquire_render_context = [osx_view] { - [osx_view async_lock]; - }; - bridge.release_render_context = [osx_view] { - [osx_view async_unlock]; - }; - bridge.present_render_context = [osx_view] { - [osx_view async_swap]; - }; - bridge.set_cursor_visible = [osx_view](bool visible) { - [osx_view show_cursor:visible]; - }; - bridge.save_ui_state = [osx_app] { - [osx_app save_ui_state]; - }; - bridge.pick_file = [osx_view]( - std::vector file_types, - pp::platform::PickedPathCallback callback) { - dispatch_async(dispatch_get_main_queue(), ^{ - const std::string path = [osx_view pick_file:apple_file_types_array(file_types)]; - callback(path); - }); - }; - bridge.pick_save_file = [osx_view]( - std::vector file_types, - pp::platform::PickedPathCallback callback) { - dispatch_async(dispatch_get_main_queue(), ^{ - const std::string path = [osx_view pick_file_save:apple_file_types_array(file_types)]; - callback(path); - }); - }; - bridge.pick_directory = [osx_view](pp::platform::PickedPathCallback callback) { - dispatch_async(dispatch_get_main_queue(), ^{ - const std::string path = [osx_view pick_dir]; - callback(path); - }); - }; - bridge.format_working_directory_path = [](std::string_view path) { - char path_buffer[4096] = {}; - if (realpath(std::string(path).c_str(), path_buffer)) - return std::string(path_buffer); - return std::string(path); - }; - return bridge; -} -#endif - -[[nodiscard]] pp::platform::PlatformFamily legacy_apple_platform_family() -{ -#ifdef __IOS__ - return pp::platform::PlatformFamily::ios; -#else - return pp::platform::PlatformFamily::macos; -#endif -} -#endif - class RetainedWebPlatformServices final : public pp::platform::WebPlatformServices { public: void publish_exported_image(std::string_view path) override @@ -277,77 +92,6 @@ void set_legacy_glfw_window(GLFWwindow* window) } #endif -#if defined(__IOS__) || defined(__OSX__) -[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state() -{ - static RetainedLegacyAppleState state; - return state; -} - -[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices& -active_legacy_apple_document_platform_services() -{ - auto& retained = retained_legacy_apple_document_platform_state(); - if (!retained.services) - { - retained.services = std::make_unique( - legacy_apple_platform_family(), - make_legacy_apple_document_picker_bridge()); - } - return *retained.services; -} - -[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths() -{ - const auto& apple_state = active_legacy_apple_state(); -#ifdef __IOS__ - [apple_state.ios_view init_dirs]; -#elif defined(__OSX__) - [apple_state.osx_app init_dirs]; -#endif - return active_legacy_storage_paths(); -} - -void set_legacy_apple_state( -#ifdef __IOS__ - GameViewController* ios_view, - AppDelegate* ios_app -#elif defined(__OSX__) - View* osx_view, - AppOSX* osx_app -#endif -) -{ - auto& retained = active_legacy_apple_state(); - bool changed = false; -#ifdef __IOS__ - if (ios_view) - { - changed = changed || retained.ios_view != ios_view; - retained.ios_view = ios_view; - } - if (ios_app) - { - changed = changed || retained.ios_app != ios_app; - retained.ios_app = ios_app; - } -#elif defined(__OSX__) - if (osx_view) - { - changed = changed || retained.osx_view != osx_view; - retained.osx_view = osx_view; - } - if (osx_app) - { - changed = changed || retained.osx_app != osx_app; - retained.osx_app = osx_app; - } -#endif - if (changed) - retained_legacy_apple_document_platform_state().services.reset(); -} -#endif - [[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services() { static RetainedWebPlatformServices services; diff --git a/src/platform_legacy/legacy_platform_state.h b/src/platform_legacy/legacy_platform_state.h index 65f25d0d..916e3bdb 100644 --- a/src/platform_legacy/legacy_platform_state.h +++ b/src/platform_legacy/legacy_platform_state.h @@ -1,22 +1,11 @@ #pragma once -#include "platform_apple/apple_platform_services.h" #include "platform_api/platform_services.h" #if __LINUX__ || __WEB__ struct GLFWwindow; #endif -#if defined(__OBJC__) && defined(__IOS__) -@class GameViewController; -@class AppDelegate; -#endif - -#if defined(__OBJC__) && defined(__OSX__) -@class View; -@class AppOSX; -#endif - namespace pp::platform::legacy { #if defined(__LINUX__) || defined(__WEB__) @@ -36,32 +25,6 @@ struct RetainedLegacyGlfwWindowState final { void set_legacy_glfw_window(GLFWwindow* window); #endif -#if defined(__IOS__) || defined(__OSX__) -struct RetainedLegacyAppleState final { -#ifdef __IOS__ - GameViewController* ios_view = nullptr; - AppDelegate* ios_app = nullptr; -#elif defined(__OSX__) - View* osx_view = nullptr; - AppOSX* osx_app = nullptr; -#endif -}; - -[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state(); -[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices& -active_legacy_apple_document_platform_services(); -[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths(); -void set_legacy_apple_state( -#ifdef __IOS__ - GameViewController* ios_view, - AppDelegate* ios_app -#elif defined(__OSX__) - View* osx_view, - AppOSX* osx_app -#endif -); -#endif - [[nodiscard]] pp::platform::WebPlatformServices& active_legacy_web_platform_services(); [[nodiscard]] const pp::platform::PlatformStoragePaths& active_legacy_storage_paths();