QM 5.1.3
$declare${}

The $declare${<model-item>} directive requests generating a declaration of the <model-item> specified between the parentheses. QM can generate declarations for the following item types: Class, Free Attribute, Free Operation, and Package.

Example of a Class with a State Machine

Class Declaration in C++

In C++, the directive $declare${<Class>} generates the C++ class declaration, which has a generic form class <Class> : public <Superclass> {...};. For instance, the code snipped below shows the code generated by the directive $declare${AOs::Ship} for the class AOs::Ship shown in the screen shot above:

//${AOs::Ship} ...............................................................
class Ship : public QP::QMActive {
private:
uint8_t m_x;
uint8_t m_y;
uint8_t m_exp_ctr;
uint16_t m_score;
public:
Ship();
protected:
static QP::QState initial(Ship * const me, QP::QEvt const * const e);
static QP::QState active (Ship * const me, QP::QEvt const * const e);
static QP::QState active_i(Ship * const me);
static QP::QMState const active_s;
static QP::QState parked (Ship * const me, QP::QEvt const * const e);
static QP::QMState const parked_s;
static QP::QState flying (Ship * const me, QP::QEvt const * const e);
static QP::QState flying_e(Ship * const me);
static QP::QMState const flying_s;
static QP::QState exploding (Ship * const me, QP::QEvt const * const e);
static QP::QState exploding_e(Ship * const me);
static QP::QMState const exploding_s;
};
Note
A class with a State Machine, such as Ship in the example above, contains also the (static) member functions and (static) attributes for each State of the state machine. These elements are specific to the state machine implementation strategy, which in this case is based on the QMsm base class from the QP/C++ framework.

Class Declaration in C (Header File)

In C, the directive $declare${<Class>} generates the C "class" declaration, which consists of a C struct with all the attributes of the class and associated C functions for all the operations (see also Application Note Simple Encapsulation and Inheritance in C).

Additionally, the specific rendering of a class declaration in C depends on the file-type context. Specifically, if the $declare${<Class>} directive is used in a header file (.h file), the declaration generates function prototypes without the static keyword, as shown in the code generated by the directive $declare${AOs::Ship} for the class AOs::Ship shown in the screen shot above:

/*${AOs::Ship} .............................................................*/
typedef struct {
/* protected: */
QMActive super;
/* private: */
uint8_t x;
uint8_t y;
uint8_t exp_ctr;
uint16_t score;
} Ship;
/* protected: */
QState Ship_initial(Ship * const me, QEvt const * const e);
QState Ship_active (Ship * const me, QEvt const * const e);
QState Ship_active_i(Ship * const me);
extern QMState const Ship_active_s;
QState Ship_parked (Ship * const me, QEvt const * const e);
extern QMState const Ship_parked_s;
QState Ship_flying (Ship * const me, QEvt const * const e);
QState Ship_flying_e(Ship * const me);
extern QMState const Ship_flying_s;
QState Ship_exploding (Ship * const me, QEvt const * const e);
QState Ship_exploding_e(Ship * const me);
extern QMState const Ship_exploding_s;
Note
A class with a State Machine, such as Ship in the example above, contains also functions and (extern) attributes for each State of the state machine.

Class Declaration in C (File Scope)

If the $declare${<Class>} directive is used in a file scope (inside a .c file), the declaration generates function prototypes with the static keyword, as shown in the code generated by the directive $declare${AOs::Ship} for the class AOs::Ship shown in the screen shot above:

