скрипты и плагины
От: anvaka Украина Yasiv
Дата: 30.07.05 12:00
Оценка:
Привет!
Как вы думаете, как лучше спроектировать программу, обладающую способностью поддержки скриптов и плагинов (причем скрипты, основываются на функциях из плагинов)?
У меня есть идея (ниже я ее изложу), но хотелось бы услышать ваше мнение. Может, уже есть некоторые паттерны?

Идея такова.
Плагины. Каждый модуль должен будет говорить мне свое имя, количество доступных функций для пользователя (расширяющие функциональность программы), имена этих функций (в двух экземплярах — один для того, чтобы показать пользователям, названия новых функций, второй для использования в скриптах). Ну и некоторую функцию (назвем ее Run(function_name), вызывающую функцию, которая соответсвтует i-му имени.

Далее скрипты. Скажем, был написан плагин my3d. имеющий единственную функцию, для рисования трехмерного куба, единичного размера. Для того чтобы нарисовать этот куб, пользователю достаточно будет ввести в срипте что-то вроде:
myd3d.cube;

Теперь, при старте программы, запоминаю все имена плагинов, соответсвующие хендлы этим именам. Когда вступает в работу ScriptEngine по перовму имени находим хендл, второе, в новом потоке, передаем в Run()...
Надеюсь, идея достаточно понятна и информативна.
Re: скрипты и плагины
От: krasin Россия  
Дата: 30.07.05 14:22
Оценка: 8 (1)
В Миранде сделано так: в плагин передается IPluginLink, состоящий из методов (далее в качестве базового языка будет использоваться C#):
interface IPluginLink
{
   void AddServiceFunction(string name, Delegate handler);
   void AddHookableEvent(string name);
   void AddHook(string eventName, Delegate handler);
   void CallService(string name, params object [] parameters);
}

Кроме того, плагин предоставляет интерфейс
interface IPlugin
{
   string Name { get; }
   string Description { get; } 
   void Load(IPluginLink link);
   void Unload(IPluginLink link);
}

При загрузке плагина, он регистрирует нужные функции (имена выбираются вида ICQ.SendMsg, DB.GetSetting, т.е. имя_плагина.функция), регистрирует свои события, подписывется на нужные события уже загруженных плагинов. Для вызова уже зарегистрированной функции используется CallService. Соответственно, из скрипта можно вызывать функции так:
ICQ.SendMsg(123456, "Привет")
Re[2]: скрипты и плагины
От: anvaka Украина Yasiv
Дата: 30.07.05 14:35
Оценка:
Здравствуйте, krasin!
Интересная информация. Особенно идея с хуками и событиями. Но это чересчур для меня.
Не очень ясен смысл IPluginLink. Если я правильно понял, то он передается из самого приложения?
Re[3]: скрипты и плагины
От: krasin Россия  
Дата: 30.07.05 15:33
Оценка:
Здравствуйте, anvaka, Вы писали:

A>Интересная информация. Особенно идея с хуками и событиями. Но это чересчур для меня.

A>Не очень ясен смысл IPluginLink.

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

A> Если я правильно понял, то он передается из самого приложения?


Верно.
Re[3]: скрипты и плагины
От: krasin Россия  
Дата: 30.07.05 15:44
Оценка:
Здравствуйте, anvaka, Вы писали:

A>Здравствуйте, krasin!

A>Интересная информация. Особенно идея с хуками и событиями. Но это чересчур для меня.
A>Не очень ясен смысл IPluginLink. Если я правильно понял, то он передается из самого приложения?

Да, с хуками непонятно, потому что неправильно написано
Правильно так:
interface IPluginLink
{
   void AddServiceFunction(string name, Delegate handler);
   EventId AddHookableEvent(string name);
   void AddHook(string eventName, Delegate handler);
   void CallService(string name, params object [] parameters);
   void NotifyEventHooks(EventId eventId, params object [] parameters);
}


Сценарий работы с событиями такова:
грузится очередной плагин, регистрирует событие "SomeEvent", вызывая
AddHookableEvent("SomeEvent");

грузится другой плагин и говорит "если произойдет SomeEvent, вызвать вот этот метод",
вызывая
AddHook("SomeEvent", new EventHandler(OnSomeEvent))

Проходит некоторое время, первый плагин вызывает NotifyEventHooks, которое вызовет делегат, переданный вторым плагином.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.