diff --git a/src/plugins/lua/bindings/utils.cpp b/src/plugins/lua/bindings/utils.cpp index c014690a238..970eef3440c 100644 --- a/src/plugins/lua/bindings/utils.cpp +++ b/src/plugins/lua/bindings/utils.cpp @@ -4,6 +4,8 @@ #include "../luaengine.h" #include "../luaqttypes.h" +#include +#include #include #include @@ -14,70 +16,28 @@ namespace Lua::Internal { void addUtilsModule() { - LuaEngine::registerProvider("__utils", [](sol::state_view lua) -> sol::object { - sol::table utils = lua.create_table(); + LuaEngine::registerProvider( + "Utils", + [futureSync = Utils::FutureSynchronizer()](sol::state_view lua) mutable -> sol::object { + auto async = lua.script("return require('async')", "_utils_").get(); - utils.set_function("waitms_cb", [](int ms, const sol::function &cb) { - QTimer *timer = new QTimer(); - timer->setSingleShot(true); - timer->setInterval(ms); - QObject::connect(timer, &QTimer::timeout, timer, [cb, timer]() { - cb(); - timer->deleteLater(); + sol::table utils = lua.create_table(); + + utils.set_function("waitms_cb", [](int ms, const sol::function &cb) { + QTimer *timer = new QTimer(); + timer->setSingleShot(true); + timer->setInterval(ms); + QObject::connect(timer, &QTimer::timeout, &LuaEngine::instance(), [cb, timer]() { + cb(); + timer->deleteLater(); + }); + timer->start(); }); - timer->start(); - }); - return utils; - }); - - LuaEngine::registerProvider("Utils", [](sol::state_view lua) -> sol::object { - sol::table utils = lua.script( - R"( -local u = require("__utils") -local a = require("async") - -return { - waitms_cb = u.waitms_cb, - waitms = a.wrap(u.waitms_cb) -} -)", - "_utils_") - .get(); - - auto hostOsInfoType = utils.new_usertype("HostOsInfo"); - hostOsInfoType["isWindowsHost"] = &HostOsInfo::isWindowsHost; - hostOsInfoType["isMacHost"] = &HostOsInfo::isMacHost; - hostOsInfoType["isLinuxHost"] = &HostOsInfo::isLinuxHost; - hostOsInfoType["os"] = sol::var([]() { - if (HostOsInfo::isMacHost()) - return "mac"; - else if (HostOsInfo::isLinuxHost()) - return "linux"; - else if (HostOsInfo::isWindowsHost()) - return "windows"; - else - return "unknown"; - }()); - - auto filePathType = utils.new_usertype( - "FilePath", - sol::call_constructor, - sol::constructors(), - "fromUserInput", - &FilePath::fromUserInput, - "searchInPath", - [](const FilePath &self) { return self.searchInPath(); }, - "exists", - &FilePath::exists, - "resolveSymlinks", - &FilePath::resolveSymlinks, - "isExecutableFile", - &FilePath::isExecutableFile, - "dirEntries", - [](sol::this_state s, const FilePath &p, const sol::table &options) -> sol::table { - sol::state_view lua(s); - sol::table result = lua.create_table(); + auto dirEntries_cb = [&futureSync]( + const FilePath &p, + const sol::table &options, + const sol::function &cb) { const QStringList nameFilters = options.get_or("nameFilters", {}); QDir::Filters fileFilters = (QDir::Filters) options.get_or("fileFilters", QDir::NoFilter); @@ -85,33 +45,87 @@ return { = (QDirIterator::IteratorFlags) options.get_or("flags", QDirIterator::NoIteratorFlags); - FileFilter filter(nameFilters); - p.iterateDirectory( - [&result](const FilePath &item) { - result.add(item); - return IterationPolicy::Continue; - }, - FileFilter(nameFilters, fileFilters, flags)); + FileFilter filter(nameFilters, fileFilters, flags); - return result; - }, - "nativePath", - &FilePath::nativePath, - "toUserOutput", - &FilePath::toUserOutput, - "fileName", - &FilePath::fileName, - "currentWorkingPath", - &FilePath::currentWorkingPath, - "parentDir", - &FilePath::parentDir, - "resolvePath", - sol::overload( - [](const FilePath &p, const QString &path) { return p.resolvePath(path); }, - [](const FilePath &p, const FilePath &path) { return p.resolvePath(path); })); + QFuture future = Utils::asyncRun([p, filter](QPromise &promise) { + p.iterateDirectory( + [&promise](const FilePath &item) { + if (promise.isCanceled()) + return IterationPolicy::Stop; - return utils; - }); + promise.addResult(item); + return IterationPolicy::Continue; + }, + filter); + }); + + futureSync.addFuture(future); + + Utils::onFinished( + future, &LuaEngine::instance(), [cb](const QFuture &future) { + cb(future.results()); + }); + }; + + utils.set_function("__dirEntries_cb__", dirEntries_cb); + + sol::function wrap = async["wrap"].get(); + + utils["waitms"] = wrap(utils["waitms_cb"]); + + auto hostOsInfoType = utils.new_usertype("HostOsInfo"); + hostOsInfoType["isWindowsHost"] = &HostOsInfo::isWindowsHost; + hostOsInfoType["isMacHost"] = &HostOsInfo::isMacHost; + hostOsInfoType["isLinuxHost"] = &HostOsInfo::isLinuxHost; + hostOsInfoType["os"] = sol::var([]() { + if (HostOsInfo::isMacHost()) + return "mac"; + else if (HostOsInfo::isLinuxHost()) + return "linux"; + else if (HostOsInfo::isWindowsHost()) + return "windows"; + else + return "unknown"; + }()); + + sol::usertype filePathType = utils.new_usertype( + "FilePath", + sol::call_constructor, + sol::constructors(), + sol::meta_function::to_string, + &FilePath::toUserOutput, + "fromUserInput", + &FilePath::fromUserInput, + "searchInPath", + [](const FilePath &self) { return self.searchInPath(); }, + "exists", + &FilePath::exists, + "resolveSymlinks", + &FilePath::resolveSymlinks, + "isExecutableFile", + &FilePath::isExecutableFile, + "isDir", + &FilePath::isDir, + "nativePath", + &FilePath::nativePath, + "toUserOutput", + &FilePath::toUserOutput, + "fileName", + &FilePath::fileName, + "currentWorkingPath", + &FilePath::currentWorkingPath, + "parentDir", + &FilePath::parentDir, + "resolvePath", + sol::overload( + [](const FilePath &p, const QString &path) { return p.resolvePath(path); }, + [](const FilePath &p, const FilePath &path) { return p.resolvePath(path); })); + + utils["FilePath"]["dirEntries_cb"] = utils["__dirEntries_cb__"]; + utils["FilePath"]["dirEntries"] = wrap(utils["__dirEntries_cb__"]); + + return utils; + }); } } // namespace Lua::Internal diff --git a/src/plugins/lua/meta/utils.lua b/src/plugins/lua/meta/utils.lua index c3a0c301596..01d291c5789 100644 --- a/src/plugins/lua/meta/utils.lua +++ b/src/plugins/lua/meta/utils.lua @@ -28,7 +28,7 @@ function utils.FilePath:searchInPath() end ---@field fileFilters? integer The filters to use (combination of QDir.Filters.*), defaults to QDir.Filters.NoFilter ---@field flags? integer The iterator flags (combination of QDirIterator.Flags.*), defaults to QDirIterator.Flags.NoIteratorFlags ----Returns all entries in the directory +---Returns all entries in the directory. Call `a.wait` on the returned value to get the result. ---@param options DirEntriesOptions ---@return FilePath[] function utils.FilePath:dirEntries(options) end