diff --git a/loader/include/Geode/utils/file.hpp b/loader/include/Geode/utils/file.hpp index 7c315dc8..8ac1164b 100644 --- a/loader/include/Geode/utils/file.hpp +++ b/loader/include/Geode/utils/file.hpp @@ -252,35 +252,17 @@ namespace geode::utils::file { std::vector filters; }; - // /** - // * Prompt the user to pick a file using the system's file system picker - // * @deprecated Will not work on Android, use the callback version instead - // * @param mode Type of file selection prompt to show - // * @param options Picker options - // */ - // [[deprecated("Use pick() instead, this will be removed in a later version.")]] - // GEODE_DLL Result pickFile(PickMode mode, FilePickOptions const& options); - - // GEODE_DLL void pickFile( - // PickMode mode, FilePickOptions const& options, - // utils::MiniFunction callback, - // utils::MiniFunction failed = {} - // ); + /** + * Prompt the user to pick a file using the system's file system picker + * @param mode Type of file selection prompt to show + * @param options Picker options + */ GEODE_DLL Task> pick(PickMode mode, FilePickOptions const& options); - // /** - // * Prompt the user to pick a bunch of files for opening using the system's file system picker - // * @deprecated Will not work on Android, use the callback version instead - // * @param options Picker options - // */ - // [[deprecated("Use pickMany() instead, this will be removed in a later version.")]] - // GEODE_DLL Result> pickFiles(FilePickOptions const& options); - - // GEODE_DLL void pickFiles( - // FilePickOptions const& options, - // utils::MiniFunction)> callback, - // utils::MiniFunction failed = {} - // ); + /** + * Prompt the user to pick a bunch of files for opening using the system's file system picker + * @param options Picker options + */ GEODE_DLL Task>> pickMany(FilePickOptions const& options); class GEODE_DLL FileWatchEvent : public Event { diff --git a/loader/src/platform/android/util.cpp b/loader/src/platform/android/util.cpp index 489ca67d..3294b9bf 100644 --- a/loader/src/platform/android/util.cpp +++ b/loader/src/platform/android/util.cpp @@ -1,4 +1,4 @@ -#include +#include using namespace geode::prelude; @@ -6,7 +6,6 @@ using namespace geode::prelude; #include #include #include -#include #include #include #include @@ -15,6 +14,9 @@ using namespace geode::prelude; #include #include #include +#include +#include +#include #include #include @@ -137,9 +139,11 @@ bool utils::file::openFolder(std::filesystem::path const& path) { } -static utils::MiniFunction s_fileCallback; -static utils::MiniFunction)> s_filesCallback; -static utils::MiniFunction s_failedCallback; +// static utils::MiniFunction s_fileCallback; +// static utils::MiniFunction)> s_filesCallback; +// static utils::MiniFunction s_failedCallback; +static std::optional> s_fileResult = std::nullopt; +static std::optional>> s_filesResult = std::nullopt; extern "C" JNIEXPORT void JNICALL Java_com_geode_launcher_utils_GeodeUtils_selectFileCallback( @@ -151,10 +155,7 @@ JNIEXPORT void JNICALL Java_com_geode_launcher_utils_GeodeUtils_selectFileCallba auto dataStr = env->GetStringUTFChars(data, &isCopy); log::debug("Selected file: {}", dataStr); - - Loader::get()->queueInMainThread([dataStr]() { - s_fileCallback(dataStr); - }); + s_fileResult = Ok(std::filesystem::path(dataStr)); } extern "C" @@ -174,9 +175,7 @@ JNIEXPORT void JNICALL Java_com_geode_launcher_utils_GeodeUtils_selectFilesCallb log::debug("Selected file {}: {}", i, dataStr); } - Loader::get()->queueInMainThread([result]() { - s_filesCallback(result); - }); + s_filesResult = Ok(std::move(result)); } extern "C" @@ -184,93 +183,82 @@ JNIEXPORT void JNICALL Java_com_geode_launcher_utils_GeodeUtils_failedCallback( JNIEnv *env, jobject ) { - if (s_failedCallback) { - Loader::get()->queueInMainThread([]() { - s_failedCallback(); - }); - } + s_fileResult = Err("Permission error"); + s_filesResult = Err("Permission error"); } -Result file::pickFile(file::PickMode mode, file::FilePickOptions const& options) { - return Err("Use the callback version"); -} +Task> file::pick(file::PickMode mode, file::FilePickOptions const& options) { + using RetTask = Task>; + s_fileResult = std::nullopt; + return RetTask::run([mode, options](auto progress, auto cancelled) -> RetTask::Result { + std::string method; + switch (mode) { + case file::PickMode::OpenFile: + method = "selectFile"; + break; + case file::PickMode::SaveFile: + method = "createFile"; + break; + case file::PickMode::OpenFolder: + method = "selectFolder"; + break; + } -GEODE_DLL Task> pick(PickMode mode, FilePickOptions const& options) { - using RetTask = Task> - return RetTask::runWithCallback([] (auto resultCallback, auto progressCallback, auto cancelCallback) { - + JniMethodInfo t; + if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", method.c_str(), "(Ljava/lang/String;)Z")) { + jstring stringArg1 = t.env->NewStringUTF(options.defaultPath.value_or(std::filesystem::path()).filename().string().c_str()); + + jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1); + + t.env->DeleteLocalRef(stringArg1); + t.env->DeleteLocalRef(t.classID); + if (result) { + return Err("Failed to open file picker"); + } + } + + // Time for while loop :D + while (!s_fileResult.has_value()) { + if (cancelled()) { + return RetTask::Cancel(); + } + } + + Result result = s_fileResult.value(); + s_fileResult = std::nullopt; + return result; }); } -void file::pickFile( - PickMode mode, FilePickOptions const& options, - MiniFunction callback, - MiniFunction failed -) { - s_fileCallback = callback; - s_failedCallback = failed; +Task>> file::pickMany(FilePickOptions const& options) { + using RetTask = Task>>; + s_filesResult = std::nullopt; - std::string method; - switch (mode) { - case file::PickMode::OpenFile: - method = "selectFile"; - break; - case file::PickMode::SaveFile: - method = "createFile"; - break; - case file::PickMode::OpenFolder: - method = "selectFolder"; - break; - } + return RetTask::run([options](auto progress, auto cancelled) -> RetTask::Result { + JniMethodInfo t; + if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "selectFiles", "(Ljava/lang/String;)Z")) { + jstring stringArg1 = t.env->NewStringUTF(options.defaultPath.value_or(std::filesystem::path()).string().c_str()); - JniMethodInfo t; - if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", method.c_str(), "(Ljava/lang/String;)Z")) { - jstring stringArg1 = t.env->NewStringUTF(options.defaultPath.value_or(std::filesystem::path()).filename().string().c_str()); + jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1); - jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1); - - t.env->DeleteLocalRef(stringArg1); - t.env->DeleteLocalRef(t.classID); - if (result) { - return; + t.env->DeleteLocalRef(stringArg1); + t.env->DeleteLocalRef(t.classID); + if (result) { + return Err("Failed to open file dialog"); + } } - } - if (s_failedCallback) { - Loader::get()->queueInMainThread([]() { - s_failedCallback(); - }); - } -} -Result> file::pickFiles(file::FilePickOptions const& options) { - return Err("Use the callback version"); -} - -void file::pickFiles( - FilePickOptions const& options, - MiniFunction)> callback, - MiniFunction failed -) { - s_filesCallback = callback; - s_failedCallback = failed; - - JniMethodInfo t; - if (JniHelper::getStaticMethodInfo(t, "com/geode/launcher/utils/GeodeUtils", "selectFiles", "(Ljava/lang/String;)Z")) { - jstring stringArg1 = t.env->NewStringUTF(options.defaultPath.value_or(std::filesystem::path()).string().c_str()); - - jboolean result = t.env->CallStaticBooleanMethod(t.classID, t.methodID, stringArg1); - - t.env->DeleteLocalRef(stringArg1); - t.env->DeleteLocalRef(t.classID); - if (result) { - return; + // Time for while loop :D + while (!s_fileResult.has_value()) { + if (cancelled()) { + return RetTask::Cancel(); + } } - } - if (s_failedCallback) { - Loader::get()->queueInMainThread([]() { - s_failedCallback(); - }); - } + + Result> result = s_filesResult.value(); + s_filesResult = std::nullopt; + return result; + }); } void geode::utils::game::launchLoaderUninstaller(bool deleteSaveData) { diff --git a/loader/src/ui/mods/settings/GeodeSettingNode.cpp b/loader/src/ui/mods/settings/GeodeSettingNode.cpp index bf543bed..db54bb7a 100644 --- a/loader/src/ui/mods/settings/GeodeSettingNode.cpp +++ b/loader/src/ui/mods/settings/GeodeSettingNode.cpp @@ -9,6 +9,7 @@ #include #include #include +#include // Helpers @@ -364,16 +365,20 @@ void FileSettingNode::valueChanged(bool updateText) { } void FileSettingNode::onPickFile(CCObject*) { - file::pickFile( - file::PickMode::OpenFile, + file::pick( + file::PickMode::OpenFile, { dirs::getGameDir(), setting()->castDefinition().controls.filters + }).then( + [this](Result* path) { + if (path->isOk()) { + m_uncommittedValue = path->unwrap(); + this->valueChanged(true); + } }, - [&](auto path) { - m_uncommittedValue = path; - this->valueChanged(true); - } + [] (auto progress) {}, + [] () {} ); }