Разработки          Услуги          О компании          Контакты  

создание структуры плагина в пакете PexPlugin самплера (модальнасти) связанного через PexLink (PexContact+PexInsert)

Материал из биософт-м

Перейти к: навигация, поиск

  !   Данная информация предназначена только только для IT-специалистов по системной интеграции модулей БИОСОФТ-М. (см. Руководства пользователя к программным продуктам)

Пакеты

Packages/PexLink остается как и раньше заниматься добавлением и просмотром измерений в обследованиях данной модальности.

В отдельный пакет Packages/PexPlugin выносится вся логика, расширяющая функциональность Pex, специфическими функциями, требуемыми для данной модальности.

Пример

См. Emix/Packages/PexPlugin где демонстрируются два типа плугина:

  • анализирующий данные обследований (EmixIndividualNorm вычисляющий демонстрационную индивидуальную норму для пациента)
  • дополняющий карточку кнопкой для специальных вычислений по полям (EmixOptimum заносящий в поле карточки значение демонстрационной "оптимальной нагрузки" вычисленное им по значениям других полей)

Emix для обоих демо показывает полученые вычисленных данных из карточки. В виде экспозированного кеша в первом случае, и простого скалярного значения во втором.

Две стороны, возможно в двух разных процессах

Плугины в Emix/Packages/PexPlugin структурированы так чтобы четко отделить логику, выполняемую в рамках процесса БД Pex и в рамках процесса самплера. Только в частном случае Pili оба процесса могут совпадать. Вся логика плугинов должна работать в любом варианте подключения к БД. Коммуникация между плугинной и самплерной стороной возможна только через официальные интерфейсы PexContact/PexInsert/Pi.

По этому плугины разделены на два Iface класса видимых приложению

  • CXxxPluginIface - на стороне БД
  • CXxxReceiverIface - на стороне самплера

"Receiver" может стать слишком узким термином если сторона на PexContact будет не только получать что то из карточки, но пока это по сути. "Receiver" просто инкапсулирует получение полей из карточки. Он относится к PexContact, общается с пакетом PexLink но вынесен из него т.к. не занимается регистрацией измерений.

Инициализация

Плугины подключаются к Pex при инициализации PexInsert для данной модальности. Инициализация оного остается как и раньше в пакете PexLink и вызывает CXxxPluginIface из пакета PexPlugin:

