Retain Apple bridge services and bind Win32 runtime
This commit is contained in:
@@ -92,6 +92,17 @@ Current hotspot files:
|
||||
|
||||
Latest slice:
|
||||
|
||||
- The full retained Apple document bridge construction no longer lives inline
|
||||
in `src/platform_legacy/legacy_platform_services.cpp`; it now lives behind
|
||||
`active_legacy_apple_document_platform_services()` in
|
||||
`src/platform_legacy/legacy_platform_state.*`, and that retained service now
|
||||
resets when seeded Apple handles change so first-use bridge capture stays in
|
||||
sync with the active entrypoint state.
|
||||
- Win32 main-thread task dispatch no longer reaches `AppRuntime` through
|
||||
`App::I` inside `src/platform_windows/windows_platform_services.cpp`;
|
||||
`src/platform_windows/windows_runtime_shell.*` now binds the active runtime
|
||||
explicitly and clears that binding on shutdown, leaving the Windows queue
|
||||
helper as a thinner runtime forwarder.
|
||||
- `App` no longer owns `and_app` or `and_engine`; the retained Android
|
||||
entrypoint now seeds only the explicit legacy platform storage snapshot
|
||||
needed by touched platform services instead of storing Android-native
|
||||
@@ -227,7 +238,9 @@ Current architecture mismatches that must be treated as real blockers:
|
||||
`platform_legacy`-mirrored Apple/GLFW handle cluster is now seeded
|
||||
explicitly from platform entrypoints instead of being copied out of `App`,
|
||||
and retained storage roots are now also seeded explicitly instead of being
|
||||
lazily copied from `App::I` inside `active_legacy_storage_paths()`.
|
||||
lazily copied from `App::I` inside `active_legacy_storage_paths()`, while the
|
||||
retained Apple document bridge now also lives in `legacy_platform_state.*`
|
||||
instead of being built inline in `legacy_platform_services.cpp`.
|
||||
- `src/platform_legacy/legacy_platform_services.*` is still part of the live
|
||||
app shell.
|
||||
- `pp_panopainter_ui` still depends on `pp_legacy_app`.
|
||||
|
||||
@@ -1154,6 +1154,11 @@ Current slice:
|
||||
also live in `src/platform_legacy/legacy_platform_state.*`, and
|
||||
`src/platform_legacy/legacy_platform_services.cpp` now consumes those
|
||||
snapshots without direct `App::I` reads in the touched paths
|
||||
- the retained Apple document bridge now also lives behind
|
||||
`active_legacy_apple_document_platform_services()` in
|
||||
`src/platform_legacy/legacy_platform_state.*` instead of being built inline
|
||||
inside `src/platform_legacy/legacy_platform_services.cpp`, and that retained
|
||||
service resets when seeded Apple handles change
|
||||
- retained Apple callback injection and broader `platform_legacy` singleton
|
||||
reach are still open
|
||||
- the `platform_legacy`-mirrored Apple/GLFW handle cluster is now seeded
|
||||
@@ -1210,6 +1215,11 @@ Current slice:
|
||||
- `App` also no longer owns `and_app` or `and_engine`; the retained Android
|
||||
entrypoint now seeds only the explicit legacy platform storage snapshot
|
||||
needed by touched platform services.
|
||||
- Win32 main-thread task dispatch also no longer reaches `AppRuntime` through
|
||||
`App::I`; `src/platform_windows/windows_runtime_shell.*` now binds the
|
||||
active runtime explicitly and
|
||||
`src/platform_windows/windows_platform_services.cpp` consumes that bound
|
||||
runtime for enqueue/drain.
|
||||
- `App` still owns broader retained legacy platform state, so this remains a
|
||||
live ownership task.
|
||||
|
||||
|
||||
@@ -23,13 +23,6 @@ std::string android_get_clipboard();
|
||||
bool android_set_clipboard(const std::string& s);
|
||||
#elif __APPLE__
|
||||
#include <Foundation/Foundation.h>
|
||||
#include "objc_utils.h"
|
||||
#ifdef __IOS__
|
||||
#include "AppDelegate.h"
|
||||
#include "GameViewController.h"
|
||||
#elif defined(__OSX__)
|
||||
#include "main.h"
|
||||
#endif
|
||||
void delete_all_files_in_path(const std::string& source_path);
|
||||
#ifdef __IOS__
|
||||
void save_image_library(const std::string& path);
|
||||
@@ -93,16 +86,6 @@ public:
|
||||
}
|
||||
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
[[nodiscard]] NSMutableArray<NSString*>* apple_file_types_array(const std::vector<std::string>& file_types)
|
||||
{
|
||||
NSMutableArray<NSString*>* types = [NSMutableArray arrayWithCapacity:file_types.size()];
|
||||
for (const auto& type : file_types)
|
||||
{
|
||||
[types addObject:[NSString stringWithCString:type.c_str() encoding:NSUTF8StringEncoding]];
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
[[nodiscard]] pp::platform::PlatformStoragePaths prepare_legacy_apple_storage_paths()
|
||||
{
|
||||
const auto& apple_state = pp::platform::legacy::active_legacy_apple_state();
|
||||
@@ -113,161 +96,6 @@ public:
|
||||
#endif
|
||||
return pp::platform::legacy::active_legacy_storage_paths();
|
||||
}
|
||||
|
||||
[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices& active_apple_document_platform_services()
|
||||
{
|
||||
#ifdef __IOS__
|
||||
const auto& apple_state = pp::platform::legacy::active_legacy_apple_state();
|
||||
auto* const ios_view = apple_state.ios_view;
|
||||
auto* const ios_app = apple_state.ios_app;
|
||||
static pp::platform::apple::AppleDocumentPlatformServices services(
|
||||
pp::platform::PlatformFamily::ios,
|
||||
[ios_view] {
|
||||
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<std::string> 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;
|
||||
}());
|
||||
return services;
|
||||
#else
|
||||
const auto& apple_state = pp::platform::legacy::active_legacy_apple_state();
|
||||
auto* const osx_view = apple_state.osx_view;
|
||||
auto* const osx_app = apple_state.osx_app;
|
||||
static pp::platform::apple::AppleDocumentPlatformServices services(
|
||||
pp::platform::PlatformFamily::macos,
|
||||
[osx_view, 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<std::string> 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<std::string> 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;
|
||||
}());
|
||||
return services;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// DEBT-0017: fallback for platforms that do not inject PlatformServices yet.
|
||||
@@ -324,9 +152,9 @@ public:
|
||||
void trigger_crash_test() override
|
||||
{
|
||||
#ifdef __IOS__
|
||||
active_apple_document_platform_services().trigger_crash_test();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().trigger_crash_test();
|
||||
#elif __OSX__
|
||||
active_apple_document_platform_services().trigger_crash_test();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().trigger_crash_test();
|
||||
#elif defined(__ANDROID__)
|
||||
int *x = nullptr; *x = 42;
|
||||
LOG("%d", *x);
|
||||
@@ -338,7 +166,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 active_apple_document_platform_services().clipboard_text();
|
||||
return pp::platform::legacy::active_legacy_apple_document_platform_services().clipboard_text();
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
return android_get_clipboard();
|
||||
@@ -352,7 +180,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 active_apple_document_platform_services().set_clipboard_text(text);
|
||||
return pp::platform::legacy::active_legacy_apple_document_platform_services().set_clipboard_text(text);
|
||||
#endif
|
||||
const std::string value(text);
|
||||
#ifdef __ANDROID__
|
||||
@@ -366,7 +194,7 @@ public:
|
||||
void set_cursor_visible(bool visible) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().set_cursor_visible(visible);
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().set_cursor_visible(visible);
|
||||
#else
|
||||
(void)visible;
|
||||
#endif
|
||||
@@ -375,7 +203,7 @@ public:
|
||||
void set_virtual_keyboard_visible(bool visible) override
|
||||
{
|
||||
#ifdef __IOS__
|
||||
active_apple_document_platform_services().set_virtual_keyboard_visible(visible);
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().set_virtual_keyboard_visible(visible);
|
||||
#elif __ANDROID__
|
||||
displayKeyboard(visible);
|
||||
#else
|
||||
@@ -400,7 +228,7 @@ public:
|
||||
void acquire_render_context() override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().acquire_render_context();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().acquire_render_context();
|
||||
#elif __ANDROID__
|
||||
android_async_lock();
|
||||
#elif __LINUX__ || __WEB__
|
||||
@@ -411,7 +239,7 @@ public:
|
||||
void release_render_context() override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().release_render_context();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().release_render_context();
|
||||
#elif __ANDROID__
|
||||
android_async_unlock();
|
||||
#endif
|
||||
@@ -420,7 +248,7 @@ public:
|
||||
void present_render_context() override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().present_render_context();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().present_render_context();
|
||||
#elif __ANDROID__
|
||||
android_async_swap();
|
||||
#elif __LINUX__ || __WEB__
|
||||
@@ -438,7 +266,7 @@ public:
|
||||
void bind_main_render_target() override
|
||||
{
|
||||
#if __IOS__
|
||||
active_apple_document_platform_services().bind_main_render_target();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().bind_main_render_target();
|
||||
#else
|
||||
bind_default_render_target();
|
||||
#endif
|
||||
@@ -520,7 +348,7 @@ public:
|
||||
std::string_view data_path) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
return active_apple_document_platform_services().document_browse_roots(work_path, data_path);
|
||||
return pp::platform::legacy::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(),
|
||||
@@ -534,7 +362,7 @@ public:
|
||||
if (!pp::platform::platform_saves_native_ui_state(pp::platform::current_platform_family()))
|
||||
return;
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().save_ui_state();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().save_ui_state();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -561,9 +389,9 @@ public:
|
||||
void pick_image(pp::platform::PickedPathCallback callback) override
|
||||
{
|
||||
#ifdef __IOS__
|
||||
active_apple_document_platform_services().pick_image(std::move(callback));
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().pick_image(std::move(callback));
|
||||
#elif __OSX__
|
||||
active_apple_document_platform_services().pick_image(std::move(callback));
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().pick_image(std::move(callback));
|
||||
#elif __ANDROID__
|
||||
android_pick_file(callback);
|
||||
#elif __LINUX__
|
||||
@@ -579,9 +407,9 @@ public:
|
||||
void pick_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
|
||||
{
|
||||
#ifdef __IOS__
|
||||
active_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback));
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback));
|
||||
#elif __OSX__
|
||||
active_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback));
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().pick_file(std::move(file_types), std::move(callback));
|
||||
#elif __ANDROID__
|
||||
android_pick_file(callback);
|
||||
#elif __LINUX__
|
||||
@@ -598,7 +426,7 @@ public:
|
||||
void pick_save_file(std::vector<std::string> file_types, pp::platform::PickedPathCallback callback) override
|
||||
{
|
||||
#if __OSX__
|
||||
active_apple_document_platform_services().pick_save_file(std::move(file_types), std::move(callback));
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().pick_save_file(std::move(file_types), std::move(callback));
|
||||
#elif __ANDROID__
|
||||
android_pick_file_save(callback);
|
||||
#else
|
||||
@@ -612,7 +440,7 @@ public:
|
||||
#ifdef __IOS__
|
||||
(void)callback;
|
||||
#elif __OSX__
|
||||
active_apple_document_platform_services().pick_directory(std::move(callback));
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().pick_directory(std::move(callback));
|
||||
#elif __ANDROID__
|
||||
(void)callback;
|
||||
#else
|
||||
@@ -623,7 +451,7 @@ public:
|
||||
[[nodiscard]] bool supports_working_directory_picker() override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
return active_apple_document_platform_services().supports_working_directory_picker();
|
||||
return pp::platform::legacy::active_legacy_apple_document_platform_services().supports_working_directory_picker();
|
||||
#else
|
||||
return pp::platform::platform_supports_working_directory_picker(
|
||||
pp::platform::current_platform_family());
|
||||
@@ -633,7 +461,7 @@ public:
|
||||
[[nodiscard]] std::string format_working_directory_path(std::string_view path) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
return active_apple_document_platform_services().format_working_directory_path(path);
|
||||
return pp::platform::legacy::active_legacy_apple_document_platform_services().format_working_directory_path(path);
|
||||
#endif
|
||||
return std::string(path);
|
||||
}
|
||||
@@ -669,7 +497,7 @@ public:
|
||||
void start_sonarpen() override
|
||||
{
|
||||
#if __IOS__
|
||||
active_apple_document_platform_services().start_sonarpen();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().start_sonarpen();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -715,7 +543,7 @@ public:
|
||||
void display_file(std::string_view path) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().display_file(path);
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().display_file(path);
|
||||
#else
|
||||
(void)path;
|
||||
#endif
|
||||
@@ -724,7 +552,7 @@ public:
|
||||
void share_file(std::string_view path) override
|
||||
{
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
active_apple_document_platform_services().share_file(path);
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().share_file(path);
|
||||
#else
|
||||
(void)path;
|
||||
#endif
|
||||
@@ -733,7 +561,7 @@ public:
|
||||
void request_app_close() override
|
||||
{
|
||||
#ifdef __OSX__
|
||||
active_apple_document_platform_services().request_app_close();
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().request_app_close();
|
||||
#elif __LINUX__
|
||||
pp::platform::legacy::active_legacy_glfw_window_hooks().request_app_close();
|
||||
#endif
|
||||
@@ -766,7 +594,7 @@ public:
|
||||
const std::string value(path);
|
||||
const std::string name(suggested_name);
|
||||
#ifdef __IOS__
|
||||
active_apple_document_platform_services().save_prepared_file(
|
||||
pp::platform::legacy::active_legacy_apple_document_platform_services().save_prepared_file(
|
||||
value,
|
||||
name,
|
||||
std::move(callback));
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#include "pch.h"
|
||||
#include "platform_legacy/legacy_platform_state.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <Foundation/Foundation.h>
|
||||
#include "objc_utils.h"
|
||||
#endif
|
||||
|
||||
#if defined(__LINUX__) || defined(__WEB__)
|
||||
#include <GLFW/glfw3.h>
|
||||
#endif
|
||||
@@ -18,6 +23,187 @@ struct RetainedLegacyStoragePaths final {
|
||||
return state;
|
||||
}
|
||||
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
struct RetainedLegacyAppleDocumentPlatformState final {
|
||||
std::unique_ptr<pp::platform::apple::AppleDocumentPlatformServices> services;
|
||||
};
|
||||
|
||||
[[nodiscard]] NSMutableArray<NSString*>* apple_file_types_array(const std::vector<std::string>& file_types)
|
||||
{
|
||||
NSMutableArray<NSString*>* 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<std::string> 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<std::string> 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<std::string> 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
|
||||
|
||||
}
|
||||
|
||||
#if defined(__LINUX__) || defined(__WEB__)
|
||||
@@ -55,6 +241,19 @@ void set_legacy_glfw_window(GLFWwindow* window)
|
||||
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<pp::platform::apple::AppleDocumentPlatformServices>(
|
||||
legacy_apple_platform_family(),
|
||||
make_legacy_apple_document_picker_bridge());
|
||||
}
|
||||
return *retained.services;
|
||||
}
|
||||
|
||||
void set_legacy_apple_state(
|
||||
#ifdef __IOS__
|
||||
GameViewController* ios_view,
|
||||
@@ -66,17 +265,32 @@ void set_legacy_apple_state(
|
||||
)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "platform_apple/apple_platform_services.h"
|
||||
#include "platform_api/platform_services.h"
|
||||
|
||||
#if __LINUX__ || __WEB__
|
||||
@@ -47,6 +48,8 @@ struct RetainedLegacyAppleState final {
|
||||
};
|
||||
|
||||
[[nodiscard]] RetainedLegacyAppleState& active_legacy_apple_state();
|
||||
[[nodiscard]] pp::platform::apple::AppleDocumentPlatformServices&
|
||||
active_legacy_apple_document_platform_services();
|
||||
void set_legacy_apple_state(
|
||||
#ifdef __IOS__
|
||||
GameViewController* ios_view,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "app.h"
|
||||
#include "legacy_preference_storage.h"
|
||||
#include "platform_windows/windows_runtime_shell.h"
|
||||
#include "platform_windows/windows_stylus_input.h"
|
||||
|
||||
namespace pp::platform::windows {
|
||||
@@ -50,6 +51,7 @@ void handle_window_close_message(VrShellState& vr)
|
||||
App::I->runtime().ui_thread_stop();
|
||||
App::I->runtime().render_thread_stop();
|
||||
App::I->terminate();
|
||||
bind_runtime(nullptr);
|
||||
delete App::I;
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
#include "platform_windows/windows_bootstrap_helpers.h"
|
||||
#include "platform_windows/windows_lifecycle_shell.h"
|
||||
#include "platform_windows/windows_platform_services.h"
|
||||
#include "platform_windows/windows_runtime_shell.h"
|
||||
#include "platform_windows/windows_stylus_input.h"
|
||||
#include "platform_windows/windows_window_shell.h"
|
||||
|
||||
#include "app_runtime.h"
|
||||
#include "log.h"
|
||||
#include "legacy_gl_runtime_dispatch.h"
|
||||
#include "legacy_ui_gl_dispatch.h"
|
||||
@@ -171,18 +173,25 @@ void swap_async_render_context()
|
||||
|
||||
void enqueue_main_thread_task(std::packaged_task<void()> task)
|
||||
{
|
||||
if (!App::I)
|
||||
if (auto* runtime = bound_runtime())
|
||||
{
|
||||
task();
|
||||
runtime->main_thread_task(std::move(task));
|
||||
return;
|
||||
}
|
||||
App::I->runtime().main_thread_task(std::move(task));
|
||||
|
||||
if (!task.valid())
|
||||
return;
|
||||
|
||||
task();
|
||||
}
|
||||
|
||||
void drain_main_thread_tasks()
|
||||
{
|
||||
if (App::I)
|
||||
App::I->runtime().drain_main_thread_tasks();
|
||||
if (auto* runtime = bound_runtime())
|
||||
{
|
||||
runtime->drain_main_thread_tasks();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // namespace pp::platform::windows
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "platform_windows/windows_runtime_shell.h"
|
||||
|
||||
#include "app.h"
|
||||
#include "app_runtime.h"
|
||||
#include "log.h"
|
||||
#include "platform_windows/windows_bootstrap_helpers.h"
|
||||
#include "platform_windows/windows_lifecycle_shell.h"
|
||||
@@ -16,6 +17,16 @@ namespace pp::platform::windows {
|
||||
|
||||
namespace {
|
||||
|
||||
struct RetainedWindowsRuntimeState final {
|
||||
AppRuntime* runtime = nullptr;
|
||||
};
|
||||
|
||||
[[nodiscard]] RetainedWindowsRuntimeState& retained_runtime_state()
|
||||
{
|
||||
static RetainedWindowsRuntimeState state;
|
||||
return state;
|
||||
}
|
||||
|
||||
void register_touch_window(HWND hWnd)
|
||||
{
|
||||
// link: https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-registertouchwindow
|
||||
@@ -102,12 +113,23 @@ void shutdown_main_window_runtime(const MainWindowStartupState& startup, HINSTAN
|
||||
|
||||
}
|
||||
|
||||
void bind_runtime(AppRuntime* runtime) noexcept
|
||||
{
|
||||
retained_runtime_state().runtime = runtime;
|
||||
}
|
||||
|
||||
AppRuntime* bound_runtime() noexcept
|
||||
{
|
||||
return retained_runtime_state().runtime;
|
||||
}
|
||||
|
||||
int run_main_application(int argc, char** argv)
|
||||
{
|
||||
auto& state = retained_state();
|
||||
state.hInst = GetModuleHandle(NULL);
|
||||
|
||||
App::I = new App();
|
||||
bind_runtime(&App::I->runtime());
|
||||
App::I->set_platform_services(&pp::platform::windows::platform_services());
|
||||
App::I->initLog();
|
||||
|
||||
@@ -136,8 +158,10 @@ int run_main_application(int argc, char** argv)
|
||||
case pp::platform::windows::MainStartupResult::Ok:
|
||||
break;
|
||||
case pp::platform::windows::MainStartupResult::GladLoadFailure:
|
||||
bind_runtime(nullptr);
|
||||
return 0;
|
||||
case pp::platform::windows::MainStartupResult::MissingCoreContextSupport:
|
||||
bind_runtime(nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -151,6 +175,7 @@ int run_main_application(int argc, char** argv)
|
||||
case const_hash("convert"):
|
||||
App::I->initShaders();
|
||||
App::I->cmd_convert(argv[2], argv[3]);
|
||||
bind_runtime(nullptr);
|
||||
return 0;
|
||||
case const_hash("-vrmode"):
|
||||
start_in_vr = true;
|
||||
|
||||
@@ -3,9 +3,13 @@
|
||||
#include "platform_windows/windows_bootstrap_helpers.h"
|
||||
#include "platform_windows/windows_splash.h"
|
||||
|
||||
class AppRuntime;
|
||||
|
||||
namespace pp::platform::windows {
|
||||
|
||||
int run_main_application(int argc, char** argv);
|
||||
void run_main_window_runtime(const MainWindowStartupState& startup, bool start_in_vr, SplashScreen& splash);
|
||||
void bind_runtime(AppRuntime* runtime) noexcept;
|
||||
[[nodiscard]] AppRuntime* bound_runtime() noexcept;
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user