far.Guids?

Здесь обсуждается всё, что касается макросов.
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

far.Guids?

Post by Shmuel »

Latest post of the previous page:

Smitis wrote: А не проще ли создать статическую таблицу всех распространённых плагинов?
Решение с метатаблицей очень простое, большей простоты не надо. И оно более универсальное, чем то, что вы предлагаете.
Вопрос только в том, нужно ли это из коробки или же кому надо сам себе поставит в _macroinit.lua.
User avatar
Smitis
Posts: 1709
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 23 times
Been thanked: 55 times

far.Guids?

Post by Smitis »

Shmuel wrote:Решение с метатаблицей очень простое, большей простоты не надо. И оно более универсальное, чем то, что вы предлагаете.
Вопрос только в том, нужно ли это из коробки или же кому надо сам себе поставит в _macroinit.lua.
Не уверен на счёт универсальности. Если кому-то нужно для себя лично, достаточно macroinit. Если предполагается использование в публичных макросах, тогда надо делать доступным для всех. Но тогда мы приходим к
Shmuel wrote:Но вижу и недостатки, главный из которых, что, если предположить, что пользоваться будет каждый десятый, то 9 пользователей из 10 заплатят 16мс ни за что. 16 мс это конечно ерунда, но эти вещи имеют свойство накапливаться (обратный вариант пословицы "копейка рубль бережёт").
Предложение: делать модулем, только модуль должен быть в дистрибутиве, например, завести папку modules в папке плагина LuaMacro, поместить путь в package.path. Пока там будет только один модуль, но глядишь, ещё появятся.
Разум когда-нибудь победит.
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

far.Guids?

Post by Shmuel »

Smitis wrote:Но тогда мы приходим к
Shmuel wrote:Но вижу и недостатки, главный из которых, что, если предположить, что пользоваться будет каждый десятый, то 9 пользователей из 10 заплатят 16мс ни за что.
В варианте с метатаблицей платит (16 ms или сколько там получится) только тот, кто пользуется.
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

far.Guids?

Post by IgorZ »

Shmuel wrote:1. Это лишнее: if not rawget(tbl,idx) then -- плагина с таким именем нет в таблице?
Возможно, я не до конца понимаю суть метатаблиц? В моём понимании, функция _ind заменяет собой стандартный обработчик обращения к элементу таблицы по индексу (а rawgtet(tbl,idx) и есть стандартный обработчик). То есть, она исполняется каждый раз, когда кто-то пишет tbl[idx]. Но тогда и цикл должен исполняться при каждом таком обращении.
Проверил. Действительно, при комментировании условия всё равно задержка в 15-20мс происходит только при первом обращении после перезагрузки. И чего именно я не знаю?
Shmuel wrote:2. В отличие от диалогов/меню самого Far, здесь нет гарантии, что 2 или больше плагина не имеют одинаковый Title, например, Calendar или HexEditor и т.д. В этом случае по имени будет доступен только один из них.
Ну, теоретически, могут совпасть и 2 uid-а у разных плагинов (даже если не учитывать теорию вероятности, достаточно недобросовестного плагинописателя или какого-то любителя красивых цифр). А добросовестный автор постарается придумать уникальный Title по умолчанию. Так что с практической точки зрения, на мой взгляд, не страшно. Но если надо, могу попробовать добавить автоматическую дописывалку к названию суффиксов, к примеру, "_2", "_3" и т. д.
Shmuel
Posts: 6819
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 41 times
Been thanked: 528 times

far.Guids?

Post by Shmuel »

IgorZ wrote: И чего именно я не знаю?
Метаметод __index вызывается только если элемент с данным ключом в таблице отсутствует, поэтому дополнительная проверка внутри метаметода является излишней.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

far.Guids?

Post by John Doe »

