Загрузка актора на лету

Модель программирования Actor Framework
Ответить
Аватара пользователя
Juri
I/O
I/O
Сообщения: 263
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2021
Благодарил (а): 13 раз
Поблагодарили: 6 раз

Загрузка актора на лету

Сообщение Juri »

Идея в том, чтобы во время исполнения программы загружать скомпилированные акторы из известной папки. У меня все акторы являются потомком одного мастер-актора. Это прописано в иерархии класса. Мне не нравится то, как фреймворк плодит кучу классов для ввода-вывода данных, поэтому я сделал мастер-актор, который обеспечивает обмен между всем акторами через тип variant. Проблемы две.
1 Я вызываю nested акторы, предварительно объединив их в массив (скрин 2). При этом в индикаторе appended array 3 мы видим, что выходящий класс превратился в класс мастер-актора (т.е. если бы я все сделал без мастер-актора, то на его месте был бы стандартный класс Actor). Проблема возникает когда я создаю Packed library из nested акторов. Создаю точно такой-же массив как скрине 2 из скомпилированных акторов, но в appended array 3 уже не появляется их общий родительский класс, а появляется стандартный пустой класс (скрин 4). В итоге у меня конфликт типов данных и nested акторы не запускаются.
2 Моя идеология предполагает, что родитель вызывает nested акторы, которых заранее нет в памяти программы. Они должны загружаться из скомпилированных библиотек. Нужные мне vi, которые посылают сообщения и должны выполняться из главного актора, находятся в папке с известным именем. Пока это обычный проект, я могу их найти через стандартную функцию поиска файлов. Но когда это будет скомпилированная библиотека, как их найти?
Вложения
Рис1 Иерархия классов
Рис1 Иерархия классов
Рис 2 Массив акторов
Рис 2 Массив акторов
2.png (11.13 КБ) 2484 просмотра
Рис 3 Мастер-актор
Рис 3 Мастер-актор
3.png (4.95 КБ) 2484 просмотра
Рис 4 Вместо мастер-актора загрузилась пустышка
Рис 4 Вместо мастер-актора загрузилась пустышка
4.png (4.34 КБ) 2484 просмотра
Аватара пользователя
IvanLis

Activity Professionalism Tutorials Gold Man of the year 2012
Автор
guru
guru
Сообщения: 5462
Зарегистрирован: 02 дек 2009, 17:44
Награды: 7
Версия LabVIEW: 2015, 2016
Откуда: СССР
Благодарил (а): 28 раз
Поблагодарили: 86 раз

Re: Загрузка актора на лету

Сообщение IvanLis »

Я сам подобного не проделывал, необходимости подобной не было, посмотрите Actor Framework from basic to PPL plugins
Аватара пользователя
Kosist

Activity Gold
expert
expert
Сообщения: 1236
Зарегистрирован: 21 фев 2011, 23:44
Награды: 2
Версия LabVIEW: 2013-2020
Благодарил (а): 23 раза
Поблагодарили: 30 раз
Контактная информация:

Re: Загрузка актора на лету

Сообщение Kosist »

Сначала простая часть - загрузка класса с диска. Для этого есть стандартные функции загрузки класса. Если класс находится в ppl (Project Packed Library), то в палете File I/O -> Advanced File Functions -> Packed Library есть тоже функции которые можно использовать.
Но вот в целом плагиновая архитектура - та еще головная боль.
Тут есть два пути - использовать классы "в сыром виде", или же в виде запакованых библиотек (ppl).
В обох случаях залог успеха - это добиться того, чтобы при динамической загрузке класса в памяти не возникало конфликтов, т.е. нельзя загружать те виайки, которые уже загружены в память самим exe.
Это главная проблема для использования классов "в сыром виде". Достичь этого можно таким способом, что Вы отдельно билдите приложение, и отдельно билдите Source Distribution классов. Но при этом, исключаете из билда все то, что уже включено в билд приложения. В результате, класс после билда обычно нерабочий сам по себе - ведь ему нехватает "общих" виаек с целым приложением.
Другой способ - это ppl. Главный недостаток ppl это то, что их нельзя переносить в другие версии :labview: , т.к. по сути это уже скомпилируемый код. Таким образом, сделав проект с использованием ppl, например, в :labview: 2018, Вы не откроете его так легко в :labview: 2020. Нужно будет билдить опять ppl минимум, а максимум - перелинковывать вручную их в проекте.
Но в случае ppl тоже должно работать правило что общие библиотеки не должны подгружаться многократно. Нужно найти "самостоятельные" библиотеки, которые не зависят от иных библиотек, и билдить ppl сначала с них. Потом - эти библиотеки поменять в коде на ppl, и начать билдить библиотеки которые уже зависят от ppl. При билде нужно ставить галочку Exclude Shared Libraries - таким образом ppl из зависимостей не будет включено в билд этих библиотек. И т.д., идете снизу вверх - сначала "независимые" библиотеки, потом дальше вверх по дереву зависимостей.
Например, LibA содержить класс Shared.lvclass, и LibB тоже использует класс Shared.lvclass. Если просто сбилдить LibA в отдельную ppl, и LibB в отдельную ppl, то обе либки будут содержать класс Shared.lvclass - но для :labview: это уже будут разные классы. А вот если сначала в исходнике поместить Shared.lvclass в отдельную либку, из нее сделать ppl, а потом сделать ppl-ки с LibA и LibB (при этом сделать Exclude Shared libs), то уже все будет нормально.
В случае Actor Framework - нужно вначале сбилдить ppl из самой корневой либки Actor Framework, и поменять на нее "исходник" (это, кстати, самое легкое - ПКМ на либке -> Replace by Packed Library). А потом билдить дальше.
Чтобы не возникало конфликтов, разные библиотеки лучше билдить из-под отдельных проектов.
В итоге, Ваше приложение потом будет зависеть от ppl, и Вы сможете сбилдить приложение которое будет их подгружать динамически.
Советую попробовать это сделать на маленьком, пробном проекте - чтобы Вы почувствовали что и как работает. Ну, и менять код на ppl лучше в самом конце, когда проект в исходнике работает полностью. Т.к. дебажить ppl - это то еще удовольствие...
Мы делили апельсин - много наших полегло...
Аватара пользователя
Juri
I/O
I/O
Сообщения: 263
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2021
Благодарил (а): 13 раз
Поблагодарили: 6 раз

