Page 1 of 5

ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 10:41
by Skirda
Крайне эксперементальный пока неофициальный билд: http://skirda-file.googlecode.com/files/mfunc.1.rar по мотивам Bug:446.
Смысл: уточнить новое АПИ.

В архиве Far и тестовый плагин Macro.Math (позволяет использовать в макросах математические функции - в хелпе описаны).
Чтобы функции math.sin, math.sqrt, etc заработали в макросах, необходимо стартануться Far, вызвать настройки плагина, жмакнуть Install, перезапустить Far. Команда Install пропишет в раздел KeyMacro\Funcs поддерживаемые функции, которые компилятор будет знать и уметь.

Например, команда

Code: Select all

macro:post print(math.format("%.4f",math.pow(math.pi(),2)))
напечатает 9.8696

Чуть позже (сейчас напряг со временем) напишу здесь поэму про "как", "что", "зачем" и "почему".
А сейчас пока поиграйтесь :)

ПыСы. в архиве есть plugin.hpp - относится к "крайенэксперементальному", все может и будет меняться (в части Macro API)! Так что делайте выводы.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 11:49
by NightRoman
А саму идею-то можно обсуждать? Идея - просто великолепная, и чего-то подобного я жду уже давно. Вызовы из макросов через меню плагинов это далеко не всегда хорошо: это и медленно (хоть жить и можно с этим), это и загромождение меню (а вот это уже реально плохо, что UI забит тем, что фактически для макросов предназначено).

Но вот реализация подхода вызывает у меня вопросы...

Необходимость регистрации этих макро-фунок сомнительна. Никак без регистрации нельзя обойтись?

Допустим, что уже хорошо подумали и, увы, нельзя. Хорошо. Плохо, что плагин (и даже пользователь) должен об этом заботится, а не Фар. Даже если этого избежать нельзя, надо плагинам тогда предоставить максимум поддержки в этом деле от Фара. Надо, чтобы ньюансы регистрации знал только Фар, плагины ничего не должны знать про реестр и прочие детали. Это и меньше работы плагинописателям, это и меньше ошибок и проблем у всех.

Зачем усложнять подход, вводя сигнатуры фунок? Я бы предложил единую и проверенную сигнатуру, как у сишной main. Просто, понятно и универсально. Опять же поддерживает переменное число аргументов, что есть хорошо и гибко на предмет расширения функциональности без изменения сигнатуры. Макро парсер сам посчитает число аргументов при парсинге, поместит их в массив и т.п. и укажет количество argc при вызове и массив агрументов argv.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 12:21
by Max Rusov
Еще вопрос, о синхронности подобного вызова. Допустим, плагин зарегистрировал функцию, по которой открывает диалог. Макрос "затормозится" до закрытия диалога? Или продолжится исполняться уже в контексте диалога? Или так вообще нельзя?

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 12:25
by NightRoman
По большому счету для вызова из макросов одной функции на плагин было бы и достаточно:
int ProcessMacroFuncW(int argc, char** argv)
(синтаксис можно и усложнить, но лишь бы он был единым)

Сколько всего она реально предоставляет, это уже дело плагина и описания в документации. Она пропарсит аргументы и вызовет, что надо. И вызов из макросов имел бы единый синтакс, в котором должны быть обозначены 3 вещи:
1) функция вызова функции плагина
2) ID плагина тем или иным способом
3) опциональный список строковых аргуметов любой длины

Наивный пример:
Callplugin(“plugin-ID-or-name-or-etc”, “Hello”, “42”)

Регистрировать ничего не надо – сигнатура известна, имя експортируетмой функции известно (ProcessMacroFuncW). Остается дело за “plugin-ID-or-name-or-etc” разве что.

Кто возразит, что такой вызов будет более громоздким, будет прав. Но если подумать, то ведь не так часто этим надо пользоваться. А бонусом будет простота внутренней реализации (меньше проблем), единый синтаксис вызова и отсутствие необходимости для пользователя и плагинописателей заботится о регистрации, переносе настроек с регистрацией и т.п.

P.S. Прошу меня извинить за возможно преждевременную критику. Закладывается предположительно долгосрочный, перспективный и очень важный функционал. Лишний раз подумать, посмотреть на все с еще одной-другой стороны всяко не помешает.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 13:16
by Shmuel
NightRoman wrote:По большому счету для вызова из макросов одной функции на плагин было бы и достаточно:
int ProcessMacroFuncW(int argc, char** argv)
(синтаксис можно и усложнить, но лишь бы он был единым)
С данной сигнатурой вполне можно вызывать и несколько функций на плагин (имя функции - в начальном параметре). Что немного смущает - это слабые возможности в смысле возвращаемого значения (целое число). Иногда бывает надо возвратить стринг, иногда - число с плавающей точкой.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 13:31
by Max Rusov
Не, это убого. Громоздкий синтаксис, ограниченный набор параметров, невозможна валидация в момент разбора макроса. То как сделано - гораздо лучше. Надеюсь, в будущем никаких "ручных" действий по "инсталляции" не потребуется - ведь плагины "саморегистрируются" прозрачно для пользователя, тут возможно то же самое.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 13:42
by NightRoman
Max Rusov wrote:Надеюсь, в будущем никаких "ручных" действий по "инсталляции" не потребуется.
Ну если это будет действительно так, то и с теперешним подходом можно жить. Но регистрация сигнатур мне не нравится все равно - что-то тут перемудрено.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 13:43
by Skirda
Уф... торопышки...