Note
The use of the static keyword for all variables and functions declared at file scope is mandated by the Motor Industry Software Reliability Association (MISRA) guidelines.
/*${AOs::Ship} .............................................................*/
typedef struct {
/* protected: */
QMActive super;
/* private: */
uint8_t x;
uint8_t y;
uint8_t exp_ctr;
uint16_t score;
} Ship;
/* protected: */
static QState Ship_initial(Ship * const me, QEvt const * const e);
static QState Ship_active (Ship * const me, QEvt const * const e);
static QState Ship_active_i(Ship * const me);
static QMState const Ship_active_s = {
(QMState const *)0, /* superstate (top) */
Q_STATE_CAST(&Ship_active),
Q_ACTION_CAST(0), /* no entry action */
Q_ACTION_CAST(0), /* no exit action */
Q_ACTION_CAST(&Ship_active_i)
};
static QState Ship_parked (Ship * const me, QEvt const * const e);
static QMState const Ship_parked_s = {
&Ship_active_s, /* superstate */
Q_STATE_CAST(&Ship_parked),
Q_ACTION_CAST(0), /* no entry action */
Q_ACTION_CAST(0), /* no exit action */
Q_ACTION_CAST(0) /* no intitial tran. */
};
static QState Ship_flying (Ship * const me, QEvt const * const e);
static QState Ship_flying_e(Ship * const me);
static QMState const Ship_flying_s = {
&Ship_active_s, /* superstate */
Q_STATE_CAST(&Ship_flying),
Q_ACTION_CAST(&Ship_flying_e),
Q_ACTION_CAST(0), /* no exit action */
Q_ACTION_CAST(0) /* no intitial tran. */
};
static QState Ship_exploding (Ship * const me, QEvt const * const e);
static QState Ship_exploding_e(Ship * const me);
static QMState const Ship_exploding_s = {
&Ship_active_s, /* superstate */
Q_STATE_CAST(&Ship_exploding),
Q_ACTION_CAST(&Ship_exploding_e),
Q_ACTION_CAST(0), /* no exit action */
Q_ACTION_CAST(0) /* no intitial tran. */
};
Note
A class with a State Machine based on the QMsm base class, such as Ship in the example above, contains also static and const "transition-tables" objects, which must be initialized at the point of declaration. In this case (file scope), the declarations of "transition-tables" are also definitions followed by initializers.

Free Attribute Declaration

The $declare${<free-attribute>} directive requests generating a declaration of the <free-attribute> specified between the parentheses. (Free attribute is a variable declared outside of any class in a package). The following screen shot shows an example of a free attribute model item (in the Model Explorer) and a $declare${} code-generation directive in a file template.

Example of a Free Attribute Declaration

The following code snippet shows the C code generated by the $declare${AOs::AO_Ship} code-generation directive:

extern QActive * const AO_Ship;

The following code snippet shows the C++ code generated by the $declare${AOs::AO_Ship} code-generation directive. Please note the C++ namespace generated around the variable. This is because the enclosing package AOs provides the namespace GAME:

namespace GAME {
extern QP::QActive * const AO_Ship;
} // namespace GAME

Free Operation Declaration

The $declare${<free-operation>} directive requests generating a declaration of the <free-operation> specified between the parentheses. (Free operation is an operation declared outside of any class in a package). The following screen shot shows an example of a free operation model item (in the Model Explorer) and a $declare${} code-generation directive in a file template.

Example of a Free Operation Declaration

The following code snippet shows the C code generated by the $declare${AOs::do_bitmaps_overlap} code-generation directive:

/*${AOs::do_bitmaps_overl~} ................................................*/
uint8_t do_bitmaps_overlap(
uint8_t bmp_id1,
uint8_t x1,
uint8_t y1,
uint8_t bmp_id2,
uint8_t x2,
uint8_t y2);

The following code snippet shows the C++ code generated by the $declare${AOs::do_bitmaps_overlap} code-generation directive. Please note the C++ namespace generated around the function. This is because the enclosing package AOs provides the namespace GAME:

namespace GAME {
//${AOs::do_bitmaps_overl~} ..................................................
bool do_bitmaps_overlap(
uint8_t bmp_id1,
uint8_t x1,
uint8_t y1,
uint8_t bmp_id2,
uint8_t x2,
uint8_t y2);
} // namespace GAME

Package Declaration

The $declare${<Package>} directive requests generating a recursive declaration of all classes, free attributes, and free operations in the <Package>, as described in the sections above. (If a package contains other packages, these packages are recursively declared, as described in the first sentence.)

Note
The QM™ code generator honors the order of the items in the package (as viewed in the Model Explorer).

Next: $define${}