Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Добрый день.
Помогите, пожалуйста. Впервые столкнулся с Pascal Script.

Tools (из состава Pascal Script) для импорта модулей сгенерил что-то невобразимое. Половину свойств потерял.
Стал пробовать ручками.

Пытался сделать как-то так, в Script1Compile:

with sender.comp.AddClassN(sender.comp.FindClass('TOBJECT'), 'TIdUDPClient') do
begin
registerproperty('host','string',iptRW);
registerproperty('port','integer',iptRW);
registerproperty('active','boolean',iptRW);
registerproperty('connect','boolean',iptRW);
registerproperty('send','string',iptRW);
end;

 Sender.AddRegisteredVariable('IdUDPClient1','TIdUDPClient');

В какой-то момент, даже показалось, что заработало. Но только показалось, увы...

Вероятно, нужно бы еще добавить что-то вроде:

with sender.RI.Add(TIdUDPClient) do RegisterPropertyHelper(Fn_чтения, Fn_присвоения, Имя);


но для этого предварительно придется ковырнуть uPSComponent и сделать RI доступным.

Наверняка есть более простой и логичный путь прикручивать в PS уже существующие в Delphi
компоненты (классы)?

Сообщение было отредактировано: 11 май 20, 11:23
10 май 20, 15:13    [22130152]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Сделал вот так, в OnCompile:



With PSScript1.comp.AddClassN(sender.comp.FindClass('TOBJECT'), 'TIDUDPCLIENT') do
  Begin
   Registerproperty('host','STRING',iptRW);
   Registerproperty('port','INTEGER',iptRW);
   Registerproperty('active','BOOLEAN',iptRW);
   RegisterMethod('procedure Connect');
   RegisterMethod('procedure Send(AData: string)');
 End;


 With PSScript1.RI.Add(TIdUDPClient) do
  Begin
    RegisterPropertyHelper(@Host_R,@Host_W,'host');
    RegisterPropertyHelper(@Port_R,@Port_W,'port');
    RegisterPropertyHelper(@Active_R,@Active_W,'active');
    RegisterVirtualMethod(@TIdUDPClient.Connect, 'Connect');
    RegisterMethod(@TIdUDPClient.Send, 'Send');
  End;


В принципе - работает. Но, вероятно, есть какой-то и другой способ, более изящный, что ли. Документации мало...
11 май 20, 21:55    [22130798]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Добрый день!

Скажите, пожалуйста: а есть у кого-то рабочий вариант, как сделать доступными в Pascal Script и Events, например, для TIdUDPServer ?

Что бы можно было и принимать данные. Правда, тут мне не совсем понятен "жизненный цикл" экземпляров TIdUDPServe, созданных внутри Pascal Script. Как думаете, такая работа с сервером UDP из скрипта, когда он реагирует на входящий пакет без постоянного опроса в скрипте - вообще возможна?
15 май 20, 13:11    [22133625]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
alekcvp
Member

Откуда:
Сообщений: 2071
AleksVoronezh
Что бы можно было и принимать данные. Правда, тут мне не совсем понятен "жизненный цикл" экземпляров TIdUDPServe, созданных внутри Pascal Script. Как думаете, такая работа с сервером UDP из скрипта, когда он реагирует на входящий пакет без постоянного опроса в скрипте - вообще возможна?

Где-то то-ли в интернете, то-ли в демках ПС были примеры, как процедуры из сценария назначать событиям реальных объектов. Но это нужно искать.
15 май 20, 15:36    [22133749]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Будем искать, и, кажется, что-то уже нарыл.


Как я понял, обращаться к разному (по условию задачи) числу хостов из скрипта через TIdUDPClient относительно не сложно. Создание их экземпляров и последующая отправка данных полностью ложаться в предусмотренные в Pascal Script средства.

Также заранее не известно, сколько, например, этих самых TIdUDPServer потребуется в конкретном скрипте. Вероятно, нужно сделать какую-то обертку, которая будет создавать экземпляры TIdUDPServe в главном, "внешнем" по отношению к скрипту приложении, приводить всякие типы AData к достаточному в данном случае String и так далее. А уже обертку сделать доступной для скрипта...