Я выкатил не готовое решение (над идеей которого, если память не изменяет, трудилось 2 чела), а рабочий концепт, на основе которого можно понять, про что идет речь в Mantis#446.

Вариант в стиле main() сразу отметаем (если речь про char** и еже с ним), т.к. в этом случае мы занимаемся двойной работой - Far конвертит что-то в строку и плагин делает это обратно - из строки в чёй-то.

Что касается регистрации функций, то т.к. это концепт, то и реализация у него соответствующая - быстро и просто.

Здесь (дальнейшие тесты) будет примерно так.
Раз плагины загружаются до макросов, то Far сможет вызывать сабж с первым параметром NULL, для того, чтобы плагин "отметился" (минимально - указать имя функции и количество параметров) - в противном случае компилятор не сможет отпрасить очередной макрос (у которого, например, встретится "%c=math.cos(%d)"). Ну вот такой у нас парсер, кому не нравится - Wелкам, "бизонистов" я уже безуспешно приглашал.

Я указал "отметился" - это как раз про то, что плагин не будет "гадить" в реестр (и ФАР туда же не будет писать инфу про эти функции - все в памяти, на текущий сеанс).

И тут вопрос.
Сейчас ОНО бегает по всем плагинам, имеющим сабж и как только кто-то откликнулся, "беготня" прекращается... (по аналогии с некоторыми эксп.функциями).
Нужно ли делать так, чтобы фар обращался только к тому плагину, который "умеет" функцию (т.е. т.н. namespace)?

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 13:45
by Max Rusov
Я думаю, это как с кэшем плагинов. Чтобы можно было парсить макросы, не загружая сами плагины. В принципе, разумно. Гораздо лучше чем грузить все плагины вместе с FAR'ом при запуске, правда ведь?

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 13:54
by Max Rusov
Может я что-то не понимаю, но зачем парсить макросы при запуске FAR? Разве нельзя парсить макрос при вызове - только тот, который вызывается?

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 13:59
by Skirda
макросы загружаются _все_ и при старте ФАРа.
в процессе загрузки они компилятся в некое внутреннее представление и помещаются в "библиотеку"
при вызове компиленный код макроса помещается в рабочую область из библиотеки и запускается.
после отработки рабочая область освобождается.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 14:02
by NightRoman
Skirda
Ну вот раз такой парсер, и никуда не деться, то я и говорю, что может единую сигнатуру использовать лучше будет. Тогда парсинг макроса будет чисто формальный. А то, что часть работы по парсингу при вызове перекладывается на плагин - я не вижу особой проблемы. Зато с плагина и с движка снимается задача регистрации сигнатур.

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 14:07
by Max Rusov
Skirda wrote:макросы загружаются _все_ и при старте ФАРа
Ну так вопрос "зачем"? Можно загружать список макросов, но не парсить их текст. Кроме ускорения загрузки FAR'а (гипотетического), можно оптимизировать и регистрацию макрофункций. Можно загружать для регистрации макрофункций только те плагины, чей "namespace" встретился при разборе макроса. А namespace можно регистрировать в GetPluginInfo, аналогично CommandPrefix. Не?

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 14:11
by Skirda
Что такое "сигнатура" в твоем понимании? Разжуй. Моя твоя не понимайт.
Я вот думаю, что если бы все выдержали бы паузу, как написано красным, то...

Re: ProcessMacroFuncW

Posted: Thu 30 Sep, 2010 14:22
by NightRoman
Skirda wrote:Что такое "сигнатура" в твоем понимании? Разжуй. Моя твоя не понимайт.
Сигнатура это описание функи, которая будет дергаться из макроса - имя, кол-во и тип параметров. То, что предполагается регистрировать, чтобы потом можно было парсить/компилить/вызывать.

Я же все еще склоняюсь к варианту, что надо ограничиться одной функцией ProcessMacroFuncW, ничего более не регистрировать, продумать простой синтакс вызова ее из макросов. Все входные/выходные аргументы строковые, количество любое. Макро движок должен уметь парсить такой синтаксис даже без наличия плагина, просто формальная проверка синтаксиса.
Skirda wrote:Я вот думаю, что если бы все выдержали бы паузу, как написано красным, то...
Возможно. Пока замолкаю. Желаю успехов в очень нужном деле.