Re: Загрузка актора на лету

Сообщение Juri »

Все получилось. Но обнаружилась неприятность. В какой-то момент при переключении с Actor Framework.lvlib на скомпилированный Actor Framework.lvlibp, библиотека AF Debug.lvlib тоже переключается на lvlibp вместо lvlib. Потом когда я возвращаюсь в свой основной проект, в котором продолжаю везде использовать только исходный Actor Framework.lvlib эта AF Debug.lvlib оказывается подключенной к скомпилированной версии Actor Framework.lvlibp и происходит конфликт. Это впрочем никак не мешает исполнению программ. Пока что решил в случае чего хранить всю папку с AF Debug.lvlib в двух архивах один подключен к одной версии Actor Framework другой - к другой и заменять всю папку в случае конфликтов.
Аватара пользователя
Juri
I/O
I/O
Сообщения: 263
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2021
Благодарил (а): 13 раз
Поблагодарили: 6 раз

Re: Загрузка актора на лету

Сообщение Juri »

У меня снова проблема. Иерархия наследования на картинке. Actior -> Actors - разные акторы
Actior - Actor Framework, всегда загружается из скомпилированной библиотеки lvlibp
Actors - мое расширение Actor Framework, всегда загружается из скомпилированной библиотеки lvlibp
Pop-up window.class или любой другой на его месте загружаются в режиме отладки из проекта или в режиме исполняемого exe из скомпилированной библиотеки lvlibp.
В Actors у меня происходит загрузка Nested Actors, которые имеют туже самую иерархию. Actors должен знать, работает он из exe или из проекта и в зависимости от этого выбирать способ загрузки Nested Actors (из проекта или из lvlibp) На картинке я это делаю при помощи Conditional Disable Structure. Проблема в том что почему-то она всегда работает в режиме default, даже когда запускается exe. Что я делаю не так? При чем в лаунчере root актора аналогичный кейс работает как надо.
Вложения
Screenshot_6.png
Screenshot_1.png
Screenshot_1.png (5.32 КБ) 2105 просмотров
Аватара пользователя
Kosist

Activity Gold
expert
expert
Сообщения: 1236
Зарегистрирован: 21 фев 2011, 23:44
Награды: 2
Версия LabVIEW: 2013-2020
Благодарил (а): 23 раза
Поблагодарили: 30 раз
Контактная информация:

Re: Загрузка актора на лету

Сообщение Kosist »

Это точно что исполняется код в Default структуре, Вы продебажили в exe - или это видно по "косвенным уликам"?
Странно, что typecast исполняется для одного типа класса - этот класс находится в ppl?
Мы делили апельсин - много наших полегло...
Аватара пользователя
Juri
I/O
I/O
Сообщения: 263
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2021
Благодарил (а): 13 раз
Поблагодарили: 6 раз

Re: Загрузка актора на лету

Сообщение Juri »

Ну на выходе индикатор exe всегда показывает false и nested акторы не загружаются, т.к. включается неверный обработчик их загрузки. Сейчас я решил проблему просто заменив Conditional Disable Structure на кейс структуру.
Странно, что typecast исполняется для одного типа класса - этот класс находится в ppl?
Actor Framework предоставляет слишком большую свободу в создании разных типов для обмена данными. Я специально ограничил эту свободу тем, что у меня все акторы - потомки класса Actors, который является потомком класса Actor. Потому все Nested акторы загружаются одной единой vi из класса Actors. Все объекты загружаются из lvlibp. PPL в вашем сообщении это какое-то расширение файла или просто аббривеатура Packed Project Library?

ps Если что, скрин выше с красной линией - это два разных скрина склеенных вместе.
Аватара пользователя
Juri
I/O
I/O
Сообщения: 263
Зарегистрирован: 19 апр 2017, 23:06
Версия LabVIEW: 2021
Благодарил (а): 13 раз
Поблагодарили: 6 раз

Re: Загрузка актора на лету

Сообщение Juri »

Периодически у меня получается, что внутри одного актора используются vi из другого актора. В итоге в скомпилированной библиотеке .lvlibp находится второй актор целиком. В ручную я это исправляю легко, но хочется автоматизировать хотябы проверку, чтобы добавить Pre-Build Action, который будет проверять, не попадаются ли vi из чужого актора. Как сделать такую проверку?

UPD: нашел решение. Потом выложу
Ответить

Вернуться в «Actor Framework»