Главная

Уровни

Главная
SINT
Ликбез
Уровни
Монитор
Код

Карта

Уровни программирования




Назад...   Далее...

Напомним, что в SINT все модули разделяются на четыре логических уровня:

  • Аппаратный: объекты (функции и данные), реализация и интерфейс которых зависит от ЭВМ пользователя (система команд процессора, операционная система и т.п.).
  • Системный: низкоуровневые объекты, код которых никак не зависит от специфики аппаратной части.
  • Прикладной: объекты, предназначенные для прикладного программиста. Защищены от возможности их неквалифицированного использования. Допускается наличие синонимов имён объектов.
  • Инструментальный: является фактически подмножеством прикладного, но для них отсутствует "защита от дурака".

Первые два уровня образуют серверную часть или ядро программного обеспечения SINT, которое и выполняет, собственно, всю работу. Два последних уровня выполняют предписания программиста через запросы к ядру. Отметим, что обращение к объектам аппаратного уровня производится только из системного. Все уровни, кроме прикладного, рассчитаны на использование программистами достаточно высокой квалификации.

Прикладной уровень

Именно на этом уровне сосредоточена подавляющая часть кода разрабатываемого программного обеспечения. Объекты прикладного уровня обычно имеют мнемонику, облегчающую восприятие текста программистом и позволяющую автоматически определять необходимые параметры другим уровням: Read - копирование из устройства (обычно файла) в ОЗУ, Type - выдача на экран, Print - вывод на принтер и т.п. В именах объектов может быть скрыто понятие "текущее устройство" (Stream), работа с массивами данных фиксированной (Array) или переменной (String) длины, необходимость форматного преобразования данных при копировании (иллюстрацией может служить мнемоника стандартной функции printf). Для устройств обычно производится буферизация операций обмена данными. Объекты прикладного уровня взаимодействуют с остальными уровнями только через имена (Handle), но не через адреса (использование адресов допускается на инструментальном уровне).

Программирование в событиях

Если объектное программирование в SINT хоть как-то похоже на классическое толкование этого процесса (по крайней мере, и там, и там оно представляет собой описание неких структур данных), то программированиие в событиях вообще ни на что не похоже. Точнее, модули, созданные для программирования в событиях внешне почти неотличимы от модулей объектного программирования (это тоже структуры данных, обычно даже более простые), но написание программы с помощью событий радикально отличается от технологии объектного программирования.

С легкой руки Билла Гейтса, объект обработки сообщений, как правило, называют "окно". Поскольку Windows является одной из самых популярных систем, в которой реализована, хорошо отлажена и документирована технология работы с сообщениями, мы будем сравнивать наш подход именно с нею (при изложении концепций SINT мы будем использовать близкие по смыслу термины "меню" и "событие" соответственно). Хотя программирование в событиях в среде SINT резко отличается, в том числе и от принятой в среде Windows двухшаговой модели обработки сообщений. Скажем ещё наглее: мы полагаем, что такая модель идеологически непригодна для программирования в событиях. Мало того, что этот сервис относится (в терминологии SINT) к аппаратному уровню и, следовательно, обеспечивает переносимость кода разве что с Windows95 на WindowsXP. Более серьёзным возражением является то, что подход Windows представляет собой всего лишь "замаскированное" операторное программирование. Действительно, первичный обработчик каждой очереди сообщений Windows раздает их адресатам, у каждого из которых имеется собственный (вторичный) обработчик. Этот подход имеет сразу несколько весьма неприятных следствий. Во-первых, при отправке сообщения необходимо знать адрес (дескриптор) получателя. В SINT же все события обезличены, поэтому на момент отправления события адресат может вообще не существовать. Во-вторых, обезличенность событий позволяет SINT-программам иметь единственный обработчик "на все случаи жизни", а всю информацию, специфицирующую объекты реакции на события, вынести в виртуальные обработчики, т.е. в данные, которые могут находиться как внутри тела программы, так и вне его. Кроме того, большинство меню пользователя имеют один и тот же обработчик даже на уровне данных (управление курсором, клавиши Enter, Esc и т.п.). Программистом такой обработчик "по умолчанию" вообще не указывается - это дело конструктора соответствующего меню. Специализированные обработчики обычно перехватывают нескольких специальных событий, а обработку остальных наследуют от более универсальных.

