Plugins Lua中插件框架的API

Plugins Lua中插件框架的API,plugins,lua,Plugins,Lua,我正在为一个应用程序实现一个带有Lua脚本的插件系统。基本上,它允许用户通过在Lua中定义一个或多个函数来扩展功能。插件函数将被调用以响应应用程序事件 Lua中是否有一些好的开源插件框架可以作为模型 特别是,我想知道什么是将参数传递给插件并接收返回值的最佳方式,这种方式既灵活又易于插件编写者使用 我只是想澄清一下,我对API的设计感兴趣的是Lua中脚本编程的角度,而不是宿主应用程序的角度 任何其他与Lua插件系统设计相关的建议或最佳实践都将不胜感激。Lua的一流功能使这类事情变得如此简单,我认为

我正在为一个应用程序实现一个带有Lua脚本的插件系统。基本上,它允许用户通过在Lua中定义一个或多个函数来扩展功能。插件函数将被调用以响应应用程序事件

Lua中是否有一些好的开源插件框架可以作为模型

特别是,我想知道什么是将参数传递给插件并接收返回值的最佳方式,这种方式既灵活又易于插件编写者使用

我只是想澄清一下,我对API的设计感兴趣的是Lua中脚本编程的角度,而不是宿主应用程序的角度


任何其他与Lua插件系统设计相关的建议或最佳实践都将不胜感激。

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,
       ...
    }
    
  • 您还将看到,我建议所有插件操作使用相同的界面:

  • 插件的第一个参数是表本身
  • 唯一的另一个参数是包含操作所需的所有其他信息的表
  • 最后,每个操作都应该返回一个结果表
  • 传递和返回单个表而不是位置结果的原因是,它将帮助您在接口发展时保持代码兼容

总之,积极使用表和一流函数,并保护插件的私有状态

插件函数将被调用以响应应用程序事件

这表明了观察者的模式。例如,如果您的应用程序有两个事件“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)
扩展以满足您的需要

我特别想知道,将参数传递给插件并接收返回值的最佳方法是什么


该插件只是为您提供了一个要调用的函数。您可以将任何想要的参数传递给它,并按照自己的意愿处理它的返回值。

对于脚本编写者来说,更简单的界面可能更容易。例如,只需要脚本编写者提供say
enter
exit
walk
函数。对未提供的函数使用默认值。在加载每个脚本之后,在运行它们之前,设置一个合适的环境。谢谢Norman。这是一个非常笼统的问题,但你的答案正是我想要的。@lhf我还认为一个更简单的界面对用户来说会更容易。我将接受关于将参数作为表传递的建议,但是让用户只定义一些函数并设置默认的no-op。顺便说一句,谢谢您的Lua,做得很好。:)