⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 watch.c

📁 用于协议状态机的编程参考
💻 C
字号:
/** * Simple digital watch example * M. Samek, 01/07/00 */
#include <assert.h>
#include <stdio.h>
#include "hsm.h"

typedef struct Watch Watch;
struct Watch {
  Hsm super;
  State timekeeping, time, date;
  State setting, hour, minute, day, month;
  State *timekeepingHist;
  int tsec, tmin, thour, dday, dmonth;
};

enum WatchEvents {
  MODE_EVT,
  SET_EVT,
  TICK_EVT
};

void WatchShowTime(Watch *me) {
  printf("time: %2d:%02d:%02d",   me->thour, me->tmin, me->tsec);
}

void WatchShowDate(Watch *me) {
    printf("date: %02d-%02d", me->dmonth, me->dday);
}

void WatchTick(Watch *me) {
  static int const month[] = { 
     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 
  };
  if (++me->tsec == 60) {
    me->tsec = 0;
    if (++me->tmin == 60) {
      me->tmin = 0;
      if (++me->thour == 24) {
        me->thour = 0;
        if (++me->dday == month[me->dmonth-1]+1) {
          me->dday = 1;
          if (++me->dmonth == 13) 
            me->dmonth = 1;
        }
      }
    }
  }
}

Msg const *Watch_top(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case START_EVT:
    STATE_START(me, &me->setting);
    return 0;
  case TICK_EVT:
    if (++me->tsec == 60)
      me->tsec = 0;
    printf("Watch::top-TICK;");
    WatchShowTime(me);
    return 0;
  } 
  return msg;
}

Msg const *Watch_timekeeping(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case START_EVT:
    STATE_START(me, me->timekeepingHist);
    return 0;
  case SET_EVT:
    STATE_TRAN(me, &me->setting);
    printf("Watch::timekeeping-SET;");
    return 0;
  case EXIT_EVT:
    me->timekeepingHist = STATE_CURR(me);
    return 0;
  } 
  return msg;
}

Msg const *Watch_time(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case ENTRY_EVT:
    WatchShowTime(me);
    return 0;
  case MODE_EVT:
    STATE_TRAN(me, &me->date);
    printf("Watch::time-DATE;");        
    return 0;
  case TICK_EVT:
    printf("Watch::time-TICK;");        
    WatchTick(me);
    WatchShowTime(me);
    return 0;
  } 
  return msg;
}

Msg const *Watch_date(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case ENTRY_EVT:
    WatchShowDate(me);
    return 0;
  case MODE_EVT:
    STATE_TRAN(me, &me->time);
    printf("Watch::date-DATE;");        
    return 0;
  case TICK_EVT:
    printf("Watch::date-TICK;");        
    WatchTick(me);
    WatchShowDate(me);
    return 0;
  } 
  return msg;
}

Msg const *Watch_setting(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case START_EVT:
    STATE_START(me, &me->hour);
    return 0;
  } 
  return msg;
}

Msg const *Watch_hour(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case SET_EVT:
    STATE_TRAN(me, &me->minute);
    printf("Watch::hour-SET;");
    return 0;
  } 
  return msg;
}

Msg const *Watch_minute(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case SET_EVT:
    STATE_TRAN(me, &me->day);
    return 0;
  } 
  return msg;
}

Msg const *Watch_day(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case SET_EVT:
    STATE_TRAN(me, &me->month);
    printf("Watch::day-SET;");
    return 0;
  } 
  return msg;
}

Msg const *Watch_month(Watch *me, Msg *msg) {
  switch (msg->evt) {
  case SET_EVT:
    STATE_TRAN(me, &me->timekeeping);
    printf("Watch::month-SET;");
    return 0;
  } 
  return msg;
}

void WatchCtor(Watch *me) {
  HsmCtor((Hsm *)me, "Watch", (EvtHndlr)Watch_top);
  StateCtor(&me->timekeeping, "timekeeping", 
            &((Hsm *)me)->top, (EvtHndlr)Watch_timekeeping);
    StateCtor(&me->time, "time", &me->timekeeping, 
              (EvtHndlr)Watch_time);
    StateCtor(&me->date, "date", &me->timekeeping, 
              (EvtHndlr)Watch_date);
  StateCtor(&me->setting, "setting", &((Hsm *)me)->top, 
            (EvtHndlr)Watch_setting);
    StateCtor(&me->hour, "hour", &me->setting, 
              (EvtHndlr)Watch_hour);
    StateCtor(&me->minute, "minute", &me->setting, 
              (EvtHndlr)Watch_minute);
    StateCtor(&me->day, "day", &me->setting, 
              (EvtHndlr)Watch_day);
    StateCtor(&me->month, "month", &me->setting, 
              (EvtHndlr)Watch_month);
  me->timekeepingHist = &me->time; 

  me->tsec = me->tmin = me->thour = 0;
  me->dday = me->dmonth = 1;
}

const Msg watchMsg[] = { 
  MODE_EVT,
  SET_EVT,
  TICK_EVT
};
int main() {  Watch watch;         
  WatchCtor(&watch);
  HsmOnStart((Hsm *)&watch);  for (;;)  {    int i;
    printf("\nEvent<-");
      scanf("%d", &i);
      if (i < 0 || sizeof(watchMsg)/sizeof(Msg) <= i) 
        break;
      HsmOnEvent((Hsm *)&watch, &watchMsg[i]); 
  }  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -