直接插入过渡代码

CG::Class::ComplexityForInlining 属性指定允许在用户代码中直接插入的行数上限。缺省值为 3

关于此任务

用户代码是状态图中的过渡的操作部分。例如,使用值 3 时,操作代码行数不超过 3 行的所有过渡都将自动地直接插入到调用函数中。

直接插入是指,将生成的代码中的函数调用替换为构成函数主体的实际代码语句。此方法可以优化代码的执行,其代价是代码大小略微增大。例如,可以直接插入的行数由 3 增大到 5 可以将代码执行时间缩短,并且幅度可达 10%。

例如,在 HomeHeatingSystem 对象的状态图中,systemControl 状态具有在超时后进行的输出过渡,其操作部分如下所示:

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

此操作将 motorReady() 事件从 HomeHeatingSystem 发送到 Furnace(如果 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() */
}

反馈