Чтобы скрипт не "повесил" главное приложение, в нем предусмотреть Application Process Message. То есть работа с получение данных в скрипте от разных хостов могла бы , наверное, выглядеть так:

1. Через обертку создаем экземпляр TIdUDPServer для конкретного порта.
2. Экземпляр обертки, в свою очередь, через свойство например, обеспечиватет передачу в скрипт данных, преобразованных из AData в String.

Довольно просто. Но тут не обойтись без циклической проверки этого свойства.


Если обеспечить передачу данных в скрипт, как советуете Вы, alekcvp, то нужно перед созданием экземпляра своей обертки, в скрипте, создать и предназначенную для обработки данных от конкретного хоста функцию. И далее закрепить ее вызов через GetProcMethod скриптового движка. Этот GetProcMethod как раз и вызывает функции внутри скрипта, по имени. Должно взлететь, я думаю.


Что-то подобное предстоит проделать и для TCP, и для COM-портов. Надеюсь, что этот GetProcMethod не заблокирует весь скриптовый движок при вызове конкретной функции, и он (движок) будет готов обрабатывать GetProcMethod для остальных функций внутри скрипта....
15 май 20, 21:29    [22133975]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 756
как-то слишком сложно.

Если не стоит вопроса вызывать скриптовое событие с блокированием (упоминание про ProcessMessages явно на это указывает), то все надо делать намного проще - создавать событие, его закидывать в очередь, в скриптовом потоке постоянно очередь крутить, при наличии там событий - выполнять их в скрипте через PSScript.ExecuteFunction, понятно приводя параметры к array of Variant, и обрабатывая возможные возвращаемые сообщения, ошибки и прочее.

Если надо - могу скинуть куски кода.
15 май 20, 21:47    [22133981]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Vizit0r, спасибо за ответ.

Видимо, я немного косноязычно пояснил. У меня есть приложение (основное), котрое занимается визуализвцией данных. Желательно расширить его таким образом, что бы пользователи могли сами подсовывать ему данные от разных источников (по UDP, TCP, RS-232) пользуясь скриптовым языком и осуществлять предварительную обработку или парсинг этих данных. Сейчас получение данных осуществляется только от тех источников, которые жестко были определены на этапе компиляции приложени.

Идея у меня была такая, что Pascal Script при своей работе ни в коем случае не должен блокировать работу основного приложения. Отсюда - надежда, что помещение ProcessMessages в событие "OnLine" поможет решить эту проблему.

С очередью внутри PS связываться бы не хотелось. В идеале - пользователь на PS описывает функцию, обрабатывающую данные от конкретного хоста, данные обрабатываются и дергают средства визуализации, предусмотренные в основном приложение.

Вызов нужной функции в PS из внешнего приложения, где "живут", например, созданные нами экземпляры UDPServer осуществляется по имени, с помощью метода GetProcMethod у скриптового движка, по приему данных экземплярами UDPServer (возможно, тут нужно будет предусмотреть анализ входящих данных на завершающую последовательность и только потом дергать функцию в движке) Получаем почти полностью событийно-управляемую, расширяемую скриптами конструкцию.

Вохможно, тут есть и другие проблемы. Но первое, что волнует - как будет, если вызов Функции_1 с помощью GetProcMethod из скрипта еще не отработан, а поступил запрос на вызов Функции_2 по приходу данных от следующего хоста? Затыки на занятость визуализатора пока опускаем, это я как раз разрулю...
15 май 20, 22:32    [22134000]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 756
AleksVoronezh
как будет, если вызов Функции_1 с помощью GetProcMethod из скрипта еще не отработан, а поступил запрос на вызов Функции_2 по приходу данных от следующего хоста?


PS это очень не понравится.

Критсекции, чтобы не было двойного вызова.
16 май 20, 07:39    [22134053]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Если "PS это очень не понравится": то, пожалуй с отказом от очереди я очень поторопился.

Буду курить про TQueue (TObjectQueue). Правда, у меня Delphi 2006, надеюсь, реализации очереди в нем хватит. Очередь должна быть внешней по отношению к программе на Pascal Script, что бы пользователи-писатели скриптов не ломали об этом голову.