IgorZ wrote: Но если надо, могу попробовать добавить автоматическую дописывалку к названию суффиксов, к примеру, "_2", "_3" и т. д.
Точно не стоит.
IgorZ wrote: А добросовестный автор постарается придумать уникальный Title по умолчанию.
Вероятность того, что у одного пользователя окажется установленным два плагина с одним именем, и к обоим он захочет обратиться через far.Guids невелика, и при необходимости может разрешится пользователем самостоятельно: прямым указанием гуида.

И всё же я не уверен в полезности этой функции "из коробки". Предвижу неочевидные последствия, навроде наивных попыток использовать таблицу гуидов как источник перечисления плагинов, и т.п.
IgorZ
Posts: 790
Joined: Wed 13 Jul, 2011 03:32
Has thanked: 15 times
Been thanked: 93 times

far.Guids?

Post by IgorZ »

Я тут среди своих залежей всякого разного нашёл когда-то скачанный Plugin.require авторства, если не ошибаюсь, JohnDoe. И скрестил со своим предложением. Вот что получилось:
  1. local function _ind(tbl,idx) -- таблица плагина
  2.  
  3. --
  4.  
  5. local function _fun(tbl,name) -- нестандартная функция плагина
  6.  
  7. local callfun,callname -- имя функции и вызывающая функция (синхронная/асинхронная)
  8.  
  9. if name:sub(1,4)=="Sync" then callfun,callname = "SyncCall",name:sub(5) else callfun,callname = "Call",name end
  10.  
  11. tbl[name] = function(...) return Plugin[callfun](tbl.Id,callname, ...) end -- добавим функцию в таблицу
  12.  
  13. return rawget(tbl,name) -- вернём функцию
  14.  
  15. end
  16.  
  17. --
  18.  
  19. for _,p in ipairs(far.GetPlugins()) do -- переберём все плагины
  20.  
  21.   local Info = far.GetPluginInformation(p).GInfo -- информация о плагине
  22.  
  23.   local guid = win.Uuid(Info.Guid) -- guid плагина
  24.  
  25.   tbl[Info.Title] = setmetatable({ -- таблица
  26.  
  27.     Id = guid:upper(), -- guid
  28.  
  29.     Call = function(...) return Plugin.Call(guid,...) end, -- стандартные функции
  30.  
  31.     Command = function(...) return Plugin.Command(guid,...) end,
  32.  
  33.     Config = function(...) return Plugin.Config(guid,...) end,
  34.  
  35.     Exist = function(...) return Plugin.Exist(guid,...) end,
  36.  
  37.     Menu = function(...) return Plugin.Menu(guid,...) end,
  38.  
  39.     SyncCall = function(...) return Plugin.SyncCall(guid,...) end},{__index=_fun}) -- обработаем обращение к нестандартной функции
  40.  
  41. end
  42.  
  43. return rawget(tbl,idx) -- вернём плагин (или nil, если такого нет)
  44.  
  45. end
  46.  
  47. far.Guids.Plugins = setmetatable({}, {__index=_ind}) -- таблица guid-ов плагинов
Теперь можно писать следующее:
  1. local ConCtrl=far.Guids.Plugins["Console Control"]
  2.  
  3.  
  4.  
  5. if not ConCtrl.Exist() then
  6.  
  7.   error("not exist plugin with guid '" ..(ConCtrl.Id or "nil").. "'")
  8.  
  9. end
  10.  
  11. -- для асинхронного вызова
  12.  
  13. local x,y = ConCtrl.BufferSize()
  14.  
  15. -- или для синхронного вызова
  16.  
  17. local x,y = ConCtrl.SyncBufferSize()
Хотя это уже не только guid-ы, так что насчёт месторасположения таблицы возможны различные мнения.
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

far.Guids?

Post by John Doe »

IgorZ wrote: авторства, если не ошибаюсь, JohnDoe.
Было дело. Но с тех пор я ещё поразмышлял над эффективностью, и в частности об использовании памяти.
Post Reply

Return to “Обсуждение макросов”