ただし、以下の条件のいずれかを満たした場合に、オブジェクトはリアクティブと見なされます。
オブジェクトがリアクティブである場合に、RiCReactive オブジェクトのインスタンスが、そのオブジェクトの構造にデータ・メンバーとして値で埋め込まれている。 例:
typedef struct Furnace Furnace;
struct Furnace {
RiCReactive ric_reactive;
/* attributes of Furnace */
};
RiCReactive は、リアクティブ・オブジェクトのイベント処理の振る舞いを定義するために IBM® Rational® Rhapsody® Developer for C フレームワークによって提供される抽象データ型です。
各リアクティブ・オブジェクトごとに、ステートチャート実装の一部として定義される関数へのポインターを入れるために、追加の struct が実装ファイルに定義されます。 このポインターが、同じオブジェクト・タイプのリアクティブ・メンバーに渡されます。
static const RiCReactive_Vtbl Furnace_reactiveVtbl = {
rootState_dispatchEvent,
rootState_entDef,
ROOT_STATE_SERIALIZE_STATES(rootState_serializeStates),
/* Violation of MISRA Rule 45 (Required): */
/* 'Type casting to or from pointers shall not be used.' */
/* The following cast is justified and is */
/* for Rational Rhapsody auto-generated code use only. */
(RiCObjectDestroyMethod) Furnace_Destroy,
NULL,
NULL,
NULL,
(RiCObjectCleanupMethod) Furnace_Cleanup,
(RiCObjectFreeMethod) FreeInstance
};
dispatchEvent()、entDef()、および serializeState() 関数は、フレームワークに定義されるハンドル・クローズ用ファイル (RiCHdlCls.c) に実装されます。 同様のタスクを実行する関数を定義して、必要に応じてそれらを仮想関数テーブル経由でプロジェクトにリンクさせることができます。 ただし、このトピックはこのサブジェクトの範囲を超えています。
リアクティブ・オブジェクトとそのオブジェクトが動かすステートチャートの初期設定は、オブジェクトの初期設定関数の一部として実行されます。 例えば、HomeHeatingSystem の Furnace オブジェクトに対して、以下のイニシャライザーは RiCReactive_init() を呼び出してリアクティブ・オブジェクトを初期設定します。その後、initStatechart() を呼び出してそのオブジェクトのステートチャートを初期設定します。
void Furnace_Init(Furnace* const me, RiCTask * p_task) {
RiCReactive_init(&me->ric_reactive, (void*)me,
p_task, &Furnace_reactiveVtbl);
/* relation initialization loop */
initStatechart(me);
}
RiCReactive_init() 関数と initStatechart() 関数が、Rational Rhapsody フレームワークに定義されます。
イニシャライザーへの 2 番目のパラメーター p_task は、関連したイベント・キューを使用するタスクへのポインターで、そのタスクからリアクティブ・オブジェクトはイベントを処理します。 リアクティブ・オブジェクトが順次オブジェクトの場合、このタスクはシステム・スレッドで、リアクティブ・オブジェクトがアクティブの場合、このタスクはそのオブジェクトのスレッドです。 詳細については、アクティブ・オブジェクトと並行性を参照してください。