Т.е. все вызовы от UDPServer (в виде полученных данных, в конечном итоге) должны не сразу передаваться на обработку функциям в PS посредством механизма вызова этих функций через GetProcMethod, а ставиться в очередь. Причем, как минимум, элемент очереди должен содержать не только имя обрабатывающей функции в PS, но и сами данные, в элементе динамического массива, например. Что бы как можно быстрее забрать полученные данные, освободить UDPServer.

Как только скриптовый движок закончил выполнение очередной функции, обрабатывающей входные данные, эта функция возвращает в основную программу определенный флаг, и из очереди происходит следующий вызов функции ( этой же самой или другой ) + передаются предназначенные для нее данные.

Взлетит такая схема, как думаете?
16 май 20, 18:35    [22134252]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
defecator
Member

Откуда:
Сообщений: 39192
Если нет строгой привязки к Pascal Script, то я бы посоветовал выбросить его на помойку истории,
и использовать гораздо более продвинутый, быстрый и удобный DWScript
https://www.delphitools.info/dwscript/

Сообщение было отредактировано: 16 май 20, 20:48
16 май 20, 20:49    [22134303]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Есть подозрение, что этот DWScript никак не поставить в мой Delphi 2006.
16 май 20, 21:35    [22134319]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Предварительно исследовал, как ведет себя вызов двух разных процедур, не возвращающих значение (а просто отображающих счетчик в главном приложении) из скрипта.

Если выполняется Процедура 1, то вызов Процедуры 2 приводит к немедленному останову выполнения Процедуры 1. Выполнение Процедуры 1 продолжается, как только отработает Процедура 2. Что-то типа очереди "последним пришел - первым ушел"

Быстрая реакция на взодяшее событие - это, пожалуй, не плохо, с одной стороны. Но только не для обслуживания протоколов работы с оборудованием - порядок обработки получился бы обратным! От последних сообщений к первым.

Да, видимо, нужна своя очередь.
17 май 20, 23:22    [22134712]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
defecator
Member

Откуда:
Сообщений: 39192
AleksVoronezh
Есть подозрение, что этот DWScript никак не поставить в мой Delphi 2006.


он даже на Delphi 7 ставится
18 май 20, 12:00    [22134905]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 756
AleksVoronezh
Предварительно исследовал, как ведет себя вызов двух разных процедур, не возвращающих значение (а просто отображающих счетчик в главном приложении) из скрипта.

Если выполняется Процедура 1, то вызов Процедуры 2 приводит к немедленному останову выполнения Процедуры 1. Выполнение Процедуры 1 продолжается, как только отработает Процедура 2. Что-то типа очереди "последним пришел - первым ушел"

Быстрая реакция на взодяшее событие - это, пожалуй, не плохо, с одной стороны. Но только не для обслуживания протоколов работы с оборудованием - порядок обработки получился бы обратным! От последних сообщений к первым.

Да, видимо, нужна своя очередь.


это ты в своих исследованиях не дошел до этапа, когда от параллельных запусков методов рано или поздно заваливается стек выполнения PS, и он весело валится. В теории не должно, на практике я такое получал, и не раз. Я ж талантливый :)

Вот на этом этапе понимаешь, что никаких "видимо", а только последовательное выполнение методов из скрипта "снаружи", без вариантов.
18 май 20, 12:41    [22134942]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
А если, в порядке бреда, для обработки каждого внешнего вызова создавать экземпляр TPSScript, подсовывать ему скрипт-код нужного метода, исполнять его и потом уничтожать созданный экземпляр.

На первый взгляд - чудовищные накладные расходы. Но ведь PS строго говоря тоже не самолет, а скорее интерпретатор (там есть что-то про байт-код, но, думаю, это пока можно всерьез не рассматривать). Возможно, общее время обработки вызова возрастет незначительно. Хотя, конечно, усложняется обмен данными между методами в скрипте. Это можно разрулить конечно, но...

Может правда нужно просто идти на TQueue.
18 май 20, 15:18    [22135089]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
Vizit0r
Member

