1 源碼
rstplib.1.1.02/statmch.c,statmch.h
2 功能
提供了快速生成樹中所有狀態機的一個抽象,類似於面向對象編程中的基類。
3 代碼簡析
3.1 數據結構
/* 通用狀態機 */
typedef struct state_mach_t {
struct state_mach_t* next; // 下一狀態機
Bool changeState; // 狀態變化標誌
unsigned int State; // 當前狀態
void (* concreteEnterState) (struct state_mach_t * ); // 執行進入某狀態後的固定動作
Bool (* concreteCheckCondition) (struct state_mach_t * ); // 檢查狀態倒換條件並完成狀態倒換
union {
struct stpm_t* stpm; // 指向本狀態機所屬網橋
struct port_t* port; // 指向本狀態機所屬端口
void * owner; // 指向本狀態機的創建者,可能是某端口,也可能是某網橋
} owner;
} STATE_MACH_T;
3.2 核心宏
/* 將某具體狀態機(由WHAT填入狀態機名稱,加##不展開WHAT,參見《宏中"#"和"##"的用法》)添加到this下面附帶的狀態機鏈表中,其中this視此宏應用場合不同而定,可能指向端口或網橋*/
#define STP_STATE_MACH_IN_LIST(WHAT) /
{ /
STATE_MACH_T* abstr; /
/* 創建狀態機,關聯執行函數、檢測函數,登記狀態機屬主(this)*/
abstr = STP_state_mach_create (STP_##WHAT##_enter_state, /
STP_##WHAT##_check_conditions, /
STP_##WHAT##_get_state_name, /
this, /
#WHAT); /
abstr->next = this->machines; /
this->machines = abstr; / // 通過指針修改將此狀態機加入狀態機鏈表
this->WHAT = abstr; / // 更新this的具體狀態機指針指向此狀態機
}
3.3 實現
/* 創建狀態機 */
STATE_MACH_T * STP_state_mach_create (void (*concreteEnterState) (STATE_MACH_T*),
Bool (*concreteCheckCondition) (STATE_MACH_T*),
char *(*concreteGetStatName) (int),
void *owner, char *name)
{
STATE_MACH_T *this;
STP_MALLOC(this, STATE_MACH_T, "state machine"); // 分配內存空間
this->State = BEGIN;
/* 複製狀態機名稱字符串,所需空間由malloc()分配且可以由free()釋放 – strdup() */
this->name = (char*) strdup (name);
this->changeState = False;
/* 關聯狀態機對應的具體函數 */
this->concreteEnterState = concreteEnterState;
this->concreteCheckCondition = concreteCheckCondition;
this->concreteGetStatName = concreteGetStatName ;
/* 登記屬主 */
this->owner.owner = owner;
return this;
}
/* 刪除狀態機 */
void STP_state_mach_delete (STATE_MACH_T *this)
{
free (this->name); // 釋放狀態機名稱字符串所佔空間
STP_FREE(this, "state machine"); // 釋放狀態機空間
}
/* 檢查倒換條件 */
Bool STP_check_condition (STATE_MACH_T* this)
{
Bool bret;
bret = (*(this->concreteCheckCondition)) (this); // 調用具體檢查倒換函數
if (bret) {
this->changeState = True; // 狀態有變
}
return bret;
}
/* 狀態機更新,在生成樹更新函數中被調用 */
Bool STP_change_state (STATE_MACH_T* this)
{
register int number_of_loops;
for (number_of_loops = 0; ; number_of_loops++) {
if (! this->changeState) return number_of_loops; // 狀態無變化則返回
(*(this->concreteEnterState)) (this); // 進入當前態,執行對應動作
this->changeState = False; // 復位狀態變化標誌
STP_check_condition (this); // 檢查倒換條件並執行倒換,更新狀態變化標誌
}
return number_of_loops;
}
/* 狀態機狀態倒換 */
Bool STP_hop_2_state (STATE_MACH_T* this, unsigned int new_state)
{
this->State = new_state; // 更新狀態
this->changeState = True; // 置位狀態倒換標誌
return True;
}
4 網橋、端口、狀態機關係圖