Описание пользователя
Глава 3. Использование стандартных модулей автокомпиляции
§3.7. Краткий перечень вводимых в модель описаний и реакций на события
Перечисляются все возможные реакции на события, которые пользователь может ввести в автокомпилируемую модель блока, и кратко описываются их параметры. Рассматривается общая структура формируемой модулем автокомпиляции программы и место пользовательских описаний в ней.
§3.7.1. Дополнительные описания, вводимые в модель
Рассматриваются три группы описаний, которые пользователь может вставить внутрь формируемой модулем автокомпиляции программы. Они могут содержать описания типов, функций, глобальных переменных и констант, дополнительных полей класса блока, команды включения файлов заголовков и т.п.
Помимо реакций на события, происходящие с блоком в схеме, в модель могут быть вставлены различные описания пользователя: описания типов и классов, служебные функции, команды включения различных файлов заголовков и т.п. Модуль автокомпиляции предоставляет три точки для вставки таких описаний внутрь автоматически формируемой программы модели: глобальные описания, описания внутри класса блока и описания после класса блока. Тексты всех этих описаний вводятся на вкладке «» в соответствующих подразделах раздела «».
Внутри формируемого текста эти три точки вставки описаний размещены следующим образом (ниже они выделены цветом):
#include <windows.h> #include <stdlib.h> #include <math.h> #include <float.h>
#include <RdsDef.h> #define RDS_SERV_FUNC_BODY rdsbcppGetService #include <RdsFunc.h> #include <CommonBl.h> #include <CommonAC.hpp> …
class rdsbcppFunction0G : public rdsbcppFunction // Global
{ … }
class rdsbcppFunction0L : public rdsbcppFunction // Local
{ … }
…
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason,void *lpReserved) { … }
// Type char ("S")
RDSBCPP_STATICPLAINCLASS(rdsbcstSignal,char);
// Dynamic of type double ("D")
RDSBCPP_DYNAMICPLAINCLASS(rdsbcdtDouble,double,"D");
…
//----------------------------------------
// Block class
//----------------------------------------
class rdsbcppBlockClass
{ public:
// RDS internal block data structure
RDS_PBLOCKDATA rdsbcppBlockData;
// Dynamic variables
rdsbcdtDouble DynTime;
// Static variables
rdsbcstSignal Start;
rdsbcstSignal Ready;
// Objects for block functions (share their names with the global ones)
rdsbcppFunction0L rdsfuncControlValueChanged;
…
// Vars initialization
void rdsbcppInitVars(void *base)
{ … };
// Check for dynamic vars existance
BOOL rdsbcppDynVarsOk(void){return DynTime.Exists();};
// Setup params load
char *rdsbcppLoadParameters(char *rdsbcpp_Text);
// Setup params save
void rdsbcppSaveParameters(void);
// Open setup window
BOOL rdsbcppShowSetupWindow(void);
// Event reaction functions
void rdsbcppModel(void);
…
}; // class rdsbcppBlockClass //----------------------------------------
// Setup parameters load
char *rdsbcppLoadParameters(char *rdsbcpp_Text)
{ … }
// Setup parameters save
void rdsbcppSaveParameters(void)
{ … }
…
extern "C" __declspec(dllexport)
int RDSCALL rdsbcppBlockEntryPoint(
int CallMode,RDS_PBLOCKDATA BlockData,
LPVOID ExtParam)
{ … }
// One simulation step
void rdsbcppBlockClass::rdsbcppModel(void)
{ … }
…
Глобальные описания пользователя размещаются после команд включения стандартных файлов заголовков и специализированных заголовков RDS, поэтому в них можно использовать все стандартные типы, константы и структуры Windows API (LPVOID, HANDLE, HWND и т.п.) Можно также использовать любые стандартные типы, константы и структуры RDS (RDS_BHANDLE, RDS_BLOCKDATA и т.п.) В глобальных описаниях нельзя ссылаться на объекты, создаваемые для работы с функциями блока (см. §3.6.13) и на класс блока rdsbcppBlockClass – все эти описания располагаются после глобальных описаний пользователя. Чаще всего в глобальные описания включают:
- команды включения файлов заголовков – как стандартных, так и пользовательских;
- глобальные переменные пользователя;
- описания типов и структур, используемых только в одной модели (если они используются в нескольких, имеет смысл записать их в отдельный файл и включать его в разных моделях, как в примере из §3.6.13.2);
- пользовательские функции общего назначения, которым не нужен доступ к переменным блока, его настроечным параметрам и к объектам для вызова функций у других блоков.
Описания пользователя в классе блока размещаются в самом конце класса, объект которого будет создаваться для каждого блока с данной моделью. Все описания типов и объявления переменных и стандартных полей класса на этот момент уже сделаны, поэтому в описаниях внутри класса можно ссылаться на любые объекты и типы. Любые функции, объявленные в этих описаниях, становятся функциями-членами класса блока, поэтому по имени их можно будет вызывать только из других функций-членов и из реакций на события (чтобы вызвать такую функцию из глобальной функции, необходимо как-то передать в нее указатель на объект класса блока, доступный внутри функций-членов через ключевое слово this). Чаще всего в описания внутри класса включают:
- пользовательские поля класса блока, если они нужны (нужно следить за тем, чтобы их имена не совпадали с именами переменных блока, настроечных параметров и прочих автоматически добавляемых в класс объектов);
- пользовательские функции, которым нужен доступ к переменным или настроечным параметрам блока, и которые будут вызываться из функций реакции на события;
- пользовательские функции, изнутри которых будут вызываться функции других блоков (см. §3.6.13.5).
Описания пользователя после класса блока, как следует из их названия, размещаются после класса блока и нескольких его служебных функций. К этому моменту все служебные объекты модели уже описаны, и в описаниях можно на них ссылаться. Чаще всего здесь размещают:
- пользовательские функции общего назначения, которым нужен доступ к объектам для вызова функций других блоков (см. пример функции обратного вызова в §3.6.13.3);
- тела функций-членов класса, которые разработчик по какой-либо причине решил вынести за пределы самого класса (при этом в описаниях внутри класса все равно должны находиться их заголовки).
Все три точки вставки пользовательских описаний располагаются в тексте программы до функций реакции на события, поэтому в функциях реакции можно пользоваться любыми объектами из этих описаний.