Lua: Make FilePath:dirEntries async

Change-Id: I0d1a918a34ca1fefe1dffdf4c5d766e6bb7aaf77
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Marcus Tillmanns
2024-05-02 11:41:06 +02:00
parent 218f07bdef
commit adcea41617
2 changed files with 101 additions and 87 deletions

View File

@@ -4,6 +4,8 @@
#include "../luaengine.h"
#include "../luaqttypes.h"
#include <utils/async.h>
#include <utils/futuresynchronizer.h>
#include <utils/hostosinfo.h>
#include <QTimer>
@@ -14,36 +16,62 @@ namespace Lua::Internal {
void addUtilsModule()
{
LuaEngine::registerProvider("__utils", [](sol::state_view lua) -> sol::object {
LuaEngine::registerProvider(
"Utils",
[futureSync = Utils::FutureSynchronizer()](sol::state_view lua) mutable -> sol::object {
auto async = lua.script("return require('async')", "_utils_").get<sol::table>();
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, timer, [cb, timer]() {
QObject::connect(timer, &QTimer::timeout, &LuaEngine::instance(), [cb, timer]() {
cb();
timer->deleteLater();
});
timer->start();
});
return utils;
auto dirEntries_cb = [&futureSync](
const FilePath &p,
const sol::table &options,
const sol::function &cb) {
const QStringList nameFilters = options.get_or<QStringList>("nameFilters", {});
QDir::Filters fileFilters
= (QDir::Filters) options.get_or<int>("fileFilters", QDir::NoFilter);
QDirIterator::IteratorFlags flags
= (QDirIterator::IteratorFlags)
options.get_or<int>("flags", QDirIterator::NoIteratorFlags);
FileFilter filter(nameFilters, fileFilters, flags);
QFuture<FilePath> future = Utils::asyncRun([p, filter](QPromise<FilePath> &promise) {
p.iterateDirectory(
[&promise](const FilePath &item) {
if (promise.isCanceled())
return IterationPolicy::Stop;
promise.addResult(item);
return IterationPolicy::Continue;
},
filter);
});
LuaEngine::registerProvider("Utils", [](sol::state_view lua) -> sol::object {
sol::table utils = lua.script(
R"(
local u = require("__utils")
local a = require("async")
futureSync.addFuture<FilePath>(future);
return {
waitms_cb = u.waitms_cb,
waitms = a.wrap(u.waitms_cb)
}
)",
"_utils_")
.get<sol::table>();
Utils::onFinished<FilePath>(
future, &LuaEngine::instance(), [cb](const QFuture<FilePath> &future) {
cb(future.results());
});
};
utils.set_function("__dirEntries_cb__", dirEntries_cb);
sol::function wrap = async["wrap"].get<sol::function>();
utils["waitms"] = wrap(utils["waitms_cb"]);
auto hostOsInfoType = utils.new_usertype<HostOsInfo>("HostOsInfo");
hostOsInfoType["isWindowsHost"] = &HostOsInfo::isWindowsHost;
@@ -60,10 +88,12 @@ return {
return "unknown";
}());
auto filePathType = utils.new_usertype<FilePath>(
sol::usertype<FilePath> filePathType = utils.new_usertype<FilePath>(
"FilePath",
sol::call_constructor,
sol::constructors<FilePath()>(),
sol::meta_function::to_string,
&FilePath::toUserOutput,
"fromUserInput",
&FilePath::fromUserInput,
"searchInPath",
@@ -74,27 +104,8 @@ return {
&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();
const QStringList nameFilters = options.get_or<QStringList>("nameFilters", {});
QDir::Filters fileFilters
= (QDir::Filters) options.get_or<int>("fileFilters", QDir::NoFilter);
QDirIterator::IteratorFlags flags
= (QDirIterator::IteratorFlags)
options.get_or<int>("flags", QDirIterator::NoIteratorFlags);
FileFilter filter(nameFilters);
p.iterateDirectory(
[&result](const FilePath &item) {
result.add(item);
return IterationPolicy::Continue;
},
FileFilter(nameFilters, fileFilters, flags));
return result;
},
"isDir",
&FilePath::isDir,
"nativePath",
&FilePath::nativePath,
"toUserOutput",
@@ -110,6 +121,9 @@ return {
[](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;
});
}

View File

@@ -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