Откуда: Одесса
Сообщений: 756
AleksVoronezh
А если, в порядке бреда, для обработки каждого внешнего вызова создавать экземпляр TPSScript, подсовывать ему скрипт-код нужного метода, исполнять его и потом уничтожать созданный экземпляр.

На первый взгляд - чудовищные накладные расходы. Но ведь PS строго говоря тоже не самолет, а скорее интерпретатор (там есть что-то про байт-код, но, думаю, это пока можно всерьез не рассматривать). Возможно, общее время обработки вызова возрастет незначительно. Хотя, конечно, усложняется обмен данными между методами в скрипте. Это можно разрулить конечно, но...

+...НО ЗАЧЕМ?
Картинка с другого сайта.
18 май 20, 15:36    [22135100]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
ъъъъъ
Member

Откуда:
Сообщений: 685
defecator
Если нет строгой привязки к Pascal Script, то я бы посоветовал выбросить его на помойку истории,
и использовать гораздо более продвинутый, быстрый и удобный DWScript
https://www.delphitools.info/dwscript/

+1e7!
18 май 20, 16:27    [22135147]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Ну... :-) зачем. Хотелось бы добиться независимости операций, для разных хостов хотя бы. Пусть в случае с входящими данными, к примеру работает TCPServer из Indy, скриптовую функцию не придется дергать, пока так или иначе передача данных по каналу или не осуществиться, или не завершиться аварийно. Опять же для снижения лагов можно было бы использовать IdAntiFreeze или потоки.

А вот в случае с исходящим запросом можно легко "заморозить" весь процесс исполнения скриптов. Т.к. движок будет занят подвисшей (тормозящей) операцией. Это в случае общего движка.
18 май 20, 16:30    [22135150]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
DWScript не компилируется под Delphi 2006. Пробовал поздно ночью, глянул краем глаза форумы, люди что-то очень много всего правили перед установкой. Или нужна более старая версия...
18 май 20, 16:39    [22135158]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
alekcvp
Member

Откуда:
Сообщений: 2071
Vizit0r
Вот на этом этапе понимаешь, что никаких "видимо", а только последовательное выполнение методов из скрипта "снаружи", без вариантов.

Можно сделать пул потоков, в каждом - свой PS, и передавать сообщения им на обработку. Но геморно.

Вообще я когда пытался с PS работать мне там много казалось не логичным. Например, зачем было делать геттеры свойств процедурами(!), когда можно было сделать функцией и тогда можно было бы регистрировать родные геттеры/сеттеры без обёрток.
Ну и ещё там по мелочи. Вобщем без напильника с ним всё печально.

Но из бесплатных альтернатив я знаю только DWS, там тоже не всё гладко.
А из платных: PaxScript загнулся, у фаста, по слухам, тоже глюков полно и он больше под репорты заточен, ТМС денег много стоит...

Сообщение было отредактировано: 18 май 20, 16:41
18 май 20, 16:42    [22135164]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
ъъъъъ
Member

Откуда:
Сообщений: 685
AleksVoronezh
DWScript не компилируется под Delphi 2006. Пробовал поздно ночью, глянул краем глаза форумы, люди что-то очень много всего правили перед установкой. Или нужна более старая версия...

Вот тут достаточно "старые" версии, которые https://sourceforge.net/projects/dws/ - запустятся точно.
То, что они "старые" - не стоит страдать, эти старые куда новее, чем то, что ты пытаешься использовать.
18 май 20, 17:12    [22135183]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Спасибо, пошел смотреть старые версии.

А вот кто работал с DWScript, подскажите, пожалуйста - есть ли у него преимущества, например здесь:

1. Удобство подключения существующих классов с методами и событиями.
2. Наличие встроенной очереди или других механизмов при вызове скриптовых функций приложениями извне?
3. Что еще, на ваш взгляд, является преимуществом DWScript ?
18 май 20, 21:19    [22135332]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
DWS 2.0 (до Delphi 7) не ставиться:

Вот какая-то шляпная конструкция:

