一种基于状态机(表)的小组件

  1 // .h
  2 typedef int (*state_action)(int state, int event);
  3 
  4 typedef struct state_trans{
  5     int next_state;
  6     state_action action;
  7 } state_trans_t,*pstate_trans_t;
  8 
  9 typedef struct fsm {
 10     int curr_state;
 11     int event_max;
 12     pstate_trans_t *pptrans_tbl;
 13     ak_mutex_t mutex;
 14 }fsm_t;
 15 
 16 
 17 int akp_fsm_ctor(fsm_t *this, pstate_trans_t *pptrans_tbl,int event_max);
 18 
 19 int akp_fsm_dector(fsm_t *this);
 20 
 21 int akp_fsm_on_event(fsm_t *this, int event);
 22 int akp_fsm_get_curr_status(fsm_t *this);
 23 
 24 // .c
 25 int akp_fsm_ctor(fsm_t *this, pstate_trans_t *pptrans_tbl,int event_max)
 26 {
 27     this->curr_state = 0;
 28     this->event_max = event_max;
 29     this->pptrans_tbl = pptrans_tbl;
 30     ak_thread_mutex_init(&(this->mutex),NULL);
 31 }
 32 
 33 int akp_fsm_dector(fsm_t *this)
 34 {
 35     this->pptrans_tbl = NULL;
 36     ak_thread_mutex_destroy(&(this->mutex));
 37 }
 38 
 39 int akp_fsm_on_event(fsm_t *this, int event)
 40 {
 41     int ret = 0;
 42 
 43     if(NULL == this->pptrans_tbl) {
 44         ak_print_error_ex("[state]: pptrans_tbl is null,pl ctor fsm
");
 45         return -1;
 46     }
 47 
 48     ak_thread_mutex_lock(&(this->mutex));
 49     int state = this->curr_state;
 50 
 51     //ak_print_normal("[state]: max=%d state=%d event=%d tbl=0x%x
",this->event_max,state,event,this->pptrans_tbl);
 52     pstate_trans_t ptrans = (*(this->pptrans_tbl+(this->event_max*state+event)));
 53     //ak_print_normal("ptrans %x
",ptrans);
 54     if(NULL != ptrans) {
 55         this->curr_state = ptrans->next_state;
 56         ret = ptrans->action(state,event); // must after change state
 57     } // else ignore this case
 58     else{
 59         ak_print_warning("[fsm]: ignore this case: curr state=%d,event=%d
",this->curr_state,event);
 60     }
 61     ak_thread_mutex_unlock(&(this->mutex));
 62 
 63     return ret;
 64 }
 65 
 66 int akp_fsm_get_curr_status(fsm_t *this)
 67 {
 68     return (this->curr_state);
 69 }
 70 
 71 
 72 // use
 73 static state_trans_t close2ready = {
 74     WIFI_ST_READY,   // next state
 75     __open      // action
 76 };
 77 static state_trans_t ready2work = {
 78     WIFI_ST_WORK,
 79     __start
 80 };
 81 static state_trans_t ready2close = {
 82     WIFI_ST_CLOSED,
 83     __close
 84 };
 85 static state_trans_t work2ready = {
 86     WIFI_ST_READY,
 87     __stop
 88 };
 89 static state_trans_t work2close = {
 90     WIFI_ST_CLOSED,
 91     __close
 92 };
 93 static state_trans_t ignore = {
 94     WIFI_ST_CLOSED,
 95     __close
 96 };
 97 
 98 
 99 static pstate_trans_t trans_tble[][WIFI_EV_MAX] = {
100                   /*EV_OPEN*/  /*EV_START*/  /*EV_STOP*/  /*EV_CLOSE*/ 
101 /*ST_CLOSED*/   &close2ready,  NULL,          NULL,          NULL,
102 /*ST_READY*/    NULL,          &ready2work,   NULL,          &ready2close,
103 /*ST_WORK*/     NULL,          NULL,          &work2ready,   &work2close
104 };
原文地址:https://www.cnblogs.com/mic-chen/p/9026315.html