Инструменты пользователя

Инструменты сайта


axapta:tabax:плагины

toc Нужно сделать возможность плагшинов для табакса – чтобы кастомизировнная функциональность лежала отдельно и не мешала обновлять табакс.

Требования

  • Tabax должен состоянть из одной формы и больше из ничего
  • Tabax в приложении с подключенными плагинами должен экспортироваться в другое приложение и нормально работать если в последнем плагинов нет

Дизайн

  • Плагин – это класс, у которого есть свойство Tabax и название которого начинается на ««TabaxPlugin_»»

Загрузка

  • Табакс проходит по таким классам, создает их экземпляры и знакомит с собой:
static void Test_PluginLoad(Args _args)
{
    UtilElements ue;
    Object element;
    Object plugin;
;
    while select name from ue group by name
        where ue.recordType == UtilElementType::Class
              &&
              ue.name like 'TabaxPlugin_*'
    {
        plugin = new SysDictClass(className2ID(ue.name)).makeObject();
        plugin.tabax(element);
    }
    info('ok');
}
  • При получении ссылки на табакс плагины могуть его каким-то образом изменить: добавить или скрыть кнопки, установить настройки, подписаться на события

События

  • плагин может подписать себя на события.
  • если плагин подписался на событие то табакс вызывает определенный метод плагина

Cобытия реализуются так:

  • есть пара методов tabaxа:
    • subscribe(str _eventName, object) – подписаться
    • unsubscribe(str _eventName, object) – отписаться
  • если есть объекты, подписанный на событие, то при возникновении события tabax дергает метод <ИмяСобятия> в объекте

Пример:

class TabaxPlugin_CopyWindowHwnd
{
    Object tabax
    int action;
    Hwnd hwnd;
    Object tabax(Object _value=tabax)
    {
        tabax=_value;
        if (!prmIsDefault(tabax) && tabax)
        {
             tabax.subscribe(methodStr(TabaxPlugin_CopyWindowHwnd, BeforeWindowContextMenu), this);
             tabax.subscribe(methodStr(TabaxPlugin_CopyWindowHwnd, AfterWindowContextMenu), this);
        }
        return tabax;
    }
    void  BeforeWindowContextMenu(Object _tabax, Hwnd _hwnd, PopupMenu _menu)
    {
    ;
        action = _menu.insertItem('Copy hwnd');
        hwnd = _hwnd;
    }
    void  AfterWindowContextMenu(Object _tabax, int _choice)
    {
        TextBuffer buf;
    ;
        if (action == _choice)
        {
            buf = new TextBuffer();
            buf.setText(int2str(hwnd));
            buf.toClipboard();
        }
    }
}

SDK

В качестве документации и помощи будет распространятся SDK состоящий из

  • интерфейса с прокомментированными методами табакса
  • базового класса с методами событиями

Плагин с применением SDK будет выглядеть так

class TabaxPlugin_CopyWindowHwnd extends TabaxPluginBase
{
    int action;
    Hwnd hwnd;
    void connect(Tabax _tabax)
    {
          #subscribe(BeforeWindowContextMenu)
          #subscribe(AfterWindowContextMenu)
    }
    void  BeforeWindowContextMenu(Object _tabax, Hwnd _hwnd, PopupMenu _menu)
    {
    ;
        action = _menu.insertItem('Copy hwnd');
        hwnd = _hwnd;
    }
    void  AfterWindowContextMenu(Object _tabax, int _choice)
    {
        TextBuffer buf;
    ;
        if (action == _choice)
        {
            buf = new TextBuffer();
            buf.setText(int2str(hwnd));
            buf.toClipboard();
        }
    }
}

Альтернативы

Почему именно такое требование? Ведь плагин будет реализовывать некий заранее предписанный интерфейс, не так ли? Может быть лучше требовать, чтобы класс плагина обязательно содержал в определении implements ««TabaxPlugin»». Тогда и обход можно сделать понятнее, эффективнее и без хакерского обращения к ««UtilElements»», воспользовавшись методами ««DictClass.implementsCnt()»», ««DictClass.implements()»» MazzyMazzy /22.03.2007 12:06/

//Это тормозит -- придется кешировать и где-то хранить кеш (где?)  // -- [[:MaxBelugin]] /22.03.2007 12:51/
axapta/tabax/плагины.txt · Последнее изменение: 2018/04/13 22:43 (внешнее изменение)