void CEmixPexInsertLinkImpl::OnInitEmixPexInsertLink(
        ref<CPexInsertConnectionIfaceGp> rPexInsertConnection)
{
    if (rPexInsertConnection->IsPexInsertConnectionAvailable())
    {
        ...
 
        x_rPexInsertConnection->
            ConnectInsertedModule(...
 
//VL: 2014-06-04 -U2
        // Install Picom callback
        m_rEmixIndividualNormPlugin->
            InitEmixIndividualNormPlugin(
                x_rPexInsertConnection);
 
        // Predefine card fields
        m_rEmixOptimumPlugin->
            InitEmixOptimumPlugin(
                x_rPexInsertConnection);
//VL.
    }
}

Как видим инициализаторы плугинов получат все необходимые им связи из rPexInsertConnection.

Реакция на события внутри БД

Плугин EmixIndividualNorm демонстрирует отслеживание добавления новых измерений и запуск новых обследований своим прибором для пересчета своих данных.

Для установки своего колбака на события в Picom используется RegisterPicomUpdateCallback(колбак, очередность):

void CEmixIndividualNormPluginImpl::OnInitEmixIndividualNormPlugin(
        ref<CPexInsertConnectionIfaceGp> rPexInsertConnection)
{
    rASSERT(...
 
    // register our callback
    m_rEmixPicomUpdate->_x_pEmixIndividualNormPlugin = this;
    rPexInsertConnection->
        RegisterPicomUpdateCallback(
            m_rEmixPicomUpdate,
            CPicomUpdateIfaceGp::E_PicomUpdateOrder_CEmixPicomUpdate);
}

См. CEmixPicomUpdate где происходит отработка соответствующих событий. Данный объект колбака может быть связан с EmixIndividualNormPluginImpl указателем ptr. Через этот указатель он делегирует выполнение всех вычислений объекту сессии плугина CEmixIndividualNormPluginImpl. Обращаю особое внимание на возможность такого указателя в данном сценарии работы.

Broadcast callbacks с множеством получателей (CMulticallGp) на котором построен PicomUpdate требует декларации enum константы для каждого класса обработчика. Соответственно нужно добавить такую константу в CPicomUpdateIfaceGp::EPicomUpdateOrder. Не забывать напоминать при интеграции нового плугина!

Захват поля карточки

Другой тип связи с Pex демонстрирует плугин EmixOptimumPlugin. Он не занимается отработкой событий Picom а создает себе особое поле карточки, обвешивая его контекстными колбаками:

void CEmixOptimumPluginImpl::OnInitEmixOptimumPlugin(
            ref<CPexInsertConnectionIfaceGp> rPexInsertConnection)
{
    rASSERT(...
 
    PrepareOptimumButtonCardField(
        rPexInsertConnection->
            x_rPiCardConfig);
}

Здесь мы:

  • создаем поле
  • настраиваем его
  • заменяем его обработчик UI (на кнопку)
  • сохраняем колбак, вызываемый по этой кнопке

Подробнее:

  • поле создается/обновляется вызовом Pi API DefinePatientFieldByPlugin()
  • параметры поля задаются через CPiFieldConfigIfaceGp
  • UI поля карточки заменяется установкой своего колбака через SetPluginAdditionalFieldConfigCallbacks() со специальным ключем CPiFieldConfigIfaceGp::C_keyFieldCallbackForMainFieldInputUi
    • в качесиве UI поля карточки выбирается встроенный в Picom особый тип поля "с кнопкой" CPicomFieldInputButtonIfaceGp
    • такая кнопка способна при ее нажатии загрузить DLL нужной модальности, восстановить ее колбак (ExposeIn) из настроек карточки и передать управлению плугину модальности для выполнения требуемых действий при нажатии кнопки
    • при инициализации такого поля задаются
      • x_sPreloadFieldButtonModule = имя модуля плугина
      • x_keyFieldButtonCallbackCookie = ключ колбака модуля плугина в настройке поля карточки
      • параметры UI самой кнопки
  • отдельно с помошью еше одного вызова SetPluginAdditionalFieldConfigCallbacks() инициализатор добавляет к полю свой полиморфный колбак.
+ Детали

См. CEmixOptimumCallback где происходит отработка нажатия вставленной в поле карточи кнопки. Обрашаю внимание что данных колбак сохраняется и восстанавливается экспозицией, вися в мапе конфига карточки. У него нет возможности после восстановления получить ptr на объект CEmixOptimumPluginImpl. Поэтому объект сессии CEmixOptimumPluginImpl выполняет только инициализацию и потом больше не используется в данном примере.

Данный плугин должен выполнять всю свою работу не располагая никаким глобальным контекстом а только ссылкой ref<CPiFieldValueIfaceGp> на значение карточки для данного пациента для которого нажата кнопка. И через Pi API из него можно выудить всю нужную информацию о пациенте.

Вычитывание данных из измерений пациента

См. демо в

    CEmixIndividualNormPluginImpl::CalcEmixIndividualNorm(
            ref<CPiPatientIfaceGp> rPiPatient)

Обращаю внимание что данные измерений доступны плугину только для чтения. Категорически запрещается пытаться их изменять даже если через запреты SEMIPUBLIC(_picom_) просочились Set-методы!

Сохранение данных в полях карточки

С полем карточки можно ассоциировать два значения.

  • простой скаляр как обычно
  • структурный экспозируемый кеш с результатами вычислений (SetPluginAdditionalFieldValueCache)

Декларация поля

делается DefinePatientFieldByPlugin() (см. примеры в Emix)

Задание значения полю

демонстрируется с использованием SetPiFieldValueAsStr()

Сохранение экспозированного кеша

см. SetPluginAdditionalFieldValueCache()

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

  • Убедится что инициализация PexInsert обновлена для поддержки соединения с Picom-PexInsert
  • Скопировать пакет PexPlugin из Emix
    • заменить слова Emix на свой проект
    • выбрать какая из заготовок ближе задаче и удалить другую если не нужна
      1. CEmixIndividualNorm*... + CEmixPicomUpdate.* вычисляют по сохраненным измерениям и сохраняют структуру в кеше поля карточки
      2. CEmixOptimum*... + CEmixOptimumCallback.* добавляют поле с кнопкой, вычисляющее свое значение по другим полям
  • Добавить вызов инициализации плугинов в OnInit....PexInsertLink (см. выше и код в CEmixPexInsertLinkImpl::OnInitEmixPexInsertLink())
  • Вызвать функции из CEmixIndividualNormReceiverIface/CEmixOptimumReceiverIface получающие результаты из карточки для проведения текущего обследования
  • Если значения этих полей нужны в самплере то в PexLink добавляются по аналогии с Emix
    • str LookupCurrentPatientFieldValueOr()
    • rp<CPiAddFieldValueIfaceGp> LookupCurrentPatientPluginFieldValueCache()
  • Убедится что работает и с Bica и c Pili перевычисляя и при добавлении измерений и/или по кнопке появившейся в карточке и все это вычитывается правильно из Receiver функций
  • Исправить на свою прикладную логику
www.biosoft-m.ru



Просмотры
Личные инструменты