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

📄 watch.cpp

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

class Watch : public Hsm {
  int tsec, tmin, thour, dday, dmonth;
protected:
  State timekeeping, time, date;
  State setting, hour, minute, day, month;
  State *timekeepingHist;
public:
  Watch();
  Msg const *topHndlr(Msg const *msg);  
  Msg const *timekeepingHndlr(Msg const *msg);  
  Msg const *timeHndlr(Msg const *msg);  
  Msg const *dateHndlr(Msg const *msg);  
  Msg const *settingHndlr(Msg const *msg);  
  Msg const *hourHndlr(Msg const *msg);  
  Msg const *minuteHndlr(Msg const *msg);  
  Msg const *dayHndlr(Msg const *msg);  
  Msg const *monthHndlr(Msg const *msg);  
  void tick();
  void showTime();
  void showDate();
};

enum WatchEvents {
  MODE_EVT,
  SET_EVT,
  TICK_EVT
};

void Watch::showTime() {
  printf("time: %2d:%02d:%02d", thour, tmin, tsec);
}

void Watch::showDate() {
  printf("date: %02d-%02d", dmonth, dday);
}

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

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

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

Msg const *Watch::timeHndlr(Msg const *msg) {
  switch (msg->evt) {
  case ENTRY_EVT:
    showTime();
    return 0;
  case MODE_EVT:
    STATE_TRAN(&date);
    printf("Watch::time-DATE;");        
    return 0;
  case TICK_EVT:
    printf("Watch::time-TICK;");        
    tick();
    showTime();
    return 0;
  } 
  return msg;
}

Msg const *Watch::dateHndlr(Msg const *msg) {
  switch (msg->evt) {
  case ENTRY_EVT:
    showDate();
    return 0;
  case MODE_EVT:
    STATE_TRAN(&time);
    printf("Watch::date-DATE;");        
    return 0;
  case TICK_EVT:
    printf("Watch::date-TICK;");        
    tick();
    showDate();
    return 0;
  } 
  return msg;
}

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

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

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

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

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

Watch::Watch() 
: Hsm("Watch", (EvtHndlr)topHndlr),
  timekeeping("timekeeping", &top,        (EvtHndlr)&Watch::timekeepingHndlr),
  time("time", &timekeeping, (EvtHndlr)&Watch::timeHndlr),
  date("date", &timekeeping, (EvtHndlr)&Watch::dateHndlr),
  setting("setting", &top, (EvtHndlr)&Watch::settingHndlr),
  hour("hour", &setting, (EvtHndlr)&Watch::hourHndlr),
  minute("minute", &setting, (EvtHndlr)&Watch::minuteHndlr),
  day("day", &setting, (EvtHndlr)&Watch::dayHndlr),
  month("month", &setting, (EvtHndlr)&Watch::monthHndlr),
  tsec(0), tmin(0), thour(0), dday(1), dmonth(1){  timekeepingHist = &time; 
}

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

⌨️ 快捷键说明

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