forked from qt-creator/qt-creator
Lua: Make OptionsPage safer
If the calling script does not keep a reference to the OptionsPage it will be garbage collected by Lua eventually. That can happen while the SettingsDialog is open, which cannot cope with a page being destroyed while its open. For now we just keep the OptionsPage alive until the plugin is unloaded. Change-Id: I8d0592731236482bbdc35078c24a5c6b962b1147 Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -286,9 +286,23 @@ sol::usertype<T> addTypedAspect(sol::table &lua, const QString &name)
|
|||||||
sol::bases<TypedAspect<typename T::valueType>, BaseAspect>());
|
sol::bases<TypedAspect<typename T::valueType>, BaseAspect>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ObjectPool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
mutable std::vector<std::shared_ptr<Core::IOptionsPage>> optionsPages;
|
||||||
|
|
||||||
|
template<class T, class... _Args>
|
||||||
|
std::shared_ptr<T> makePage(_Args &&...__args) const
|
||||||
|
{
|
||||||
|
auto page = std::make_shared<T>(std::forward<_Args>(__args)...);
|
||||||
|
optionsPages.push_back(page);
|
||||||
|
return page;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void setupSettingsModule()
|
void setupSettingsModule()
|
||||||
{
|
{
|
||||||
registerProvider("Settings", [](sol::state_view lua) -> sol::object {
|
registerProvider("Settings", [pool = ObjectPool()](sol::state_view lua) -> sol::object {
|
||||||
const ScriptPluginSpec *pluginSpec = lua.get<ScriptPluginSpec *>("PluginSpec");
|
const ScriptPluginSpec *pluginSpec = lua.get<ScriptPluginSpec *>("PluginSpec");
|
||||||
|
|
||||||
sol::table settings = lua.create_table();
|
sol::table settings = lua.create_table();
|
||||||
@@ -607,8 +621,8 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<OptionsPage>(
|
settings.new_usertype<OptionsPage>(
|
||||||
"OptionsPage",
|
"OptionsPage",
|
||||||
"create",
|
"create",
|
||||||
[pluginSpec](const sol::table &options) {
|
[&pool, pluginSpec](const sol::table &options) {
|
||||||
return std::make_unique<OptionsPage>(pluginSpec, options);
|
return pool.makePage<OptionsPage>(pluginSpec, options);
|
||||||
},
|
},
|
||||||
"show",
|
"show",
|
||||||
[](OptionsPage *page) { Core::ICore::showOptionsDialog(page->id()); });
|
[](OptionsPage *page) { Core::ICore::showOptionsDialog(page->id()); });
|
||||||
@@ -616,8 +630,8 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<ExtensionOptionsPage>(
|
settings.new_usertype<ExtensionOptionsPage>(
|
||||||
"ExtensionOptionsPage",
|
"ExtensionOptionsPage",
|
||||||
"create",
|
"create",
|
||||||
[pluginSpec](AspectContainer *container) {
|
[pluginSpec, &pool](AspectContainer *container) {
|
||||||
return std::make_unique<ExtensionOptionsPage>(pluginSpec, container);
|
return pool.makePage<ExtensionOptionsPage>(pluginSpec, container);
|
||||||
},
|
},
|
||||||
"show",
|
"show",
|
||||||
[](ExtensionOptionsPage *page) { Core::ICore::showOptionsDialog(page->id()); });
|
[](ExtensionOptionsPage *page) { Core::ICore::showOptionsDialog(page->id()); });
|
||||||
|
Reference in New Issue
Block a user