處理內部轉移的事件
考慮下圖所示的狀態圖。
狀態A有一個內部轉移。轉移動作爲A_two。
狀態B有一個指向自身的外部轉移(自循環轉移self loop transition)。注意,這個不是內部轉移!後面將會看到差別。
初始化完成後,狀態A爲活動狀態。然後狀態圖進入休眠。
發生事件時,不轉移到外部狀態
假設條件C_one爲FALSE。
當事件E_one發生時,狀態圖被激活,該事件的處理步驟如下:
- 圖表根目錄檢查是否存在事件E_one的有效的轉換。檢測到從狀態
A
到狀態B的潛在有效轉換。但是,轉換無效,因爲條件[C_one]爲假
。 - 執行狀態A的during動作:durA()。
- 狀態
A
檢查其子狀態是否存在有效轉移,並檢測有效的內部轉移。 - 狀態
A
仍然保持爲活動狀態。執行內部轉移的轉移動作A_two
。因爲它是內部轉移,所以不執行狀態A的退出和進入動作。 - 圖表又回到睡眠狀態。
發生事件,轉移到外部狀態
還是上面那張圖。假設初始化已經完成,狀態A爲活動狀態。
但這一次,假設條件C_one爲TRUE。
當事件E_one發生時,狀態圖被激活,該事件的處理步驟如下:
-
圖表根目錄檢查是否存在事件
E_one的有效轉移
。從狀態
A
到狀態B的轉移現在是有效的,因爲條件[C_one]爲真
。 -
執行狀態
A的
退出動作:exitA()。 -
狀態
A
標記爲無效。 -
執行轉移動作:A_one
。 -
狀態B
標記爲活動。 -
執行狀態
B的進入
動作:entB()
。 -
圖表又回到睡眠狀態。
自循環外部轉移
還是這張圖。不過,起始條件不一樣。假設已經進入了狀態B。條件C_two爲FALSE。
當事件E_two發生時,狀態表被喚醒,該圖表從根向下的層次結構來處理事件:
-
圖表根目錄檢查是否存在事件E_two的有效的轉移。
檢測到從狀態
B
到狀態A的潛在有效轉移。但轉換無效,因爲條件[C_two]爲
假。但是,活動狀態B
具有有效的自循環轉移。 -
執行狀態
B
退出動作(exitB()
)並完成。 -
狀態
B
標記爲無效。 -
執行自循環轉移操作
A_four
,並完成。 -
狀態B
標記爲活動。 -
執行狀態
B的進入
動作(entB()
)並完成。 -
圖表又回到了睡眠狀態。
此序列完成了與事件E_two關聯的Stateflow圖表的執行。此示例顯示內部轉移和自循環轉移之間的行爲差異。
處理事件:包含指向節點的內部轉移
考慮以下狀態圖。父狀態A包括3個子狀態:A1,A2和A3。其中A1爲默認狀態。
同時,狀態A還有一個內部轉移,該內部轉移先指向一個結點,再根據條件轉移到子狀態。
切換子狀態的內部轉移
假設初始化已經完成,A1爲活動狀態。條件C_two爲TRUE。
事件E_one
發生並喚醒圖表,該圖表從根向下的層次結構來處理事件:
- 圖表檢查根級別是否存在事件E_one的有效轉移。沒有有效的轉移。
- 執行狀態A的during動作:durA()。
-
狀態
A
檢查自身是否存在有效轉移。檢測到有效的內部轉移,該轉移的目標對象是連接點。評估條件以確定其中一個轉換是否有效。因爲條件
[C_two]爲
真,經過連接點再到狀態A.
A2的內部轉移是有效的
。 -
執行狀態
A.
A1的退出動作:
exitA1()
。 -
狀態
A.
A1
被標記爲無效。 -
狀態A.
A2
標記爲活動。 -
執行狀態
A.
A2的進入動作:
entA2()
。 -
圖表又回到睡眠狀態。
不切換子狀態的內部轉移
現在,活動狀態是A2。條件C_two仍然爲TRUE。
事件E_one
發生並喚醒圖表,該圖表從根向下的層次結構來處理事件:
-
狀態圖檢查根級別是否存在事件E_one的有效轉移。沒有有效的轉移。
-
執行狀態A的during動作:durA()。
-
狀態
A
檢查自身的有效轉移,並檢測到指向連接點的有效內部轉移。評估條件以確定其中一個轉移是否有效。因爲條件
[C_two]
是真,經過結點然後到狀態A.A2的內部轉移是有效的。 -
執行狀態
A.
A2的退出動作:
exitA2()
。 -
狀態
A.
A2
被標記爲無效。 -
狀態
A.
A2
標記爲活動。 -
執行狀態
A.
A2的進入動作:
entA2()
。 -
圖表又回到睡眠狀態。
可以看出,對於具有有效內部轉移的狀態,活動子狀態可以先退出並立即重新進入。
指向歷史結點的內部轉移
考慮以下狀態圖。父狀態A包含2個子狀態A1和A2,並且還包含一個歷史狀態結點。當事件E_one發生時,狀態A發生內部轉移到該歷史狀態結點。
初始化完成後,狀態A.A1爲活動狀態。當事件E_one發生時,喚醒狀態圖,該圖從根向下的層次結構來處理事件:
-
狀態圖檢查根級別是否存在事件E_one的有效的轉移。沒有有效的轉移。
-
執行狀態
A的during動作:durA()
。 -
狀態
A
檢查自身是否存在有效轉移,並檢測到有效的指向歷史結點的內部轉移。根據歷史信息,最後一個活動狀態A.A1
是目標狀態。 -
執行狀態
A.A1的
退出動作exitA1()並完成。 -
狀態
A.A1
標記爲無效。 -
狀態A.A1
標記爲活動。 -
執行狀態
A.A1的
進入動作entA1()並完成。 -
圖表又回到了睡眠狀態。
同樣地,對於具有有效內部轉移的狀態,活動子狀態可以先退出並立即重新輸入。
參考資料
Process Events Using Inner Transitions
https://ww2.mathworks.cn/help/stateflow/ug/inner-transition-examples.html