แยกเครื่องจักรสถานะสองเครื่องและใช้การส่งข้อความระหว่างกัน ดังนั้น state machine 1 จะเริ่มต้นจาก ABC โดยที่ state B จะตรวจสอบผลลัพธ์ปัจจุบันจาก state machine 2 หากผลลัพธ์มีการเปลี่ยนแปลงแล้ว state machine 1 สามารถอธิบายได้และ State machine 2 ไม่จำเป็นต้องรับรู้ใด ๆ การทำงานของกลไกสถานะ 1 ใช้งานได้จริง สิ่งที่ต้องการ:
typedef struct StateMachine {
void(*Update)(); // function to update the state machine
int Data; // generic temp holder to survive state contexts
int State; // current state of our state machine
int *Message; // pointer to a shared integer for message passing
};
int main(void) {
int Message = 0;
/* NewStateMachine would malloc the struct, pass in the int reference
* and function pointer as well as add it to a circularly linked list */
NewStateMachine(&Message, MainLoop);
NewStateMachine(&Message, MinorLoop);
StateMachine *Current = StateMachine_CLL.First;
for(;;) {
Current->Update(Current); /* Update the current state machine */
Current = Current->Next; /* And the advance to the next one */
}
}
void MainLoop(StateMachine *this) {
switch(this.State) {
case 0:
CloseCoolantTank(1); /* safe to call if valve already closed */
CloseCoolantTank(2); /* safe to call if valve already closed */
this.State = 1;
break;
case 1:
/* we have a message, do something */
if(*this.Message) this.State = 2;
/* otherwise stall at this state until we get a message */
else this.State = 1;
break;
case 2:
if(*this.Message == 1) this.State = 3; /* warm */
else if(*this.Message == 2) this.State = 4; /* hot! */
else this.State = 0; /* cooled down, shut off valves */
this.Message = 0; /* clear the message */
break;
case 3:
OpenCoolantTank(1); /* opens the valve, safe to call if already open */
this.State = 2; /* recheck for new message */
break;
case 4:
OpenCoolantTank(2); /* opens the valve, safe to call if already open */
this.State = 3; /* also open coolant tank 1 for extra cooling */
break;
}
}
/* Monitor temperature and send messages on overheat */
void MinorLoop(StateMachine *this) {
switch(this.State) {
case 0:
this.Data = ReadADCValue();
this.State = 1;
break;
case 1:
if(this.Data > 150) *this.Message = 2;
else if(this.Data > 100) *this.Message = 1;
this.State = 0;
break;
}
}
MachineContainer
คลาสสำหรับB
ที่มี B0, B1, และ B2 และเมื่อ B2 จบลงมันจะผ่านการควบคุมกลับไปที่ตู้คอนเทนเนอร์ซึ่งเปลี่ยนไปเป็น C ... ฉันไม่เคยลองอะไรแบบนี้มาก่อน มันเป็นปัญหาที่น่าสนใจ!