Ещё более неприятное следствие подхода Windows состоит в том, что приходится прилагать значительные усилия, чтобы позволить программам свободно обмениваться сообщениями друг с другом или внешними устройствами, и в то же время максимально изолировать приложения, чтобы крах одного из них не вызвал крах других или всей системы: синхронизация очередей сообщений, контроль их доставки, перемещений внутри потоков, обработка аварийных ситуаций. Например, что делать с сообщениями, если окно-адресат закрывается? Ответ нелегко дать даже в философском плане. У Windows очередь таких сообщений просто сбрасывается. В технологии SINT диспетчер посылает очередное событие всегда текущему активному обработчику. Это позволяет направлять группу событий сразу многим обработчикам, при этом часть событий может быть предназначена для переключения обработчиков, осуществляя своего рода навигацию по ним. Под действием этой группы обработчики могут "рождаться", обрабатывать предназначенные им события и "умирать", передав остаток необработанных событий очередному обработчику.

У нас пока не возникало необходимости программирования многозадачных приложений, хотя техническая возможность создания нескольких процессов в рамках одного приложения имеется, и даже не очень сложна в реализации. Следует лишь помнить, что методы класса "функции" работают на одном и том же программном стеке, и при переключении процессов следует заботиться о сохранении и восстановлении данных этого стека. Внутри же одного процесса обработка событий в SINT также имеет радикальные отличия от той же Windows, касающиеся приоритетов. В обоих случаях обработка обычно происходит в порядке поступления (очередь). Что же касается асинхронных (срочных) событий, мы полностью отказались от управления последовательностью их обработки с помощью приоритетов: любое событие, даже имеющее наивысший приоритет, всегда можно при необходимости "обогнать". Это принципиально невозможно для Windows, где обработчик срочных сообщений вызывается "напрямую", и до окончания его обработки никакое другое сообщение не может быть обработано, т.е. объект реакции на событие не может иметь класс строка событий, что создает колоссальные трудности при программировании диалога (в SINT более половины всех объектов диалога принадлежат именно этому классу).

Проиллюстрируем технику программирования в событиях на примере. В уже написанной и сданной заказчику программе технологического контроля имелось два окна дампа памяти подключаемого к PC электронного блока. Памяти разного типа, разного быстродействия и даже способа адресации. Заказчик просит переопределить клавиши PgUp и PgDn "серой" клавиатуры так, чтобы они листали оба дампа одновременно, сохранив при этом возможность раздельного пролистывания обычными клавишами PgUp, PgDn. Какой же код для этого нужно написать? Оказывается - никакой. Поскольку переход из одного дампа в другой и обратно уже реализован и происходит по нажатию клавиши Tab, оператор уже сейчас в состоянии последовательно нажать клавиши PgUp, Tab, PgUp, Tab, чтобы оба дампа пролистались на экран вверх. При этом с первой парой событий "разберётся" обработчик первого дампа, со второй - второго. Остается лишь помочь оператору, "нажав" на клавиши вместо него.

Заводим объекты GPgDn, GPgUp класса строка событий:
I16 GPgDnSE[] = { k_PgDn, k_Tab, k_PgDn, k_Tab, 0 };
I16 GPgUpSE[] = { k_PgUp, k_Tab, k_PgUp, k_Tab, 0 };

Подключаем объекты к "серым" клавишам в наследуемую (общую) область обработчиков событий обоих дампов:
k_GPgDn, GPgDn, k_PgUp, GPgUp,

Вот и всё. Процедура (а что же ещё?) синхронного листания дампов написана, и даже отлажена - ошибиться здесь просто негде. При некотором навыке весь процесс занимает около 5 минут. Реализация подобной задачи средствами операторного программирования потребовала бы нескольких дней работы программиста гораздо более высокой квалификации!

Программирование в шаблонах

