2つの状態マシンを分離し、それらの間のメッセージ受け渡しを使用します。したがって、ステートマシン1はABCから進み、ステートBでステートマシン2からの現在の結果をチェックします。出力が変更された場合、ステートマシン1はそれを考慮に入れることができ、ステートマシン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
クラスが必要になる場合があります。B2がB
終了すると、制御がコンテナーに戻され、コンテナーがCに移行します。実際には、このようなことは試していません。興味深い問題です。