forked from qt-creator/qt-creator
Lua: Guard Hook connections
Change-Id: Id30c75093879b92321af864273c6d4ef390cf71a Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -12,20 +12,24 @@ namespace Internal {
|
|||||||
|
|
||||||
void addHookModule()
|
void addHookModule()
|
||||||
{
|
{
|
||||||
LuaEngine::registerHook("editors.documentOpened", [](const sol::protected_function &func) {
|
LuaEngine::registerHook(
|
||||||
|
"editors.documentOpened", [](const sol::protected_function &func, QObject *guard) {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
Core::EditorManager::instance(),
|
Core::EditorManager::instance(),
|
||||||
&Core::EditorManager::documentOpened,
|
&Core::EditorManager::documentOpened,
|
||||||
|
guard,
|
||||||
[func](Core::IDocument *document) {
|
[func](Core::IDocument *document) {
|
||||||
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
||||||
QTC_CHECK_EXPECTED(res);
|
QTC_CHECK_EXPECTED(res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
LuaEngine::registerHook("editors.documentClosed", [](const sol::protected_function &func) {
|
LuaEngine::registerHook(
|
||||||
|
"editors.documentClosed", [](const sol::protected_function &func, QObject *guard) {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
Core::EditorManager::instance(),
|
Core::EditorManager::instance(),
|
||||||
&Core::EditorManager::documentClosed,
|
&Core::EditorManager::documentClosed,
|
||||||
|
guard,
|
||||||
[func](Core::IDocument *document) {
|
[func](Core::IDocument *document) {
|
||||||
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
||||||
QTC_CHECK_EXPECTED(res);
|
QTC_CHECK_EXPECTED(res);
|
||||||
|
|||||||
@@ -117,30 +117,33 @@ void addTextDocumentsModule()
|
|||||||
return documents;
|
return documents;
|
||||||
});
|
});
|
||||||
|
|
||||||
LuaEngine::registerHook("editors.text.opened", [](sol::function func) {
|
LuaEngine::registerHook("editors.text.opened", [](sol::function func, QObject *guard) {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
TextDocumentRegistry::instance(),
|
TextDocumentRegistry::instance(),
|
||||||
&TextDocumentRegistry::documentOpened,
|
&TextDocumentRegistry::documentOpened,
|
||||||
|
guard,
|
||||||
[func](TextEditor::TextDocument *document) {
|
[func](TextEditor::TextDocument *document) {
|
||||||
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
||||||
QTC_CHECK_EXPECTED(res);
|
QTC_CHECK_EXPECTED(res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
LuaEngine::registerHook("editors.text.closed", [](sol::function func) {
|
LuaEngine::registerHook("editors.text.closed", [](sol::function func, QObject *guard) {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
TextDocumentRegistry::instance(),
|
TextDocumentRegistry::instance(),
|
||||||
&TextDocumentRegistry::documentClosed,
|
&TextDocumentRegistry::documentClosed,
|
||||||
|
guard,
|
||||||
[func](TextEditor::TextDocument *document) {
|
[func](TextEditor::TextDocument *document) {
|
||||||
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
||||||
QTC_CHECK_EXPECTED(res);
|
QTC_CHECK_EXPECTED(res);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
LuaEngine::registerHook("editors.text.contentsChanged", [](sol::function func) {
|
LuaEngine::registerHook("editors.text.contentsChanged", [](sol::function func, QObject *guard) {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
TextDocumentRegistry::instance(),
|
TextDocumentRegistry::instance(),
|
||||||
&TextDocumentRegistry::documentContentsChanged,
|
&TextDocumentRegistry::documentContentsChanged,
|
||||||
|
guard,
|
||||||
[func](TextEditor::TextDocument *document, int position, int charsRemoved, int charsAdded) {
|
[func](TextEditor::TextDocument *document, int position, int charsRemoved, int charsAdded) {
|
||||||
Utils::expected_str<void> res
|
Utils::expected_str<void> res
|
||||||
= LuaEngine::void_safe_call(func, document, position, charsRemoved, charsAdded);
|
= LuaEngine::void_safe_call(func, document, position, charsRemoved, charsAdded);
|
||||||
@@ -148,10 +151,11 @@ void addTextDocumentsModule()
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
LuaEngine::registerHook("editors.text.currentChanged", [](sol::function func) {
|
LuaEngine::registerHook("editors.text.currentChanged", [](sol::function func, QObject *guard) {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
TextDocumentRegistry::instance(),
|
TextDocumentRegistry::instance(),
|
||||||
&TextDocumentRegistry::currentDocumentChanged,
|
&TextDocumentRegistry::currentDocumentChanged,
|
||||||
|
guard,
|
||||||
[func](TextEditor::TextDocument *document) {
|
[func](TextEditor::TextDocument *document) {
|
||||||
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
Utils::expected_str<void> res = LuaEngine::void_safe_call(func, document);
|
||||||
QTC_CHECK_EXPECTED(res);
|
QTC_CHECK_EXPECTED(res);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
QHash<QString, LuaEngine::PackageProvider> m_providers;
|
QHash<QString, LuaEngine::PackageProvider> m_providers;
|
||||||
QList<std::function<void(sol::state_view)>> m_autoProviders;
|
QList<std::function<void(sol::state_view)>> m_autoProviders;
|
||||||
|
|
||||||
QMap<QString, std::function<void(sol::function)>> m_hooks;
|
QMap<QString, std::function<void(sol::function, QObject *)>> m_hooks;
|
||||||
|
|
||||||
std::unique_ptr<LuaInterfaceImpl> m_luaInterface;
|
std::unique_ptr<LuaInterfaceImpl> m_luaInterface;
|
||||||
};
|
};
|
||||||
@@ -155,20 +155,22 @@ void LuaEngine::autoRegister(const std::function<void(sol::state_view)> ®iste
|
|||||||
instance().d->m_autoProviders.append(registerFunction);
|
instance().d->m_autoProviders.append(registerFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaEngine::registerHook(QString name, const std::function<void(sol::function)> &hook)
|
void LuaEngine::registerHook(
|
||||||
|
QString name, const std::function<void(sol::function, QObject *guard)> &hook)
|
||||||
{
|
{
|
||||||
instance().d->m_hooks.insert("." + name, hook);
|
instance().d->m_hooks.insert("." + name, hook);
|
||||||
}
|
}
|
||||||
|
|
||||||
expected_str<void> LuaEngine::connectHooks(
|
expected_str<void> LuaEngine::connectHooks(
|
||||||
sol::state_view lua, const sol::table &table, const QString &path)
|
sol::state_view lua, const sol::table &table, const QString &path, QObject *guard)
|
||||||
{
|
{
|
||||||
qCDebug(logLuaEngine) << "connectHooks called with path: " << path;
|
qCDebug(logLuaEngine) << "connectHooks called with path: " << path;
|
||||||
|
|
||||||
for (const auto &[k, v] : table) {
|
for (const auto &[k, v] : table) {
|
||||||
qCDebug(logLuaEngine) << "Processing key: " << k.as<QString>();
|
qCDebug(logLuaEngine) << "Processing key: " << k.as<QString>();
|
||||||
if (v.get_type() == sol::type::table) {
|
if (v.get_type() == sol::type::table) {
|
||||||
return connectHooks(lua, v.as<sol::table>(), QStringList{path, k.as<QString>()}.join("."));
|
return connectHooks(
|
||||||
|
lua, v.as<sol::table>(), QStringList{path, k.as<QString>()}.join("."), guard);
|
||||||
} else if (v.get_type() == sol::type::function) {
|
} else if (v.get_type() == sol::type::function) {
|
||||||
QString hookName = QStringList{path, k.as<QString>()}.join(".");
|
QString hookName = QStringList{path, k.as<QString>()}.join(".");
|
||||||
qCDebug(logLuaEngine) << "Connecting function to hook: " << hookName;
|
qCDebug(logLuaEngine) << "Connecting function to hook: " << hookName;
|
||||||
@@ -176,7 +178,7 @@ expected_str<void> LuaEngine::connectHooks(
|
|||||||
if (it == d->m_hooks.end())
|
if (it == d->m_hooks.end())
|
||||||
return make_unexpected(Tr::tr("No hook with the name \"%1\" found.").arg(hookName));
|
return make_unexpected(Tr::tr("No hook with the name \"%1\" found.").arg(hookName));
|
||||||
else
|
else
|
||||||
it.value()(v.as<sol::function>());
|
it.value()(v.as<sol::function>(), guard);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,8 +257,10 @@ expected_str<sol::protected_function> LuaEngine::prepareSetup(
|
|||||||
return self.name;
|
return self.name;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
lua["PluginSpec"]
|
auto guardObject = std::make_unique<QObject>();
|
||||||
= ScriptPluginSpec{pluginSpec.name(), appDataPath, std::make_unique<QObject>()};
|
auto guardObjectPtr = guardObject.get();
|
||||||
|
|
||||||
|
lua["PluginSpec"] = ScriptPluginSpec{pluginSpec.name(), appDataPath, std::move(guardObject)};
|
||||||
|
|
||||||
// TODO: only register what the plugin requested
|
// TODO: only register what the plugin requested
|
||||||
for (const auto &[name, func] : d->m_providers.asKeyValueRange()) {
|
for (const auto &[name, func] : d->m_providers.asKeyValueRange()) {
|
||||||
@@ -289,7 +293,7 @@ expected_str<sol::protected_function> LuaEngine::prepareSetup(
|
|||||||
|
|
||||||
qCDebug(logLuaEngine) << "Hooks table found: " << hookTable.has_value();
|
qCDebug(logLuaEngine) << "Hooks table found: " << hookTable.has_value();
|
||||||
if (hookTable) {
|
if (hookTable) {
|
||||||
auto connectResult = connectHooks(lua, *hookTable, {});
|
auto connectResult = connectHooks(lua, *hookTable, {}, guardObjectPtr);
|
||||||
if (!connectResult)
|
if (!connectResult)
|
||||||
return make_unexpected(connectResult.error());
|
return make_unexpected(connectResult.error());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ public:
|
|||||||
|
|
||||||
static void registerProvider(const QString &packageName, const PackageProvider &provider);
|
static void registerProvider(const QString &packageName, const PackageProvider &provider);
|
||||||
static void autoRegister(const std::function<void(sol::state_view)> ®isterFunction);
|
static void autoRegister(const std::function<void(sol::state_view)> ®isterFunction);
|
||||||
static void registerHook(QString name, const std::function<void(sol::function)> &hookProvider);
|
static void registerHook(
|
||||||
|
QString name, const std::function<void(sol::function, QObject *guard)> &hookProvider);
|
||||||
|
|
||||||
static bool isCoroutine(lua_State *state);
|
static bool isCoroutine(lua_State *state);
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
Utils::expected_str<void> connectHooks(
|
Utils::expected_str<void> connectHooks(
|
||||||
sol::state_view lua, const sol::table &table, const QString &path);
|
sol::state_view lua, const sol::table &table, const QString &path, QObject *guard);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<LuaEnginePrivate> d;
|
std::unique_ptr<LuaEnginePrivate> d;
|
||||||
|
|||||||
Reference in New Issue
Block a user