我正在为应用程序实现一个带Lua脚本的插件系统。基本上,它将允许用户通过在Lua中定义一个或多个函数来扩展功能。将调用插件函数以响应应用程序事件。
Lua中是否有一些可以作为模型的良好开源插件框架?
特别是我想知道将参数传递给插件并接收返回值的最佳方法是什么,这种方式既灵活又易于插件编写者使用。
为了澄清一点,我从Lua脚本编程的角度来看,我对API的设计很感兴趣,而不是从托管应用程序的角度来看。
与Lua插件系统设计相关的任何其他建议或最佳实践将不胜感激。
答案 0 :(得分:4)
Lua的一流功能使这种事情变得如此简单,以至于我认为你不会在框架方面找到太多东西。请记住,Lua的口头禅是提供最小的机制,让个别程序员为自己制定政策。
您的问题很一般,但我建议您使用API:
单个插件应该由单个Lua表表示(就像Lua模块由单个表表示一样)。
表格的字段应包含表格的操作或回调。
共享状态应该不存储在表中;它应该存储在创建表的代码的局部变量中,例如,
local initialized = false
return {
init = function(self, t) ... ; initialized = true end,
something_else = function (self, t)
if not initialized then error(...) end
...
end,
...
}
您还会看到我建议所有插件操作都使用相同的界面:
传递和返回单个表而不是位置结果的原因是,它将帮助您在接口发展时保持代码兼容。
总之,积极使用表格和一流功能,保护插件的私有状态。
答案 1 :(得分:2)
将响应应用程序事件调用插件函数。
这表明了观察者的模式。例如,如果您的应用有两个事件,'foo'和'bar',您可以编写如下内容:
HostApp.listeners = {
foo = {},
bar = {},
}
function HostApp:addListener(event, listener)
table.insert(self.listeners[event], listener)
end
function HostApp:notifyListeners(event, ...)
for _,listener in pairs(self.listeners[event]) do
listener(...)
end
end
然后当foo
事件发生时:
self:notifyListeners('foo', 'apple', 'donut')
对foo
事件感兴趣的客户端(例如插件)只会注册一个监听器:
HostApp:addListener('foo', function(...)
print('foo happened!', ...)
end)
扩展以满足您的需求。
特别是我想知道将参数传递给插件并接收返回值的最佳方法是什么
该插件只是为您提供了一个调用函数。您可以传递任何您想要的参数,并根据需要处理它的返回值。