For example, the following example is the prototype of the initializer generated for the object A:
void A_Init(struct A_t* const me);
The first argument is a constant pointer to the object being initialized. The const keyword defines a constant pointer in ANSI C. Passing a constant pointer as an argument allows the operation to change the value of the object that the pointer addresses, but not the address that the argument me contains.
The object initializer has the following responsibilities, which it performs in the following order:
Subobject initialization includes calling the initializers for each subobject of a composite object. In the case of arrays, the initialization of each subobject can include the $index keyword.
By default, the initializer has no arguments (other than the me argument). If you create an initializer with arguments, you can enter initial values for the arguments in the Object window. IBM® Rational® Rhapsody® generates initialization code for initializers with arguments from the values entered in the Object window.
Compositions are initialized with a call to initRelations() in the initializer of the parent. For example, the following initializer is generated for an object D that has a subobject E:
void D_Init(D* const me) {
initRelations(me);
}
The initRelations() call in D's initializer calls the initializer for E:
static void initRelations(D* const me) {
E_Init(&me->E);
}
If subobjects are implemented as an array (for example, because the subobject has a numeric multiplicity greater than one), the subobjects are initialized using a while() loop in the initRelations() operation. For example, if E's multiplicity is two, E is implemented as a two‑element array inside D. The following example of a while() loop is generated in D's initRelations() operation to initialize both instances of E:
static void initRelations(D* const me) {
E_Init(&(me->E));
{
RhpInteger iter = 0;
while (iter < 5){
E_Init(&((me->itsE)[iter]));
iter++;
}
}
}
If related objects are not components of a composite object, you can have the main program instantiate one of the objects by selecting it as an initial instance (in the Initialization tab for the configuration). In that initializer for the object, you can create the related object explicitly and then set the link to it. For example, if an object A and an object B are related and the main() function instantiates A as an initial instance, then in the body of A's initializer you can write the following code to set its link to B:
B *itsB = B_Create(); A_setItsB(me, itsB);
Setting a link to a to‑many relation involves calling the initializer for the container. In the following code, the call to RiCCollection_Init() sets the Furnace's link to three itsRooms. Passing a value of RiCTRUE to RiCCollection_setFixedSize() says that the collection is of fixed size:
void Furnace_Init(Furnace* const me, RiCTask * p_task) {
RiCReactive_init(&me->ric_reactive, (void*)me,
p_task, &Furnace_reactiveVtbl);
RiCCollection_Init(&me->itsRoom, 3);
NOTIFY_REACTIVE_CONSTRUCTOR(me, NULL, Furnace,
Furnace, Furnace(), 0, Furnace_SERIALIZE);
{
RiCCollection_setFixedSize(&me->itsRoom,
RiCTRUE);
}
initStatechart(me);
NOTIFY_END_CONSTRUCTOR(me);
}
The NOTIFY_CONSTRUCTOR() and NOTIFY_END_CONSTRUCTOR() calls are instrumentation macros generated when animation is enabled. The first macro notifies the animator when the initializer has been called and creates an animation instance. The second macro notifies the animator when the initializer is about to exit.
User code entered for the constructor include initializations of the attributes of the object. You can specify the actual value for every parameter in the object constructor. The actual value is inserted verbatim as uninterpreted text.
User code is generated between the /*#[ and /*#] symbols in the code. For example, you could enter the following code in the Implementation field for the initializer:
RiCString temp; RiCString_Init(&temp, "Hello World"); A_print(me, temp);
This code is implemented as follows:
void A_Init(struct A_t* const me) {
NOTIFY_CONSTRUCTOR(me, NULL, A, A, A(), 0,
A_SERIALIZE);
me->itsB = NULL;
{
/*#[ operation A() */
RiCString temp;
RiCString_Init(&temp, "Hello World");
A_print(me, temp);
/*#]*/
}
NOTIFY_END_CONSTRUCTOR(me);
}