Const

  cValTtoVarT: array[TValueType] of Integer = (varNull, varError, varByte,
    varSmallInt, varInteger, varDouble, varString, varError, varBoolean,
    varBoolean, varError, varError, varString, varEmpty, varError, varSingle,
    varCurrency, varDate, varOleStr, varError
{$IFDEF VER140UP}
    , varError // UTF8
{$ENDIF}
    );



Ошибка: [Pascal Error] dws2GlobalVarsFunctions.pas(408): E2072 Number of elements (21) differs from declaration (22)

Ладно, правим. Потом - "[Pascal Fatal Error] dws2CLXRuntime.dpk(32): E2202 Required package 'visualclx' not found"

Как с этим бороться в Delphi 2006 - я не знаю....
18 май 20, 21:48    [22135354]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
alekcvp
Member

Откуда:
Сообщений: 2071
AleksVoronezh

Ошибка: [Pascal Error] dws2GlobalVarsFunctions.pas(408): E2072 Number of elements (21) differs from declaration (22)

Ладно, правим. Потом - "[Pascal Fatal Error] dws2CLXRuntime.dpk(32): E2202 Required package 'visualclx' not found"

Как с этим бороться в Delphi 2006 - я не знаю....

Они где-то с дефайнами накосячили, clx - это линуксовая дельфя...
19 май 20, 00:25    [22135421]     Ответить | Цитировать Сообщить модератору
 Re: Как к Pascal Script прикрутить TIdUDPClient из Indy  [new]
AleksVoronezh
Member

Откуда:
Сообщений: 331
Провел грубый эксперимент по созданию из Pascal Script парочки UDP-серверов.

Для этого включил в основную программу вот такую вот конструкцию - написано левой ногой, буду очень признателен, если кто-то вдруг сочтет возможным указать на недостатки/способ более простого решения:


type
  TMy_UDP_Read = class(TObject)    // Класс-посредник. Создается экземпляр, метод класса назначается событию, возникающему по приему данных UDP сервером

   protected
      Function_Name_To_Return_UDP_Data: String;
      Procedure Proc_UDPRead(Sender: TObject; AData: TBytes; ABinding: TIdSocketHandle);
   end;


Procedure TMy_UDP_Read.Proc_UDPRead(Sender: TObject; AData: TBytes; ABinding: TIdSocketHandle);  // Процедуора приема данных сервером

Var
  i:Integer;
  s:String;

begin
  s := '';
  try
    i := 0;
    while (AData[i] <> 0) do
      begin
      s := s+chr(AData[i]);
      i := i+1;
      end;
  finally
    Form3.Call_PS_Function(Function_Name_To_Return_UDP_Data,s,'',''); // Здесь вызов функции внутри скрипта по ее имени, Call_PS_Function работает через PSScript1.GetProcMethod(Function_Name)
  end;

end;



Function PS_UDP_Server_Create(UDP_Server_Name: string; Function_Name_To_Return_UDP_Data: string; IP_To_Bind: String; Port_To_Bind: Integer): Pointer;

Var
My_UDPServer: TIdUDPServer;
My_UDP_Read_Event: TMy_UDP_Read;

Begin
  My_UDPServer:=TIdUDPServer.Create(nil);
  My_UDPServer.Name:=UDP_Server_Name;

  With My_UDPServer.Bindings.Add do begin
   IP  := IP_To_Bind;
   Port:= Port_To_Bind;
  end;

   My_UDP_Read_Event:=TMy_UDP_Read.Create; // Создаем экземпляр класса с процедурой, преобразующей получаемые по UDP данные в строку
   My_UDPServer.OnUDPRead:= My_UDP_Read_Event.Proc_UDPRead; // Назначаем индивидуальный обработчик событию получения данных по UDP для созданного сервера

   My_UDP_Read_Event.Function_Name_To_Return_UDP_Data:=Function_Name_To_Return_UDP_Data; // Указываем имя функции внутри скрипта, в которую будем позвращать строку полученных данных

   My_UDPServer.Active:= True;

   Result:= My_UDPServer; // На всякий случай


End;



Теперь нужно подумать, что бы не сразу дергать функции внутри PS, а сделать для них осередь...
21 май 20, 23:17    [22137383]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить