Route prepared file targets through platform services
This commit is contained in:
@@ -544,8 +544,9 @@ Known local toolchain state:
|
|||||||
hooks, render debug callback hooks, per-frame platform hooks, picker
|
hooks, render debug callback hooks, per-frame platform hooks, picker
|
||||||
callbacks, recording cleanup, exported-image publishing, persistent storage
|
callbacks, recording cleanup, exported-image publishing, persistent storage
|
||||||
flushing, document browse roots, native UI/window state saving, live
|
flushing, document browse roots, native UI/window state saving, live
|
||||||
asset/layout reload policy, diagnostic stacktrace/crash hooks, prepared-file
|
asset/layout reload policy, diagnostic stacktrace/crash hooks,
|
||||||
save/download handoff;
|
prepared-file writable target selection, and prepared-file save/download
|
||||||
|
handoff;
|
||||||
Windows
|
Windows
|
||||||
live app execution now uses injected
|
live app execution now uses injected
|
||||||
`WindowsPlatformServices` from
|
`WindowsPlatformServices` from
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ agent or engineer to remove them without reconstructing context from chat.
|
|||||||
| 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-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 now dispatch through `PlatformServices`, but iOS `Inbox` inclusion still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve current iOS document import/browse 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 are owned by injected Apple and desktop `pp_platform_*` services with no legacy adapter branch |
|
| DEBT-0051 | Open | Modernization | Document browser search roots now dispatch through `PlatformServices`, but iOS `Inbox` inclusion still lives in `src/platform_legacy/legacy_platform_services.*` | Preserve current iOS document import/browse 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 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-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 now dispatches 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 and save/download handoff are owned by injected platform services with no legacy adapter branch |
|
||||||
|
|
||||||
## Closed Debt
|
## Closed Debt
|
||||||
|
|
||||||
|
|||||||
@@ -639,6 +639,10 @@ is preserved while their platform shell implementations are extracted.
|
|||||||
Prepared-file save/download handoff is now also part of the service contract,
|
Prepared-file save/download handoff is now also part of the service contract,
|
||||||
so iOS/Web export completion routes through `PlatformServices` after the app
|
so iOS/Web export completion routes through `PlatformServices` after the app
|
||||||
writes the temporary/exported payload.
|
writes the temporary/exported payload.
|
||||||
|
Prepared-file writable target selection now also dispatches through
|
||||||
|
`PlatformServices`, preserving the existing iOS temporary background-write path
|
||||||
|
and Web data-path synchronous write path while removing those platform branches
|
||||||
|
from `App::pick_file_save`.
|
||||||
Canvas image export publishing and explicit persistent-storage flushes now
|
Canvas image export publishing and explicit persistent-storage flushes now
|
||||||
dispatch through `PlatformServices` too, preserving iOS photo-library export
|
dispatch through `PlatformServices` too, preserving iOS photo-library export
|
||||||
publication and WebGL filesystem sync behavior in the legacy adapter while
|
publication and WebGL filesystem sync behavior in the legacy adapter while
|
||||||
@@ -1692,7 +1696,8 @@ Results:
|
|||||||
dispatch, render debug callback dispatch, render-capture frame hook dispatch,
|
dispatch, render debug callback dispatch, render-capture frame hook dispatch,
|
||||||
recording cleanup dispatch, exported-image publish dispatch, persistent
|
recording cleanup dispatch, exported-image publish dispatch, persistent
|
||||||
storage flush dispatch, document browse-root dispatch,
|
storage flush dispatch, document browse-root dispatch,
|
||||||
native UI/window state save dispatch, live asset/layout reload policy dispatch,
|
native UI/window state save dispatch, prepared-file writable target dispatch,
|
||||||
|
live asset/layout reload policy dispatch,
|
||||||
diagnostic hook dispatch, per-frame platform hook dispatch, picker callback
|
diagnostic hook dispatch, per-frame platform hook dispatch, picker callback
|
||||||
dispatch, and prepared-file save/download callback dispatch. The live Windows
|
dispatch, and prepared-file save/download callback dispatch. The live Windows
|
||||||
app now
|
app now
|
||||||
|
|||||||
@@ -181,12 +181,9 @@ public:
|
|||||||
bool clipboard_set_text(const std::string& s);
|
bool clipboard_set_text(const std::string& s);
|
||||||
void pick_image(std::function<void(std::string path)> callback);
|
void pick_image(std::function<void(std::string path)> callback);
|
||||||
void pick_file(std::vector<std::string> types, std::function<void(std::string path)> callback);
|
void pick_file(std::vector<std::string> types, std::function<void(std::string path)> callback);
|
||||||
#if __IOS__ || __WEB__
|
|
||||||
void pick_file_save(const std::string& type, const std::string& default_name,
|
void pick_file_save(const std::string& type, const std::string& default_name,
|
||||||
std::function<void(std::string path)> writer, std::function<void(const std::string& path, bool saved)> callback);
|
std::function<void(std::string path)> writer, std::function<void(const std::string& path, bool saved)> callback);
|
||||||
#else
|
|
||||||
void pick_file_save(std::vector<std::string> types, std::function<void(std::string path)> callback);
|
void pick_file_save(std::vector<std::string> types, std::function<void(std::string path)> callback);
|
||||||
#endif
|
|
||||||
void pick_dir(std::function<void(std::string path)> callback);
|
void pick_dir(std::function<void(std::string path)> callback);
|
||||||
void display_file(std::string path);
|
void display_file(std::string path);
|
||||||
void share_file(std::string path);
|
void share_file(std::string path);
|
||||||
|
|||||||
@@ -152,35 +152,34 @@ void App::pick_file(std::vector<std::string> types, std::function<void (std::str
|
|||||||
active_platform_services().pick_file(std::move(types), std::move(callback));
|
active_platform_services().pick_file(std::move(types), std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __IOS__
|
|
||||||
void App::pick_file_save(const std::string& type, const std::string& default_name,
|
void App::pick_file_save(const std::string& type, const std::string& default_name,
|
||||||
std::function<void(std::string)> writer, std::function<void(const std::string& path, bool saved)> callback)
|
std::function<void(std::string)> writer, std::function<void(const std::string& path, bool saved)> callback)
|
||||||
{
|
{
|
||||||
redraw = true;
|
redraw = true;
|
||||||
std::string ext = "." + type;
|
const auto target = active_platform_services().prepare_writable_file(type, default_name, data_path, tmp_path);
|
||||||
std::string path = tmp_path + "/" + default_name + ext;
|
if (target.path.empty())
|
||||||
std::thread([=]{
|
{
|
||||||
writer(path);
|
callback({}, false);
|
||||||
save_prepared_file(path, default_name + ext, callback);
|
return;
|
||||||
}).detach();
|
}
|
||||||
|
|
||||||
|
LOG("App::pick_file_save %s", target.path.c_str());
|
||||||
|
auto write_and_save = [=] {
|
||||||
|
writer(target.path);
|
||||||
|
save_prepared_file(target.path, target.suggested_name, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (target.write_on_background_thread)
|
||||||
|
std::thread(write_and_save).detach();
|
||||||
|
else
|
||||||
|
write_and_save();
|
||||||
}
|
}
|
||||||
#elif __WEB__
|
|
||||||
void App::pick_file_save(const std::string& type, const std::string& default_name,
|
|
||||||
std::function<void(std::string)> writer, std::function<void(const std::string& path, bool saved)> callback)
|
|
||||||
{
|
|
||||||
redraw = true;
|
|
||||||
auto path = data_path + "/" + default_name + "." + type;
|
|
||||||
LOG("App::pick_file_save %s", path.c_str());
|
|
||||||
writer(path);
|
|
||||||
save_prepared_file(path, default_name + "." + type, std::move(callback));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void App::pick_file_save(std::vector<std::string> types, std::function<void(std::string)> callback)
|
void App::pick_file_save(std::vector<std::string> types, std::function<void(std::string)> callback)
|
||||||
{
|
{
|
||||||
redraw = true;
|
redraw = true;
|
||||||
active_platform_services().pick_save_file(std::move(types), std::move(callback));
|
active_platform_services().pick_save_file(std::move(types), std::move(callback));
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
void App::pick_dir(std::function<void(std::string path)> callback)
|
void App::pick_dir(std::function<void(std::string path)> callback)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,6 +10,12 @@ namespace pp::platform {
|
|||||||
using PickedPathCallback = std::function<void(std::string path)>;
|
using PickedPathCallback = std::function<void(std::string path)>;
|
||||||
using PreparedFileCallback = std::function<void(std::string path, bool saved)>;
|
using PreparedFileCallback = std::function<void(std::string path, bool saved)>;
|
||||||
|
|
||||||
|
struct PreparedFileTarget {
|
||||||
|
std::string path;
|
||||||
|
std::string suggested_name;
|
||||||
|
bool write_on_background_thread = false;
|
||||||
|
};
|
||||||
|
|
||||||
struct PlatformStoragePaths {
|
struct PlatformStoragePaths {
|
||||||
std::string data_path;
|
std::string data_path;
|
||||||
std::string work_path;
|
std::string work_path;
|
||||||
@@ -57,6 +63,11 @@ public:
|
|||||||
virtual void pick_file(std::vector<std::string> file_types, PickedPathCallback callback) = 0;
|
virtual void pick_file(std::vector<std::string> file_types, PickedPathCallback callback) = 0;
|
||||||
virtual void pick_save_file(std::vector<std::string> file_types, PickedPathCallback callback) = 0;
|
virtual void pick_save_file(std::vector<std::string> file_types, PickedPathCallback callback) = 0;
|
||||||
virtual void pick_directory(PickedPathCallback callback) = 0;
|
virtual void pick_directory(PickedPathCallback callback) = 0;
|
||||||
|
[[nodiscard]] virtual PreparedFileTarget prepare_writable_file(
|
||||||
|
std::string_view type,
|
||||||
|
std::string_view default_name,
|
||||||
|
std::string_view data_path,
|
||||||
|
std::string_view temporary_path) = 0;
|
||||||
virtual void save_prepared_file(
|
virtual void save_prepared_file(
|
||||||
std::string_view path,
|
std::string_view path,
|
||||||
std::string_view suggested_name,
|
std::string_view suggested_name,
|
||||||
|
|||||||
@@ -431,6 +431,34 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] pp::platform::PreparedFileTarget prepare_writable_file(
|
||||||
|
std::string_view type,
|
||||||
|
std::string_view default_name,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
void display_file(std::string_view path) override
|
void display_file(std::string_view path) override
|
||||||
{
|
{
|
||||||
const std::string value(path);
|
const std::string value(path);
|
||||||
|
|||||||
@@ -448,6 +448,19 @@ public:
|
|||||||
invoke_selected_path(path, callback);
|
invoke_selected_path(path, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] pp::platform::PreparedFileTarget prepare_writable_file(
|
||||||
|
std::string_view type,
|
||||||
|
std::string_view default_name,
|
||||||
|
std::string_view data_path,
|
||||||
|
std::string_view temporary_path) override
|
||||||
|
{
|
||||||
|
(void)type;
|
||||||
|
(void)default_name;
|
||||||
|
(void)data_path;
|
||||||
|
(void)temporary_path;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
void save_prepared_file(
|
void save_prepared_file(
|
||||||
std::string_view path,
|
std::string_view path,
|
||||||
std::string_view suggested_name,
|
std::string_view suggested_name,
|
||||||
|
|||||||
@@ -210,6 +210,20 @@ public:
|
|||||||
callback(directory_path);
|
callback(directory_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] pp::platform::PreparedFileTarget prepare_writable_file(
|
||||||
|
std::string_view type,
|
||||||
|
std::string_view default_name,
|
||||||
|
std::string_view data_path,
|
||||||
|
std::string_view temporary_path) override
|
||||||
|
{
|
||||||
|
++prepare_writable_file_requests;
|
||||||
|
writable_file_type.assign(type);
|
||||||
|
writable_file_default_name.assign(default_name);
|
||||||
|
writable_file_data_path.assign(data_path);
|
||||||
|
writable_file_temporary_path.assign(temporary_path);
|
||||||
|
return writable_file_target;
|
||||||
|
}
|
||||||
|
|
||||||
void save_prepared_file(
|
void save_prepared_file(
|
||||||
std::string_view path,
|
std::string_view path,
|
||||||
std::string_view suggested_name,
|
std::string_view suggested_name,
|
||||||
@@ -255,6 +269,7 @@ public:
|
|||||||
int pick_file_requests = 0;
|
int pick_file_requests = 0;
|
||||||
int pick_save_file_requests = 0;
|
int pick_save_file_requests = 0;
|
||||||
int pick_directory_requests = 0;
|
int pick_directory_requests = 0;
|
||||||
|
int prepare_writable_file_requests = 0;
|
||||||
int save_prepared_file_requests = 0;
|
int save_prepared_file_requests = 0;
|
||||||
bool cursor_visible = false;
|
bool cursor_visible = false;
|
||||||
bool keyboard_visible = false;
|
bool keyboard_visible = false;
|
||||||
@@ -271,6 +286,10 @@ public:
|
|||||||
std::string exported_image_path;
|
std::string exported_image_path;
|
||||||
std::string browse_work_path;
|
std::string browse_work_path;
|
||||||
std::string browse_data_path;
|
std::string browse_data_path;
|
||||||
|
std::string writable_file_type;
|
||||||
|
std::string writable_file_default_name;
|
||||||
|
std::string writable_file_data_path;
|
||||||
|
std::string writable_file_temporary_path;
|
||||||
std::string picker_path = "D:/Paint/import.png";
|
std::string picker_path = "D:/Paint/import.png";
|
||||||
std::string save_path = "D:/Paint/export.ppi";
|
std::string save_path = "D:/Paint/export.ppi";
|
||||||
std::string directory_path = "D:/Paint";
|
std::string directory_path = "D:/Paint";
|
||||||
@@ -286,6 +305,11 @@ public:
|
|||||||
"D:/Paint/work",
|
"D:/Paint/work",
|
||||||
"D:/Paint/Inbox",
|
"D:/Paint/Inbox",
|
||||||
};
|
};
|
||||||
|
pp::platform::PreparedFileTarget writable_file_target{
|
||||||
|
"D:/Paint/tmp/export.mp4",
|
||||||
|
"export.mp4",
|
||||||
|
true,
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string clipboard_value_;
|
std::string clipboard_value_;
|
||||||
@@ -542,6 +566,23 @@ void platform_services_dispatch_prepared_file_save(pp::tests::Harness& harness)
|
|||||||
PP_EXPECT(harness, saved);
|
PP_EXPECT(harness, saved);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void platform_services_dispatch_writable_file_target(pp::tests::Harness& harness)
|
||||||
|
{
|
||||||
|
FakePlatformServices fake("unused");
|
||||||
|
pp::platform::PlatformServices& services = fake;
|
||||||
|
|
||||||
|
const auto target = services.prepare_writable_file("mp4", "export", "D:/Paint", "D:/Paint/tmp");
|
||||||
|
|
||||||
|
PP_EXPECT(harness, fake.prepare_writable_file_requests == 1);
|
||||||
|
PP_EXPECT(harness, fake.writable_file_type == "mp4");
|
||||||
|
PP_EXPECT(harness, fake.writable_file_default_name == "export");
|
||||||
|
PP_EXPECT(harness, fake.writable_file_data_path == "D:/Paint");
|
||||||
|
PP_EXPECT(harness, fake.writable_file_temporary_path == "D:/Paint/tmp");
|
||||||
|
PP_EXPECT(harness, target.path == "D:/Paint/tmp/export.mp4");
|
||||||
|
PP_EXPECT(harness, target.suggested_name == "export.mp4");
|
||||||
|
PP_EXPECT(harness, target.write_on_background_thread);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -564,5 +605,6 @@ int main()
|
|||||||
harness.run("platform services dispatch file actions", platform_services_dispatch_file_actions);
|
harness.run("platform services dispatch file actions", platform_services_dispatch_file_actions);
|
||||||
harness.run("platform services dispatch picker callbacks", platform_services_dispatch_picker_callbacks);
|
harness.run("platform services dispatch picker callbacks", platform_services_dispatch_picker_callbacks);
|
||||||
harness.run("platform services dispatch prepared file save", platform_services_dispatch_prepared_file_save);
|
harness.run("platform services dispatch prepared file save", platform_services_dispatch_prepared_file_save);
|
||||||
|
harness.run("platform services dispatch writable file target", platform_services_dispatch_writable_file_target);
|
||||||
return harness.finish();
|
return harness.finish();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user