Own grid workers and thin Apple platform bridge
This commit is contained in:
@@ -5,6 +5,14 @@
|
||||
#include "app_core/document_platform_io.h"
|
||||
#include "app_core/document_sharing.h"
|
||||
#include "platform_api/platform_services.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <stop_token>
|
||||
#include <thread>
|
||||
|
||||
#ifdef __LINUX__
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "platform_linux/linux_platform_services.h"
|
||||
@@ -14,6 +22,79 @@
|
||||
|
||||
namespace {
|
||||
|
||||
class LegacyPreparedFileWorker final {
|
||||
public:
|
||||
LegacyPreparedFileWorker()
|
||||
: worker_([this](std::stop_token stop_token) {
|
||||
run(stop_token);
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
~LegacyPreparedFileWorker()
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void post(std::function<void()> task)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (stopping_)
|
||||
return;
|
||||
tasks_.push_back(std::move(task));
|
||||
}
|
||||
cv_.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
void shutdown()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
stopping_ = true;
|
||||
}
|
||||
cv_.notify_all();
|
||||
}
|
||||
|
||||
void run(std::stop_token stop_token)
|
||||
{
|
||||
for (;;) {
|
||||
std::function<void()> task;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
cv_.wait(lock, [&] {
|
||||
return stopping_ || stop_token.stop_requested() || !tasks_.empty();
|
||||
});
|
||||
if ((stopping_ || stop_token.stop_requested()) && tasks_.empty())
|
||||
break;
|
||||
task = std::move(tasks_.front());
|
||||
tasks_.pop_front();
|
||||
}
|
||||
|
||||
if (task) {
|
||||
try {
|
||||
task();
|
||||
} catch (...) {
|
||||
LOG("prepared file worker task failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cv_;
|
||||
std::deque<std::function<void()>> tasks_;
|
||||
bool stopping_ = false;
|
||||
std::jthread worker_;
|
||||
};
|
||||
|
||||
LegacyPreparedFileWorker& prepared_file_worker()
|
||||
{
|
||||
static LegacyPreparedFileWorker worker;
|
||||
return worker;
|
||||
}
|
||||
|
||||
[[nodiscard]] GLint rgba8_internal_format() noexcept
|
||||
{
|
||||
return static_cast<GLint>(pp::renderer::gl::rgba8_internal_format());
|
||||
@@ -201,15 +282,31 @@ void App::pick_file_save(const std::string& type, const std::string& default_nam
|
||||
}
|
||||
|
||||
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) {
|
||||
auto* app = this;
|
||||
prepared_file_worker().post([
|
||||
app,
|
||||
writer = std::move(writer),
|
||||
callback = std::move(callback),
|
||||
path = target.path,
|
||||
suggested_name = target.suggested_name
|
||||
]() mutable {
|
||||
writer(path);
|
||||
app->ui_task([app,
|
||||
path = std::move(path),
|
||||
suggested_name = std::move(suggested_name),
|
||||
callback = std::move(callback)]() mutable {
|
||||
app->save_prepared_file(
|
||||
std::move(path),
|
||||
std::move(suggested_name),
|
||||
std::move(callback));
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.write_on_background_thread)
|
||||
std::thread(write_and_save).detach();
|
||||
else
|
||||
write_and_save();
|
||||
writer(target.path);
|
||||
save_prepared_file(target.path, target.suggested_name, std::move(callback));
|
||||
}
|
||||
|
||||
void App::pick_file_save(std::vector<std::string> types, std::function<void(std::string)> callback)
|
||||
|
||||
@@ -7,9 +7,89 @@
|
||||
#include "image.h"
|
||||
#include "node_panel_grid.h"
|
||||
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <stop_token>
|
||||
#include <thread>
|
||||
|
||||
namespace pp::panopainter {
|
||||
namespace {
|
||||
|
||||
class LegacyGridWorker final {
|
||||
public:
|
||||
LegacyGridWorker()
|
||||
: worker_([this](std::stop_token stop_token) {
|
||||
run(stop_token);
|
||||
})
|
||||
{
|
||||
}
|
||||
|
||||
~LegacyGridWorker()
|
||||
{
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void post(std::function<void()> task)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
if (stopping_)
|
||||
return;
|
||||
tasks_.push_back(std::move(task));
|
||||
}
|
||||
cv_.notify_one();
|
||||
}
|
||||
|
||||
private:
|
||||
void shutdown()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
stopping_ = true;
|
||||
}
|
||||
cv_.notify_all();
|
||||
}
|
||||
|
||||
void run(std::stop_token stop_token)
|
||||
{
|
||||
for (;;) {
|
||||
std::function<void()> task;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
cv_.wait(lock, [&] {
|
||||
return stopping_ || stop_token.stop_requested() || !tasks_.empty();
|
||||
});
|
||||
if ((stopping_ || stop_token.stop_requested()) && tasks_.empty())
|
||||
break;
|
||||
task = std::move(tasks_.front());
|
||||
tasks_.pop_front();
|
||||
}
|
||||
|
||||
if (task) {
|
||||
try {
|
||||
task();
|
||||
} catch (...) {
|
||||
LOG("grid worker task failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::mutex mutex_;
|
||||
std::condition_variable cv_;
|
||||
std::deque<std::function<void()>> tasks_;
|
||||
bool stopping_ = false;
|
||||
std::jthread worker_;
|
||||
};
|
||||
|
||||
LegacyGridWorker& grid_worker()
|
||||
{
|
||||
static LegacyGridWorker worker;
|
||||
return worker;
|
||||
}
|
||||
|
||||
class LegacyGridUiServices final : public pp::app::GridUiServices {
|
||||
public:
|
||||
explicit LegacyGridUiServices(NodePanelGrid& panel) noexcept
|
||||
@@ -66,13 +146,17 @@ public:
|
||||
if (!renders_lightmap)
|
||||
return;
|
||||
|
||||
auto* panel = &panel_;
|
||||
std::thread([panel] {
|
||||
auto panel = std::static_pointer_cast<NodePanelGrid>(panel_.shared_from_this());
|
||||
grid_worker().post([panel] {
|
||||
BT_SetTerminate();
|
||||
panel->bake_uvs();
|
||||
panel->m_hm_shading->set_index(3);
|
||||
panel->m_shade_mode = NodePanelGrid::ShadeMode::Textured;
|
||||
}).detach();
|
||||
if (App::I) {
|
||||
App::I->ui_task([panel] {
|
||||
panel->m_hm_shading->set_index(3);
|
||||
panel->m_shade_mode = NodePanelGrid::ShadeMode::Textured;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void commit_heightmap(bool updates_ground_opacity) override
|
||||
|
||||
@@ -6,11 +6,6 @@
|
||||
#include <array>
|
||||
#include <utility>
|
||||
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
#include "app_core/app.h"
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
namespace pp::platform::apple {
|
||||
namespace {
|
||||
|
||||
@@ -54,26 +49,16 @@ std::vector<std::string> AppleDocumentPlatformServices::document_browse_roots(
|
||||
|
||||
std::string AppleDocumentPlatformServices::clipboard_text() const
|
||||
{
|
||||
#if defined(__IOS__)
|
||||
return [App::I->ios_view clipboard_get_string];
|
||||
#elif defined(__OSX__)
|
||||
return [App::I->osx_view clipboard_get_string];
|
||||
#else
|
||||
if (bridge_.clipboard_text)
|
||||
return bridge_.clipboard_text();
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
bool AppleDocumentPlatformServices::set_clipboard_text(std::string_view text) const
|
||||
{
|
||||
const std::string value(text);
|
||||
#if defined(__IOS__)
|
||||
return [App::I->ios_view clipboard_set_string:value];
|
||||
#elif defined(__OSX__)
|
||||
return [App::I->osx_view clipboard_set_string:value];
|
||||
#else
|
||||
(void)value;
|
||||
if (bridge_.set_clipboard_text)
|
||||
return bridge_.set_clipboard_text(text);
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void AppleDocumentPlatformServices::pick_image(PickedPathCallback callback) const
|
||||
@@ -158,9 +143,8 @@ void AppleDocumentPlatformServices::display_file(std::string_view path) const
|
||||
{
|
||||
const std::string value(path);
|
||||
#if defined(__IOS__)
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[App::I->ios_view display_file:value];
|
||||
});
|
||||
if (bridge_.display_file)
|
||||
bridge_.display_file(value);
|
||||
#elif defined(__OSX__)
|
||||
[[NSWorkspace sharedWorkspace] openFile:[NSString stringWithUTF8String:value.c_str()]];
|
||||
#else
|
||||
@@ -171,14 +155,9 @@ void AppleDocumentPlatformServices::display_file(std::string_view path) const
|
||||
void AppleDocumentPlatformServices::share_file(std::string_view path) const
|
||||
{
|
||||
const std::string value(path);
|
||||
#if defined(__IOS__)
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[App::I->ios_view share_file:[NSString stringWithUTF8String:value.c_str()]];
|
||||
});
|
||||
#elif defined(__OSX__)
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[App::I->osx_view share_file:[NSString stringWithUTF8String:value.c_str()]];
|
||||
});
|
||||
#if defined(__IOS__) || defined(__OSX__)
|
||||
if (bridge_.share_file)
|
||||
bridge_.share_file(value);
|
||||
#else
|
||||
(void)value;
|
||||
#endif
|
||||
@@ -187,7 +166,8 @@ void AppleDocumentPlatformServices::share_file(std::string_view path) const
|
||||
void AppleDocumentPlatformServices::set_cursor_visible(bool visible) const
|
||||
{
|
||||
#if defined(__OSX__)
|
||||
[App::I->osx_view show_cursor:visible];
|
||||
if (bridge_.set_cursor_visible)
|
||||
bridge_.set_cursor_visible(visible);
|
||||
#else
|
||||
(void)visible;
|
||||
#endif
|
||||
@@ -196,7 +176,8 @@ void AppleDocumentPlatformServices::set_cursor_visible(bool visible) const
|
||||
void AppleDocumentPlatformServices::save_ui_state() const
|
||||
{
|
||||
#if defined(__OSX__)
|
||||
[App::I->osx_app save_ui_state];
|
||||
if (bridge_.save_ui_state)
|
||||
bridge_.save_ui_state();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,12 @@ struct AppleDocumentPickerBridge {
|
||||
std::function<void(std::vector<std::string> file_types, PickedPathCallback callback)> pick_save_file;
|
||||
std::function<void(PickedPathCallback callback)> pick_directory;
|
||||
std::function<std::string(std::string_view path)> format_working_directory_path;
|
||||
std::function<std::string()> clipboard_text;
|
||||
std::function<bool(std::string_view text)> set_clipboard_text;
|
||||
std::function<void(std::string path)> display_file;
|
||||
std::function<void(std::string path)> share_file;
|
||||
std::function<void(bool visible)> set_cursor_visible;
|
||||
std::function<void()> save_ui_state;
|
||||
};
|
||||
|
||||
class AppleDocumentPlatformServices {
|
||||
|
||||
@@ -112,6 +112,23 @@ public:
|
||||
pp::platform::PlatformFamily::ios,
|
||||
[] {
|
||||
pp::platform::apple::AppleDocumentPickerBridge bridge;
|
||||
bridge.clipboard_text = [] {
|
||||
return [App::I->ios_view clipboard_get_string];
|
||||
};
|
||||
bridge.set_clipboard_text = [](std::string_view text) {
|
||||
const std::string value(text);
|
||||
return [App::I->ios_view clipboard_set_string:value];
|
||||
};
|
||||
bridge.display_file = [](std::string path) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[App::I->ios_view display_file:path];
|
||||
});
|
||||
};
|
||||
bridge.share_file = [](std::string path) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[App::I->ios_view share_file:[NSString stringWithUTF8String:path.c_str()]];
|
||||
});
|
||||
};
|
||||
bridge.pick_image = [](pp::platform::PickedPathCallback callback) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[App::I->ios_view pick_photo:callback];
|
||||
@@ -132,6 +149,24 @@ public:
|
||||
pp::platform::PlatformFamily::macos,
|
||||
[] {
|
||||
pp::platform::apple::AppleDocumentPickerBridge bridge;
|
||||
bridge.clipboard_text = [] {
|
||||
return [App::I->osx_view clipboard_get_string];
|
||||
};
|
||||
bridge.set_clipboard_text = [](std::string_view text) {
|
||||
const std::string value(text);
|
||||
return [App::I->osx_view clipboard_set_string:value];
|
||||
};
|
||||
bridge.share_file = [](std::string path) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[App::I->osx_view share_file:[NSString stringWithUTF8String:path.c_str()]];
|
||||
});
|
||||
};
|
||||
bridge.set_cursor_visible = [](bool visible) {
|
||||
[App::I->osx_view show_cursor:visible];
|
||||
};
|
||||
bridge.save_ui_state = [] {
|
||||
[App::I->osx_app save_ui_state];
|
||||
};
|
||||
bridge.pick_file = [](
|
||||
std::vector<std::string> file_types,
|
||||
pp::platform::PickedPathCallback callback) {
|
||||
|
||||
Reference in New Issue
Block a user