Текущий раздел:

Описания RDS

Описание пользователя

Глава 3. Использование стандартных модулей автокомпиляции

§3.7. Краткий перечень вводимых в модель описаний и реакций на события

§3.7.5. Вызов функции блока

# Описание пользователя

## Глава 3. Использование стандартных модулей автокомпиляции

### §3.7. Краткий перечень вводимых в модель описаний и реакций на события

#### §3.7.5. Вызов функции блока

Описывается реакция на вызов функции блока, то есть на непосредственный вызов модели данного блока моделью другого.

Для каждой функции блока, добавленной в редактор модели (см. §3.5.5), модуль автокомпиляции автоматически добавляет в список событий реакцию на вызов этой функции. Текст этой реакции вводится на вкладке «события» левой панели редактора модели: раздел «мышь и клавиатура», подраздел с именем нужной функции (см. рис. 468). Написание реакций на вызовы функций подробно и с примерами рассматривается в §3.6.13, здесь же мы рассмотрим техническую сторону этих реакций.

В классе блока для реакции на вызов создается функция-член с именем, автоматически сформированным по имени объекта функции, которое пользователь ввел при ее добавлении в модель. В зависимости от того, есть ли у функции параметр, эта функция-член будет иметь два или три параметра. Если параметр у функции есть, созданная для реакции на ее вызов функция-член будет выглядеть так (цветом выделены части текста, зависящие от конкретной функции):

      // Block function call reaction "имя_функции"
      void rdsbcppBlockClass::имя_реакции(
                                тип_указателя_на_параметр Param,
                                RDS_PFUNCTIONCALLDATA FData,
                                int &Result)
      {
         … пользовательский текст реакции …
      }

В параметре Param находится указатель на параметр вызванной функции блока, переданный другой моделью в момент этого вызова. Параметром функции блока, если он есть, всегда должен быть какой-нибудь указатель, и тип этого указателя вводится при добавлении функции в модель (см. рис. 470, поле ввода «тип параметра функции»). Если, например, в качестве параметра функции было введено «TMyFuncParam*» (то есть «указатель на некоторую структуру TMyFuncParam»), Param в реакции тоже будет иметь тип TMyFuncParam*.

Параметр FData – это указатель на общую для всех функций структуру описания события RDS_FUNCTIONCALLDATA, из полей которой можно узнать, как и кем именно вызвана функция:

      typedef struct {
        int Function;       // Идентификатор функции в RDS
        LPVOID Data;        // Параметр функции
        int Reserved;       // Зарезервировано (не используется)
        RDS_BHANDLE Caller; // Вызвавший блок
        BOOL Broadcast;     // Вызов не одного блока, а нескольких
        int BroadcastCnt;   // Номер блока среди всех вызванных
        BOOL Stop;          // Прекратить вызов блоков (возврат)
        BOOL Delayed;       // Отложенный вызов
        DWORD DataBufSize;  // Размер буфера при отложенном вызове
      } RDS_FUNCTIONCALLDATA;
      typedef RDS_FUNCTIONCALLDATA *RDS_PFUNCTIONCALLDATA;

Поля этой структуры имеют следующий смысл:

Function(int)
  Уникальный целый идентификатор вызванной функции в RDS. Этот идентификатор присваивается функции автоматически. Его также можно в любой момент получить из объекта функции, создаваемого модулем автокомпиляции для работы с ней, при помощи функции-члена Id этого объекта.
Data(LPVOID)
  Указатель, являющийся параметром функции (NULL, если параметра нет). Значение этого поля совпадает с описанным выше параметром Param, за исключением типа: Param уже приведен к нужному типу, а поле Data – универсальный указатель типа void*. В автокомпилируемых моделях использовать это поле не имеет смысла, вместо него используется Param.
Caller(RDS_BHANDLE)
  Идентификатор вызвавшего функцию блока. Модель вызванного блока может использовать его для того чтобы, в свою очередь, вызвать у него какую-либо функцию в ответ.
Broadcast(BOOL)
  Значение TRUE в этом поле сигнализирует о том, что данная функция была вызвана сразу у нескольких блоков (см. §3.6.13.2), значение FALSE – что она вызвана только у данного блока (см. §3.6.13.3).
BroadcastCnt(BOOL)
  При Broadcast==TRUE в этом поле будет находиться порядковый (начинающийся с нуля) номер данного блока среди всех вызванных. Например, если функция вызвана у всех блоков какой-либо подсистемы, и в этой подсистеме находится три блока, при вызове первого из них в BroadcastCnt будет передан ноль, при вызове второго – 1, при вызове третьего – 2.
Stop(BOOL)
  Флаг прекращения вызова функции у группы блоков. Исходно в этом поле записано значение FALSE. При Broadcast==TRUE модель вызванного блока может записать в Stop значение TRUE, запретив тем самым вызов функции для оставшихся блоков. Таким образом можно, например, организовать поиск в подсистеме блока, выполняющего какие-либо действия: можно вызвать функцию у всех блоков подсистемы и написать реакцию на вызов этой функции так, чтобы первый же выполняющий ее блок произвел необходимые действия или сообщил вызвавшему блоку свой идентификатор, а затем прервал дальнейший перебор блоков и вызов их функций, присвоив Stop значение TRUE.
Delayed(BOOL)
  Значение FALSE в этом поле указывает на прямой вызов функции, значение TRUE – на отложенный. Отложенные вызовы не поддерживаются модулем автокомпиляции напрямую через объекты функций, но их можно выполнять при помощи обычных функций RDS (см. §2.13.5 руководства программиста).
DataBufSize(DWORD)
  При отложенном вызове функции в этом поле передается размер области данных, указатель на которую находится в поле Data.

Третий параметр функции реакции – это ссылка на целую переменную Result. Значение этой переменной возвращается вызвавшему блоку. Допустим, например, что в модель какого-то блока добавлена некоторая функция без параметров, в реакции на вызов которой записано:

      Result=123;

В модель другого блока добавлена та же самая функция, и объект для работы с ней назван MyFuncObject. Если идентификатор первого блока будет записан в переменной block (например, этот блок был найден по какому-то признаку перебором всех блоков подсистемы), то вызов

      int i=MyFuncObject.Call(block);

запишет в переменную i значение 123. По умолчанию в Result записано значение 0 – если в реакции на вызов функции Result ничего не будет присвоено, этот ноль там и останется и будет возвращен вызвавшему блоку.

Если у функции нет параметра, в функции-члене для нее просто будет отсутствовать параметр Param:

      // Block function call reaction "имя_функции"
      void rdsbcppBlockClass::имя_реакции(
          RDS_PFUNCTIONCALLDATA FData,
          int &Result)
      {
         … пользовательский текст реакции …
      }

Смысл оставшихся двух параметров остается тем же.

При написании моделей блоков без использования модуля автокомпиляции вызову любой функции блока соответствует константа RDS RDS_BFM_FUNCTIONCALL. При этом, чтобы понять, какая именно функция вызвана, программист должен сам анализировать значение поля Function в переданной в модель структуре RDS_FUNCTIONCALLDATA. Модуль автокомпиляции несколько упрощает работу, вставляя этот анализ в модель автоматически.