Copyright
(c) Prolog Development Center SPb
Application Frame.
Механизм plugin
Механизм
plugins в AppFrame базируется на концепции PzlSystem,
которая является системой соглашений по применению DLL для хранения
части исполняемой системы.
Подробнее концепция
PzlSystem изложена в документе VpPuzzle.
Пакеты системы
размещаются в директории SpbVipTools\Packs\Logic\PzlSystem\OpenPzl.
Каждый
из вариантов проектов AppFrame в соответствии с концепцией
VpPuzzle является pzl-Контейнером, то есть он может содержать в своем
составе pzl-Компоненты. Ядро AppFrame не использует свойства
pzl-Контейнера, однако ничто не мешает в конкретном проекте
воспользоваться этими свойствами.
Механизм Plugins предполагает
использование pzl-Компонент, размещенных в pzl-Контейнерах, каждый из
которых является DLL. Каждый pzl-Контейнер может содержать любое
количество pzl-Компонент.
Pzl-Компоненты, использование которых
предполагается в проекте на базе AppFrame должны быть
предварительно зарегистрированы любым из способов, предсмотренных
pzl-Концепцией.
Каждая pzl-Компонента может обращаться к любым
другим зарегистрированным pzl-компонентам. Глубина иерархии вызовов не
ограничена.
Однако AppFrame "знает" только о той компоненте, к
которой он обращается.
Вызов plugin
Поскольку
архитектура ApplicationFrame предполагает строгое разделение FrontEnd и
BackEnd, постольку вызовы Plugins в контексте FrontEnd и BackEnd имеют
свои особенности.
В частности, это касается вызова компоненты, представленной своим
пользовательским интерфейсом, командой панели управления.
В xml-описании панели управления для
ядра AppFrame существенным является соглашение об
указании в идентификаторе команды ключевого сочетания ribbon.cmd.plugin.<имя
компоненты> и данных свойства category команды.
При этом содержание данных свойства category
определяется только разработчиком plugin-компоненты.
Пример определения вызова pzl-Компоненты pzlGame приведен ниже
<cmd
id="ribbon.cmd.plugin.pzlGame"
label="Game_PLL14"
cmdstyle="image-and-text-vertical"
run="pzl-extension"
menu-label="Game_PLL14"
enabled="true"
visible="true"
category=""
>
<icon
file="$(pdc-external)\categories\applications-games.ico"/>
<tooltip text="Polyline14
aggregated
pzlComponent"/>
</cmd>
Здесь свойство category
показано для полноты, хотя могло бы отсутствовать, поскольку не имеет
практического значения.
Важным является определение аттрибута run="pzl-extension",
которое означает, что pzl-extension
является идентификатором предиката, который будет вызван при
активизации команды с label="Game_PLL14".
При определении контекста для этого случая должно быть
выполнено назначение
setCommonPerformers(ContextObj):-
...
ContextObj:setRunner("pzl-extension",fe_CoreTests():runPlugin),
...
А в объекте fe_CoreTests() вызов pzl-Компоненты при этом может
выглядеть так:
clauses
runPlugin(Command):-
PluginID=fe_Command::tryExtractCommandSuffix(Command,"ribbon.cmd.plugin."),
!,
ComponentObj=pzl::newByName(PluginID,fe_AppWindow()),
Component=convert(pzlRun,ComponentObj),
Component:pzlRun(toString(Command:category)).
runPlugin(Command):-
Msg=string::format("Not pzl plugin invocation command [%]\n",Command:id),
log::write(log::error,Msg),
exception::raise_User(Msg).
Здесь используется соглашение о том, что компоненты, представленные
пользовательским интерфейсом, могут быть активизированы
вызовом предиката pzlRun(...)
с передачей ему необходимых данных в текстовой форме. В данном примере
передается содержимое свойства category
команды. Интерфейс pzlRun
(содержащий одномименный предикат) является одним из интерфейсов
pzl-Системы.
После
вызова предиката pzlRun дальнейшее поведение Plugin определяется его
реализацией. После завершения работы plugin все его
компоненты
будут автоматически выгружены и память будет освобождена.