My state machines have about 200 motions and are so big to add the next motion.
is there a way to fix this problem or how can I make the transition in code?
CodePudding user response:
If you can define a set of rules for your 200 events you can use a vectored state machine, take a look at this smaller rule based time domain event driven example:
Using a Domain specific language for defining a calculator state machine using a sequence statement containing four rules. The four rules define the elements in a rule. The engine keeps track of the time so the state machine only needs to respond to the calculator button events. Only 19 decision points in the four rules.(www.vsmerlot.com)
sequence statement:
Calculator = Operand1 Operator Operand2 Result;
four rules:
Operand1 = Negate Digit Dot Digit Clear ClrEnt;
Operator = Add Sub Mul Div;
Operand2 = Negate Digit Dot Digit Clear ClrEnt;
Result = Chain Equals Percent;
the vector control engine is turned on and off by the while loop scope. The state test is either true or false. The trace covers 100 percent of the state machine. When the test is true the true behavior is executed and the next true step in a rule is executed. Rules can only be entered at the very first step and can exit from any step in a rule like a compiler basic block. The engine includes an introspective trace that can be turned off under program control.
This is just plain ugly in C but very clean in C or Delphi.
``` iCalcStatus = 1;
``` bCalcEngine = true;
``` strValue = strArgValue;
``` tkCalcToken = iToken;
``` while(bCalcEngine){
``` if((this->*(aCalc[iCalcTime].fState))()){
``` (this->*(aCalc[iCalcTime].pTrueProc))();
``` (this->*(CalcTrueIntro))(iCalcTime);
``` iCalcTime = aCalc[iCalcTime].iTrueNext;
``` } else {
``` (this->*(aCalc[iCalcTime].pFalseProc))();
``` (this->*(CalcFalseIntro))(iCalcTime);
``` iCalcTime = aCalc[iCalcTime].iFalseNext;
``` }
``` }
```}
```{
```rOper1 = 0;
```rOper8 = rOper1 6;
```rOper2 = rOper8 4;
```rResult = rOper2 6;
```// True True False False
```// Rule Name State Behavior Next Behavior Next Trace
``` cx( rOper1 0, &TCOSACalc::fNeg45, &TCOSACalc::pNeg45, rOper1 1, &TCOSACalc::pClrBuff, rOper1 1, 100);
``` cx( rOper1 1, &TCOSACalc::fDigit, &TCOSACalc::pDigit, rOper1 1,&TCOSACalc::pCalcIgnore, rOper1 2, 101);
``` cx( rOper1 2, &TCOSACalc::fDot59, &TCOSACalc::pDot59, rOper1 3,&TCOSACalc::pCalcIgnore, rOper1 4, 102);
``` cx( rOper1 3, &TCOSACalc::fDigit, &TCOSACalc::pDigit, rOper1 3,&TCOSACalc::pCalcIgnore, rOper1 4, 103);
``` cx( rOper1 4, &TCOSACalc::fClr, &TCOSACalc::pClr, rOper1 0,&TCOSACalc::pCalcIgnore, rOper1 5, 104);
``` cx( rOper1 5, &TCOSACalc::fClrEnt, &TCOSACalc::pClrEnt, rOper1 0,&TCOSACalc::pPush_Disp, rOper8, 105);
// Warning! Don't Change the Code, You Will Regret It!
``` cx( rOper8 0, &TCOSACalc::fAdd43, &TCOSACalc::pAdd43, rOper2,&TCOSACalc::pCalcIgnore, rOper8 1, 400);
``` cx( rOper8 1, &TCOSACalc::fSub45, &TCOSACalc::pSub45, rOper2,&TCOSACalc::pCalcIgnore, rOper8 2, 401);
``` cx( rOper8 2, &TCOSACalc::fMul42, &TCOSACalc::pMul42, rOper2,&TCOSACalc::pCalcIgnore, rOper8 3, 402);
``` cx( rOper8 3, &TCOSACalc::fDiv47, &TCOSACalc::pDiv47, rOper2, &TCOSACalc::pEngOff, rOper1, 403);
// Warning! Don't Change the Code, You Will Regret It!
``` cx( rOper2 0, &TCOSACalc::fNeg45, &TCOSACalc::pNeg45, rOper2 1, &TCOSACalc::pClrBuff, rOper2 1, 700);
``` cx( rOper2 1, &TCOSACalc::fDigit, &TCOSACalc::pDigit, rOper2 1,&TCOSACalc::pCalcIgnore, rOper2 2, 701);
``` cx( rOper2 2, &TCOSACalc::fDot59, &TCOSACalc::pDot59, rOper2 3,&TCOSACalc::pCalcIgnore, rOper2 4, 702);
``` cx( rOper2 3, &TCOSACalc::fDigit, &TCOSACalc::pDigit, rOper2 3,&TCOSACalc::pCalcIgnore, rOper2 4, 703);
``` cx( rOper2 4, &TCOSACalc::fClr, &TCOSACalc::pClr, rOper2 0,&TCOSACalc::pCalcIgnore, rOper2 5, 704);
``` cx( rOper2 5, &TCOSACalc::fClrEnt, &TCOSACalc::pClrEnt, rOper2,&TCOSACalc::pSave_Disp, rResult, 705);
```// Warning! Don't Change the Code, You Will Regret It!
``` cx( rResult 0, &TCOSACalc::fEqual, &TCOSACalc::pEqual, rOper1,&TCOSACalc::pCalcIgnore, rResult 1, 900);
``` cx( rResult 1, &TCOSACalc::fChain, &TCOSACalc::pChain, rOper8,&TCOSACalc::pCalcIgnore, rResult 2, 901);
``` cx( rResult 2, &TCOSACalc::fPercent, &TCOSACalc::pPercent, rOper1, &TCOSACalc::pEngOff, rOper1, 902);
```}
```// Embarcadero Builder CPP Trace
```***** Turning Introspective(tm) Trace On ******* Result
``` F= rOper1 0, fNeg45, pNeg45, rOper1 1, pClrBuff, rOper1 1, 100;
``` T= rOper1 1, fDigit, pDigit, rOper1 1, pCalcIgnore, rOper1 2, 101; 1
``` F= rOper1 1, fDigit, pDigit, rOper1 1, pCalcIgnore, rOper1 2, 101; 1
``` F= rOper1 2, fDot59, pDot59, rOper1 3, pCalcIgnore, rOper1 4, 102; 1
``` F= rOper1 4, fClr, pClr, rOper1 0, pCalcIgnore, rOper1 5, 104; 1
``` F= rOper1 5, fClrEnt,pClrEnt, rOper1 0, pPush_Disp, rOper8, 105;
``` T= rOper8 0, fAdd43, pAdd43, rOper2, pCalcIgnore, rOper8 1, 400;
``` F= rOper2 0, fNeg45, pNeg45, rOper2 1, pClrBuff, rOper2 1, 700;
``` T= rOper2 1, fDigit, pDigit, rOper2 1, pCalcIgnore, rOper2 2, 701; 2
``` F= rOper2 1, fDigit, pDigit, rOper2 1, pCalcIgnore, rOper2 2, 701; 2
``` F= rOper2 2, fDot59, pDot59, rOper2 3, pCalcIgnore, rOper2 4, 702; 2
``` F= rOper2 4, fClr, pClr, rOper2 0, pCalcIgnore, rOper2 5, 704; 2
``` F= rOper2 5, fClrEnt,pClrEnt, rOper2, pSave_Disp, rResult, 705;
``` T= rResult 0, fEqual, pEqual, rOper1, pCalcIgnore, rResult 1, 900; 3