33. ИСПОЛЬЗОВАНИЕ Java КОДА В ACL ПРОГРАММАХ

Этот раздел можно пропустить при первом изучении основ программирования на ACL. Но это может быть важно тем, кто уже все знает, и хочет знать больше. Я это записал лично для себя. Хотя кое-что уже было написано в главе 18. Дело в том, что есть еще одно применение команды #e (execute). Программы на языке ACL все же достаточно медленные, так как на интерпретацию команд тратится время, иногда соизмеримое с самим выполнением команды. Это совсем не важно, если речь идет о любых однократных операциях с графикой, файлами, текстом. Но в математических задачах часто используются циклы с многократным повторением одного и того же кода. Чтобы ускорить работу программы в этом случае в ACL введена команда #ma (mathematics), которая выполняет много стандартных операций над массивами чисел. В нашем случае массивами являются части одного массива r(). Но иногда разумно всю расчетную работу выполнить в программе на языке программирования Java, на котором написан интерпретатор ACL. Затем код этой программы можно подключить в интерпретатор и всю программу как целое исполнять в ACL программе. Такой вызов тоже выполняется командой #e, а сами программы просто имеют номера из двух разрядов, например, 05 (ноль писать обязательно). Выглядит это так #e [параметры] _\nn.

Каждая из таких программ имеет собственное описание, в котором написано что она делает и как она обменивается информацией с ACL программой через массивы r() и t(). Первоначально я такие программы писал только для себя и своих соавторов, точнее для своей работы по рентгеновской оптике. Они представляют интерес только для моих коллег, но я все же перечислю что было сделано.

\00 -- расчет коэффициента прохождения для многокристального монохроматора на плоскости энергия-угол
\01 -- программа рентгеновской ин-лайн оптики, т.е. перенос волновой функции через объекты и воздух
\02 -- программа метода стоячих волн, угловая зависимость рентгеновского отражения и выхода вторичных процессов
\03 -- программа расчета лауэ-дифракции в кристалле методами геометрической оптики
\04 -- расчет набора стандартных функций для использования в ACL программах одномерной ин-лайн оптики
\05 -- программа трех-волновой дифракции в кристаллах
\06 -- программа четырех-волновой дифракции в кристаллах
\07 -- программа расчета реальных функций двух аргументов (матриц)
\08 -- программа расчета произвольных функций без файлов
\09 -- программа spexpro для вызова внешних программ общего назначения
\10 -- программа extpro для вызова внешних программ по физике

Программа 00 уже имеет аналог на языке javascript и работает онлайн на моем сайте. Программу 01 я уже практически не использую, так как то же самое можно делать на ACL другим способом. Она была моей самой первой java программой. Программы 02,03,05,06 написаны для решения конкретных задач. Программа 08 является заменой программам 04 и 07, но их пришлось оставить для совместимости со старыми версиями ACL программ.

Метод подключения сложных специальных программ на языке Java к языку ACL удобен тем, что хотя основной расчет эти программы выполняют сами, но подготовку входных данных для расчета и обработку результатов расчета, а также их графическое представление удобнее и проще программировать на ACL. Конечно, всегда есть возможность делать связь между ACL и такими программами через файлы и операционную систему. Но это уже менее удобно и очень ограничивает автоматическое выполнение программ. Программа на языке ACL умеет запускать внешние программы, но она не знает когда они закончат, чтобы использовать результаты и программу надо останавливать сообщением с кнопками.

Однако, раньше подключение Java программ к программе на языке ACL требовало каждый раз заново компилировать программу интерпретатора, что не очень удобно, учитывая большой размер программы. А реализация связи внешних программ с ACL требует знания всего кода на языке Java. В конце концов я пришел к выводу, что иногда удобно подключать полностью внешние программы. Достаточно включить в интерпретатор только вызов некоторого стандартного java класса, который никак не связан с остальным кодом и прокомпилировать программу. А затем внешнюю программу можно разрабатывать отдельно и отдельно компилировать, но с такой же структурой папок. Такая программа должна получать входные данные из файла и в файлы же записывать результаты.

А когда программа готова, то файлы новых классов можно просто скопировать в jar архив vkACL и программа будет работать как внутренняя, оставаясь внешней. Удобство такого подхода еще и в том, что если внешняя программа не нужна, то файлы ее классов можно снова вынуть, или заменить на новые. То есть программа не растет в размере как снежный ком при добавлении новых внешних программ. Именно этим грешат все специализированные программы типа Матлаба. Такая технология реализована в двух последних программах 09 и 10.

Программа 09 используется для вызова внешних программ общего назначения, то есть полезных программ, которые разрабатывались независимо от ACL. Она реагирует на параметр [n] указывающий на вызов n-й внешней программы. Их может быть много и все они должны запускаться в конструкторе класса spexpro(n) в папке com.vks. Сейчас работает вызов #e [n=1;] _\09, который запускает мощный редактор текстов с большим числом функций и настроек, а именно, модифицированную копию программы vkNotepad.jar. Первоначально редактор брал имя файла для редактирования из первой строки файла vknpfile.txt в папке [tmp]. Записать нужное имя в этот файл можно с помощью ACL команд. Сейчас такой способ работает при [em=0;].

