如何創建一個狀態機的應用程序,是比較簡單的,如果把你的應用程序改造成狀態機是比較困難的,換個說法,如何把應用程序優雅的用狀態機實現,這有點考驗你對項目需求和狀態機兩方面的理解能力。這一篇我們只講把一個簡單的應用編程一個狀態機應用程序。
第一步,就是枚舉信號,也就是整個狀態機應用里面用到的所有信號都枚舉出來。如下:
注意下,第一個信號A_SIG 的默認值是Q_USER_SIG,也就是說他是第一個Q_USER_SIG信號,而狀態機本身是有幾個被默認信號的,Q_ENTRY_SIG/Q_EXIT_SIG/Q_INIT_SIG,這幾個默認的信號已經在QEP處理器中被事先定義好了:
第二步,定義事件類型,QEP有默認的事件類型,叫QEvt,他只提供一個最簡單的類型,或者說是事件處理器需要的類型,實際應用中你可能需要一個事件帶有其它的參數,這時候你需要繼承QEP的默認事件來創建你的事件類型。這兩種情況給出官方定義的兩種事件類型的例子如下:
第三步、派生狀態機類型,這個詞在C++中用來還是比較合適,針對C來講,我們暫且稱之為定義狀態機類型。
第四步、聲明狀態處理函數。
第五步、實例化一個特定狀態機對象、以及實例化一個通用狀態機全局指針。
第六步、構造狀態機、類似于C++中的構造函數。
第七步、定義狀態處理函數。
到這里應該沒有遺漏的了,關于狀態機相關的內容編碼就完畢了,下面就是要真正的讓狀態機跑起來,你需要在main函數中進行一些操作,讓這個狀態機真正的運行起來,針對事件驅動型系統來講,狀態機本身是被動的,他不會主動進行任何操作,他需要事件處理器進行分發事件,然后根據分發的事件觸發狀態處理或轉換。
關于如何讓狀態機運行起來,我們需要在main函數中進行一下操作,還是拿這個例程為模板進行說明吧。
第一步、顯式調用ctor函數,構造狀態機。
第二步、顯式調用init函數,初始化狀態機。
第三步、采集輸入信號、構造事件對象、調用事件處理器,將相應的事件發送給狀態機。
以上步驟就完成了一個單一狀態機的編碼及應用。