Tách hai máy trạng thái và sử dụng tin nhắn chuyển qua lại giữa chúng. Do đó, máy trạng thái 1 sẽ tiến hành từ ABC, trong đó ở trạng thái B, nó sẽ kiểm tra kết quả hiện tại từ máy trạng thái 2. Nếu đầu ra thay đổi, thì máy trạng thái 1 có thể giải thích cho nó và máy trạng thái 2 không cần có bất kỳ nhận thức nào làm thế nào máy trạng thái 1 thực sự hoạt động. Cái gì đó như:
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
lớpB
chứa B0, B1 và B2 và khi B2 kết thúc, nó sẽ chuyển điều khiển trở lại vùng chứa của nó, sau đó chuyển sang C ... Tôi thực sự chưa bao giờ thử bất cứ thứ gì như thế này. Đó là một vấn đề thú vị!