Программа была чуть переделана и теперь она умеет работать с файлом, имя которого можно просто напечатать командой #pr перед вызовом программы. Такой способ намного быстрее и проще. Он выполняется при [em=1;]. Старый способ можно больше не использовать, он сохранен для возможности работы старых программ. Кроме того, редактор в версиях после 1 февраля 2021 года реагирует на параметр [c]. Он работает в старом модальном режиме при всех значениях, кроме [c=0;]. При [c=0;] программа на языке ACL открывает редактор и идет дальше, не закрывая его. Такой режим можно использовать в коротких ACL программах для запуска нескольких копий редактора сразу.

18 марта 2022 года я добавил вызов #e [n=2;] _\09, который запускает тот же редактор, но практически в полном эквиваленте исходному редактору. Он сразу читает имя файла из последней печати по команде #pr и альтернативы нет. Также он не останавливает работу ACL программы, она всегда идет дальше. Зато он открывает окно, которое имеет независимую иконку. Предыдущая версия редактора иконку не имела, и если на экране открыто много окон, то окно редактора невозможно было найти пока не будут закрыты окна, которые его закрывают. Это было весьма неудобно при работе с многими окнами. Сейчас легко открыть много окон редактора и каждое будет иметь иконку.

C несколькими окнами можно будет работать после того, как ACL программа закончится. В противном случае она берет фокус на себя и окна редакторов фокус не получат. Возможность открыть сразу несколько копий редактора с одной копией JRE иногда может быть весьма полезной. В будущем возможно подключение других внешних программ (с другим номером). Предполагается, что все такие программы будут записываться в папку com.vks.

Программа 10 сделана аналогичным образом. Она запускает конструктор класса extpro(n) в папке com.vku. Что конкретно делает этот конструктор зависит от реализации. Все остальное можно разрабатывать и компилировать независимо от vkACL. Такая программа тоже может не иметь никакой связи с переменными и массивами ACL, а может и иметь, если при компиляции, например, объявить общие массивы должным образом. Она может получать входные данные из файла с названием, например, in.txt в папке tmp, а результат записывает в файл out.dat в той же папке. Но это не обязательно делать именно так, названия и папку можно менять как и способ обмена информацией. Фактически такой способ является универсальным и позволяет заменить все другие. Все математические расчеты можно оформить таким образом. Но неразумно переписывать старый код, поэтому этот способ ориентирован на будущее, а старые номера программ пока работают по старому.

В настоящее время я организовал 6 программ вычислений указанным выше способом, которые были использованы после того, как этот метод был реализован. При n=0 запускается программа (calcul). Я сам ее не пишу, она зарезервирована для сторонних пользователей и для программирования вычислительных процессов. Каждый пользователь может писать свою собственную программу как ему это нравится. При n=1 запускается программа (xmdl) из соответствующего класса. Она делает расчет многоволновой дифракции в случае Лауэ. При n=2 запускается программа (calc), которая также написана в своем классе. Эта программа использует некоторые классы основной программы, например, комплексную арифметику. Она задумана как набор вычислений с большими циклами, которые имеют настолько специальный характер, что нет смысла добавлять новые операции в команду #ma или в программы с номерами 04, 07, 08. Вообще говоря. она может вычислять любую математику и программы с номерами до 09 уже не нужны. Но пока все есть как есть. Есть специальное описание того, что и как выполняет данная программа.

При n=3 запускается программа (xmdswt). Она делает расчет многоволновой дифракции сферической волны. Она дополнительно использует реальный массив основной программы для экономии памяти при работе с большими массивами. При n=4 запускается программа (takagi). Она использовалась в цикле работ по Лауэ дифракции в толстом кристалле, имеющем неровную выходную поверхность. При n=5 запускается программа (emls4), которая выполняет рассылку электронной почты. Для работы этой программы потребовалось расширение виртуальной машины, то есть классы, которые предлагаются отдельно от JRE. Она сделана так, что работает с внешними файлами, а дополнительный ACL код позволяет упростить работу по подготовке этих файлов.

Вопрос о том какой размер массива mi.da[] нужно использовать при компиляции внешней программы остался открытым. Должен ли он совпадать с размером массива в версии vkACL или нет. Иногда программа работает при несовпадении, иногда нет. Сейчас существуют три версии vkACL с разными размерами массива r(), нужно ли иметь три версии классов дополнительной программы -- ответ пока не найден. Пока я в основном использую массив размером 26 М в обоих случаях. При исправлении какого-то внутреннего класса программы vkACL и не только надо делать bat файл таким образом, чтобы в нем уничтожалась цепочка классов до того класса, который вызывает новый класс. Остальные классы можно не трогать, они компилироваться не будут и все будет быстро.

Для компиляции программ, подключаемых по 9-му и 10-му номерам я открыл папку [Java] в папке Java кода программы. Но эти же программы можно скомпилировать и как совершенно отдельные, не связанные с интерпретатором. Для таких программ я открыл папку [Java-s] в папке программы. Если кого-то интересует какую структуру имеют эти папки, то пишите мне письмо, я могу выслать. Публиковать это в интернете нет смысла, желающих все равно будет мало. Вообще-говоря Java-код таких программ имеет небольшой размер, и можно включать все программы в интерпретатор без проблем, даже если они и не будут никем использоваться. Сам я ими пользуюсь и выделять их каждый раз просто не хочется, жалко времени.