Description
I was toying with the idea of writing plugins in such a way so that they can be called by other plugins, aka plugin-as-a-library (not the best name, I know). At the moment this is just an idea and I haven't tried it out, but combined with the state management offered by finenv.RetainLuaState
, this could open up some interesting opportunities for interactions between plugins.
I came across a method for checking if a script is included as a library or whether it is the main script.
Using it in a plugin means the following is possible:
src/my_plugin.lua
-- True if this script is included as a library, false if it's the main script
local is_library = pcall(debug.getlocal, 4, 1)
...
-- plugin defining code
...
-- At the end of the file
if is_library then
-- As library
return dialog
else
-- As main script
dialog:ExecuteModal(nil)
end
If exposing the whole dialog object is not desirable (and I imagine it wouldn't be), we could have a factory for creating wrapping tables:
-- function finalemix.create_wrapper(object, exposed_methods)
if is_library then
return finalemix.create_wrapper(dialog, {'ExecuteModal', 'MyCustomFunction', 'MyOtherCustomFunction'})
end
And if control over preserving/refeshing state is needed, the plugin could return a create function, which then returns a dialog or a wrapper as desired. Then the calling plugin would be in control of when the plugin-as-a-library is retained or garbage collected.
Possible usage:
src/consuming_plugin.lua
-- my_plugin returns a create function when run as a library
local my_plugin = require('my_plugin')
...
-- plugin defining code
...
-- create a button that invokes my_plugin
-- to save some lines, named controls are taken from the dialog mixin I'm currently working on
dialog:CreateButton(10, 10, 'my_plugin_ctrl')
dialog:RegisterHandleControlEvent(dialog:GetControl('my_plugin_ctrl'), function(ctrl)
if not dialog.my_plugin then
dialog.my_plugin = my_plugin()
end
dialog.my_plugin.ExecuteModal(dialog)
-- Additional tasks or testing the return value can be done here as well
end)