Page 2 of 6

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Mon 25 Feb, 2013 21:17
by John Doe

Latest post of the previous page:

John Doe wrote:Просьба прокомментировать.
Какие могут быть недостатки, как можно улучшить.

Пока вижу это:
1. Проверять наличие плагина
2. Обрабатывать переменное количество параметров

Code: Select all

function Plugin.require(id)
  if not Plugin.Exist(id) then return nil, "not exist plugin with guid '"..id.."'" end
  local NameSpace={}
  NameSpace.mt={}
  setmetatable(NameSpace, NameSpace.mt)
  NameSpace.mt.__index=
    function(table,key)
      return function(...)
               return Plugin.Call(id, key, ...)
             end
    end
  return NameSpace
end
Использовать так:

Code: Select all

ConCtrl,x=Plugin.require("94624B7B-FFDB-435F-B955-F99DBBC3BFE0")
if not ConCtrl then error(x) end
x,y=ConCtrl.BufferSize()
P.S.
Разместил функцию в глобальной таблице Plugin

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Mon 25 Feb, 2013 22:48
by John Doe
Думаю как лучше добавить сюда обработку Plugin.Config и Plugin.Menu.
Вероятно для них придётся зарезервировать ключи "_Сonfig", "_Menu".
Плюс ещё один ключ может потребоваться получении гуида плагина - "_id"

Ещё надо подумать о случае, когда плагин не имеет именованого ключа.
Т.е. вызывается примерно так: Plugin.Call(guid, n1, n2, n3).
Для этого нужно тоже зарезервировать какой-то ключ, например "_main".

Как-то не слишком всё красиво выходит...
Поправьте пока не поздно, а то я вам напридумываю велосипедов.

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Mon 25 Feb, 2013 22:55
by Shmuel
Оптимизировал немного requirePlugin (название не очень удачное, по-моему).

Code: Select all

function requirePlugin(id)
  local mt = {}
  local NameSpace = setmetatable({}, mt)
  mt.__index=function(table,key)
      NameSpace[key] = function(...) return Plugin.Call(id,key,...) end
      return NameSpace[key]
    end
  return NameSpace
end

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Mon 25 Feb, 2013 23:03
by John Doe
Спасибо за оптимизацию!
Shmuel wrote:(название не очень удачное, по-моему).
По аналогии со стандартным require.
В прошлом сообщении я предложил поместить require в таблицу Plugin.
Если есть более удачные идеи - welcome.

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Tue 26 Feb, 2013 00:36
by John Doe
Очередной вариант:
Позволяет всё это:

Code: Select all

x,y=ConCtrl.BufferSize()         --равнозначно
x,y=ConCtrl._Call("BufferSize")  --равнозначно
ConCtrl._Menu()
ConCtrl._Config()
msgbox(ConCtrl._id) --может понадобиться для конструкции типа if Dlg.Owner==ConCtrl._id

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Tue 26 Feb, 2013 01:02
by John Doe
Эти подчёркивания мне не нравятся, вероятно нужен какой-то отдельный способ вызова Plugin.*
Пока просто убрал подчёркивания:

Code: Select all

  NameSpace.Id = id
  for _,f in ipairs{"Call","Command","Config","Exist","Menu"} do
    NameSpace[f] = function(...) return Plugin[f](id, ...) end
  end
Если вдруг надо понадобиться действительно передать эти значения в Plugin.Call - можно воспользоваться <NameSpace>.Call
Полный текст:
Возможности:

Code: Select all

ConCtrl=Plugin.require("94624B7B-FFDB-435F-B955-F99DBBC3BFE0")
if not ConCtrl.Exist() then error("not exist plugin with guid '" ..ConCtrl.Id.. "'") end
msgbox(ConCtrl.Id)   -- может также понадобиться для конструкции типа if Dlg.Owner==ConCtrl.Id
x,y = ConCtrl.BufferSize()         --равнозначно
x,y = ConCtrl.Call("BufferSize")   --равнозначно
ConCtrl.Menu()         --Plugin.Menu()
ConCtrl.Call("Menu")   --Plugin.Call("Menu")
ConCtrl.Config()
ConCtrl.Command("/Scale=4 /Load=DOS.PLT")

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 01:36
by John Doe
Так, в предыдущем сообщении видимо изобретён велосипед.
Хотелось бы вызывать Call/Cmdline/Config/Menu как "методы", через двоеточие: ConCtrl:Menu()
Надо разбираться с ооп...

