API для плагина фреймворка в Lua - PullRequest
6 голосов
/ 30 мая 2011

Я внедряю систему плагинов с Lua-скриптами для приложения.В основном это позволит пользователям расширить функциональность, определив одну или несколько функций в Lua.Функция плагина будет вызываться в ответ на событие приложения.

Есть ли в Lua несколько хороших платформ с открытым исходным кодом, которые могут служить моделью?

В частности, мне интересно, что лучшеспособ передачи параметров в плагин и получения возвращаемых значений, который является гибким и простым в использовании для авторов плагинов.

Просто чтобы прояснить, я заинтересован в разработке API изТочка зрения сценария программирования на Lua, а не с точки зрения хостинга приложения.

Будем благодарны за любые другие советы или лучшие практики, связанные с разработкой системы плагинов в Lua.

Ответы [ 2 ]

4 голосов
/ 31 мая 2011

Первоклассные функции 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. Единственным другим аргументом является таблица, содержащая всю другую информацию, необходимую для операции.
    3. Наконец, каждая операция должнавернуть таблицу результатов.

    Причиной передачи и возврата одной таблицы вместо результатов позиционирования является то, что она поможет вам поддерживать совместимость кода по мере развития интерфейсов.

Таким образом, агрессивно использует таблицы и первоклассные функции и защищает личное состояние вашего плагина .

2 голосов
/ 31 мая 2011

Функция плагина будет вызываться в ответ на событие приложения.

Это указывает на паттерн наблюдателя.Например, если в вашем приложении есть два события, «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)

Расширится в соответствии с вашими потребностями.

В частности, яИнтересно, как лучше всего передать параметры плагину и получить возвращенные значения

Плагин просто предлагает вам функцию для вызова.Вы можете передать ему любые параметры и обработать возвращаемые значения так, как пожелаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...