列入轉移程式碼

CG::Class::ComplexityForInlining 內容指定容許列入的使用者程式碼中的行數上限。預設值是 3

關於這項作業

使用者程式碼是狀態圖中轉移的動作組件。例如,如果使用的值是 3,則會將含有由 3 個或更少程式碼行組成之動作的所有轉移,自動列入在進行呼叫的函數中。

列入是使用組成函數主體的實際程式碼陳述式,取代所產生程式碼中的函數呼叫。此方法可最佳化程式碼執行,但是代價是程式碼大小略微增大。例如,如果將可以列入的行數從 3 增加到 5,則最多可以將程式碼執行時間縮短 10%。

例如,在 HomeHeatingSystem 物件的狀態圖中,systemControl 狀態具有逾時的輸出轉移,其含有下列動作組件:

if(IS_IN(&me->theFurnace,Furnace_starting))
   RiCGEN(&me->theFurnace,motorReady());

如果 Furnace 處於啟動狀態,則此動作會將 motorReady() 事件從 HomeHeatingSystem 傳送至 Furnace

如果 ComplexityForInlining 內容設定為 0(預設值),則會在 HomeHeatingSystem 物件之 systemControl 狀態的 takeEvent() 作業中產生轉移程式碼,如下所示:

int HomeHeatingSystem_systemControl_takeEvent(
HomeHeatingSystem* const me, short id) {
    int res = eventNotConsumed;
    if(id == Timeout_id)
    {
      if(RiCTimeout_getTimeoutId((RiCTimeout*)
         me->ric_reactive.current_event) ==
            HomeHeatingSystem_Timeout_systemControl_id)
      {
         NOTIFY_TRANSITION_STARTED(me,HomeHeatingSystem,
            "1");
         HomeHeatingSystem_systemControl_exit(me);
         {
            /*#[ transition 1 */
            if(IS_IN(&me->theFurnace,Furnace_starting))
               RiCGEN(&me->theFurnace, motorReady());
            /*#]*/
         }
         systemControl_entDef(me);
         NOTIFY_TRANSITION_TERMINATED(me,
            HomeHeatingSystem,"1");
         res = eventConsumed;
      }
   }
   return res;
}

HomeHeatingSystem 物件之 rootStatedispatchEvent() 作業會呼叫 takeEvent() 作業,如下所示:

static int rootState_dispatchEvent(
   void * const void_me, short id) {
   HomeHeatingSystem * const me =
      (HomeHeatingSystem *)void_me;
      int res = eventNotConsumed;
      switch (me->rootState_active) {
         case HomeHeatingSystem_systemControl:
         {
            res =
               HomeHeatingSystem_systemControl_takeEvent(
                  me, id);
            break;
         };
      default:
         break;
   };
   return res;
}

不過,如果 ComplexityForInlining 設定為 3,例如因為動作程式碼少於 3 行,則它會在 rootStatedispatchEvent() 作業中直接產生,並取代 takeEvent() 呼叫,如下所示:

static int rootState_dispatchEvent(void * const void_me,
   short id) {
   HomeHeatingSystem * const me = (HomeHeatingSystem *)
      void_me;
   int res = eventNotConsumed;
   switch (me->rootState_active) {
      case HomeHeatingSystem_systemControl:
      {
         if(id == Timeout_id)
         {
            if(RiCTimeout_getTimeoutId(
               (RiCTimeout*) me
               ->ric_reactive.current_event) == 
               HomeHeatingSystem_Timeout_systemControl_id)
            {
            NOTIFY_TRANSITION_STARTED(me,HomeHeatingSystem,
               "1");
            RiCTask_unschedTm(me->ric_reactive.myTask,
               HomeHeatingSystem_Timeout_systemControl_id,
               &me->ric_reactive);
            NOTIFY_STATE_EXITED(me,HomeHeatingSystem,
               "ROOT.systemControl");
            {
               /*#[ transition 1 */
               if(IS_IN(&me->theFurnace, Furnace_starting))
                  RiCGEN(&me->theFurnace,motorReady());
               /*#]*/
            }
         }
         /* rest of dispatchEvent() */
}

意見回饋