Re: Spring — внедрение Lua в качестве макроязыка

Posted: Tue 26 Feb, 2013 10:53
by Shmuel
John Doe wrote:

Code: Select all

function Plugin.require(id)
  if not Plugin.Exist(id) then return nil, "not exist plugin with guid '" ..id.. "'" end
  ......
end
Так делать не надо.
Во-первых, на момент вызова Plugin.require плагин id может быть не загружен, но быть загружен позднее.
Во-вторых, на момент вызова Plugin.require плагин id может быть загружен, но быть выгружен позднее.

Вместо этого можно сделать поле-функцию NameSpace.Exist.

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 11:00
by John Doe
Отредактировал в прошлом сообщении.

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 11:49
by Smitis
Маленькая придирка :) - может лучше require с большой буквы, как и остальные функции в Plugin?

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 12:31
by John Doe
Как-бы специально с маленькой, чтобы подчеркнуть отличия :-)
Но это не имеет значения.

Давайте лучше большие придирки.
В конечном счёте хочется чтобы что-то подобное было "из коробки", в составе LuaMacro.
Тогда мы автоматически получим удобные интерфейсы для всех плагинов.

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 12:39
by Max Rusov
John Doe wrote:Тогда мы автоматически получим удобные интерфейсы для всех плагинов.
Для Plugin.Call тут слишком много допущений.
1. Что первым аргументом идет "имя функции"
2. Что "имя функции" строковое
3. Что все аргументы передаются отдельно (а не кодируются в строку)

IMHO, lua-интерфейс к плагину должен поставляться вместе с плагином, т.к. только автору плагина известны все эти тонкости...

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 12:45
by John Doe
Имхо это как раз вообще не проблема.
С плагином идёт документация, и там будет указано КАК использовать.

И автор плагина уже сам решит, как ему удобно.
Функция задана числом: ConCtrl.Call(a,b,c) или ConCtrl[a](b,c)
Всё кодируется в строку - ConCtrl.Call(S)

Думаю не надо объяснять, что при наличии Plugin.require в поставке - плагинописатель способен сделать верный выбор.

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 12:57
by Max Rusov
John Doe wrote:Всё кодируется в строку - ConCtrl.Call(S)
Ну так это неудобно. Wrapper бы мог это сам делать.
Вот, например, у плагина EdtFind есть много возможностей вызова через Plugin.Call:

Code: Select all

Plugin.Call(EdtFind, "Find:ИскомаяСтрока Replace:СтрокаЗамены Prompt:0")
А интерфейс хотелось бы:

Code: Select all

EdtFind.Replace(ИскомаяСтрока, СтрокаЗамены, Справшивать)
Конечно, надо бы в плагине программный интерфейс переделать, с учетом новых возможностей... Но все равно не факт, что wrapper всегда только перевызов.

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 13:01
by John Doe
Max Rusov wrote:Ну так это неудобно. Wrapper бы мог это сам делать.
Это всё равно удобнее чем сейчас.
А чтобы стало вообще удобно - автор плагина может переделать интерфейс, если сочтёт нужным.

Враппер как ни крути мысли читать не может.
Даже если сделать в нём разбор строки.

Re: Plugin.require — функция-враппер на замену Plugin.Call и

Posted: Tue 26 Feb, 2013 13:07
by John Doe
Вот беру первый попавшийся пример.
Как было:

Code: Select all

OpenType = 1
ConEmu = "4b675d80-1d4a-4ea9-8436-fdc23f2fc14b"
callplugin(ConEmu,OpenType)
Как будет (автоматически, без изменений в ConEmu):

Code: Select all

ConEmu = Plugin.require("4b675d80-1d4a-4ea9-8436-fdc23f2fc14b")
OpenType=1
ConEmu[OpenType]()
Не супер, но уже лучше

А если автор ConEmu сочтёт нужным, то сделает и так:

Code: Select all

ConEmu = Plugin.require("4b675d80-1d4a-4ea9-8436-fdc23f2fc14b")
ConEmu.OpenType()