Навигация:
<< >> Оглавление Указатель

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

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

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

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

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

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

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

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

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

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

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

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

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.(block);

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

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

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

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

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


<< >> Оглавление Указатель