Важнейшим следствием принятой в SINT концепции объектного программирования является возможность вызова объектов SINT-программ по имени из внешних файлов. Иными словами, появляется возможность создания в этих файлах собственных методов обработки данных средствами готового приложения (разумеется, за исключением методов класса функции), т.е. в распоряжении программиста имеется возможность почти полноценного программирования на уровне шаблонов или методов, хранимых в базах данных. Строго говоря, термин "программирование" не очень подходит для шаблонов, поскольку они представляют собой обычные текстовые файлы, редактирование которых осуществляется с помощью любого текстового редактора. Их первоначальная функция заключалась просто в формировании внешнего вида выходных HTML-документов при генерации динамических веб-страниц с результатами обращения к расположенным в Интернет базам данных. Но шаблоны оказались настолько удобным средством разработки клиентских приложений, что их функциональная нагрузка стала очень быстро возрастать. Был разработан специальный язык команд шаблонов, т.е. шаблоны стали играть роль программируемых приложений.

Язык шаблонов разрабатывался нами скорее для внутреннего потребления и, разумеется, всерьёз говорить о его синтаксисе и функциональных возможностях нельзя. Тем не менее, он позволял создавать на уровне шаблонов вполне полноценные алгоритмы обработки данных: арифметические и логические операции, сравнение, копирование, условные и безусловные переходы, циклы, "вызов" вложенных шаблонов. Допустим и прямой вызов методов SINT-программы, если для них разрешена возможность внешнего вызова. Например, смена языка интерфейса извне выглядит примерно так:
#run ChangeLang (Russian);

Очевидно, что шаблоны целесообразно использовать для создания "макетных образцов" SINT-компонентов, отладки их логики исполнения и взаимодействия с другими модулями. Шаблоны образуют ещё один уровень программирования, более простой и надёжный, чем даже прикладной уровень.

Аппаратный уровень

Программирование на этом уровне практически совпадает с классическим толкованием этого термина. Разумеется, при этом следует придерживаться всех принятых в среде SINT соглашений о мнемонике. За правильное формирование платформо-зависимых блоков отвечает условная трансляция. Модули этого (и только этого) уровня могут иметь интерфейс, зависящий от используемой аппаратуры и/или системного программного обеспечения. Обращение к ним допускается только из системного уровня.

Системный уровень

Модули системного уровня обеспечивают групповую обработку объектов и событий, обслуживание ОЗУ, стеков различного назначения, обеспечивают прозрачность доступа к объектам для других уровней (например, при уплотнении памяти), динамический вызов объектов (т.е. количество, тип и порядок следования параметров могут быть неизвестны вызывающей функции ни при компиляции, ни даже в момент вызова). Значения многих аргументов не передаются в качестве входных параметров, а определяются самостоятельно как текущие значения (работа по паспортам). Это позволяет резко упростить интерфейс программиста, поскольку нет необходимости указывать, например, тип памяти (ОЗУ, HDD), тип группы (массив, кортеж, стек, очередь, список), размеры окна, палитру и т.д. Обращение к объектам системного уровня осуществляется с помощью команд, которые обычно скрыты в параметрах или именах вызывающих объектов. Таких команд на системном уровне совсем немного:

  • CALL - вызов метода (объекта класса функция, группа событий, меню и т.п.);
  • COPY - копирование, имеет модификатор FORMAT (форматное преобразование);
  • OPEN - установка связи с объектом, имеет модификатор CREATE (создание объекта);
  • CLOSE - разрыв связи с объектом, имеет модификатор DELETE (уничтожение объекта);
  • GET - получение сведений об объекте, имеет модификатор SET (установка параметров).

Объекты системного уровня, в свою очередь, могут обращаться с запросами к прикладному уровню при возникновении некоторых событий - обычно при ошибках исполнения команд. Обращение осуществляется вызовом текущего обработчика событий клиентской части (выдача диагностики, обращение к оператору и т.п.). Ответные команды системному обработчику событий (ABORT, CONTINUE, EXIT, RETRY) особых пояснений не требуют.
Назад...   Далее...

08.12.2017 20:43
 
`