/*---------------------------------------- header file ----------------------------------------*/
typedef struct tagE1Params {
int x;
}E1Params;
typedef struct tagMainStm {
HdStateMachine base;
#define MainStm_StmTop_Dmy ( 1 << 0 )
#define MainStm_StmTop ( MainStm_StmTop_Dmy | MainStm_S1 | MainStm_S2 )
#define MainStm_S1 ( 1 << 1 )
#define MainStm_S2 ( 1 << 2 )
}MainStm;
/*---------------------------------------- source file ----------------------------------------*/
static void MainStm_S1_Entry( ContextImpl* pContextImpl, MainStm* pStm ){
if( HdStateMachine_Enterable( &pStm->base, MainStm_S1 ) ){
DisplayMsg("Enter S1");
}
}
static BOOL MainStm_S1_EventProc( ContextImpl* pContextImpl, MainStm* pStm, ContextImpl_EVENT nEventId, void* pEventParams ){
BOOL bResult = FALSE;
pStm->base.nSourceState = MainStm_S1;
switch( nEventId ){
case ContextImpl_E1:{
E1Params* e = ( E1Params* )pEventParams;
if (e->x > 0) {
MainStm_BgnTrans( pContextImpl, pStm, MainStm_S2, STATE_UNDEF );
DisplayMsg("Do an Action");
MainStm_EndTrans( pContextImpl, pStm );
bResult = TRUE;
}
} break;
case ContextImpl_E2:{
DisplayMsg("Another Action");
bResult = TRUE;
} break;
default: break;
}
return bResult;
}
static void MainStm_S1_Exit( ContextImpl* pContextImpl, MainStm* pStm ){
if( HdStateMachine_Exitable( &pStm->base, MainStm_S1 ) ){
DisplayMsg("Exit S1");
}
}
public class ContextImpl: Context
{
public struct E1Params {
int x;
}
class MainStm: Statemachine {
public class StmTop: TopState {
private static TopState singleInstance = new StmTop();
public static new TopState GetInstance() { return singleInstance; }
}
public class S1: StmTop {
private static TopState singleInstance = new S1();
public static new TopState GetInstance() { return singleInstance; }
public override void Entry(Context pContext, Statemachine pStm){
if( pStm.IsEnterable(GetInstance()) ){
DisplayMsg("Enter S1");
}
}
public override bool EventProc( Context pContext, Statemachine pStm, int nEventId, EventParams pParams ){
bool bResult = false;
pStm.m_pSourceState = GetInstance();
switch( (_EventId)nEventId ){
case _EventId.E1:{
E1Params e = ( E1Params )pParams;
if (e.x > 0) {
pStm.BgnTrans( pContext, S2.GetInstance() );
DisplayMsg("Do an Action");
pStm.EndTrans( pContext );
bResult = true;
}
} break;
case _EventId.E2:{
DisplayMsg("Another Action");
bResult = true;
} break;
default: break;
}
return bResult;
}
public override void Exit(Context pContext, Statemachine pStm) {
if (pStm.IsExitable(GetInstance())) {
DisplayMsg("Exit S1");
}
}
}
}
...
};
There is no special adaption on Composite State notation.
static BOOL MainStm_S2_EventProc( ContextImpl* pContextImpl, MainStm* pStm, ContextImpl_EVENT nEventId, void* pEventParams ){
BOOL bResult = FALSE;
pStm->base.nSourceState = MainStm_S2;
switch( nEventId ){
case ContextImpl_E2:{
MainStm_BgnTrans( pContextImpl, pStm, MainStm_S5, STATE_UNDEF );
MainStm_EndTrans( pContextImpl, pStm );
bResult = TRUE;
} break;
default: break;
}
return bResult;
}
...
static BOOL MainStm_S3_EventProc( ContextImpl* pContextImpl, MainStm* pStm, ContextImpl_EVENT nEventId, void* pEventParams ){
BOOL bResult = FALSE;
pStm->base.nSourceState = MainStm_S3;
switch( nEventId ){
case ContextImpl_E0:{
MainStm_BgnTrans( pContextImpl, pStm, MainStm_S4, STATE_UNDEF );
MainStm_EndTrans( pContextImpl, pStm );
bResult = TRUE;
} break;
case ContextImpl_E1:{
MainStm_BgnTrans( pContextImpl, pStm, MainStm_S5, STATE_UNDEF );
MainStm_EndTrans( pContextImpl, pStm );
bResult = TRUE;
} break;
default: break;
}
return bResult ? bResult : MainStm_S2_EventProc( pContextImpl, pStm, nEventId, pEventParams );
}
...
static BOOL MainStm_S4_EventProc( ContextImpl* pContextImpl, MainStm* pStm, ContextImpl_EVENT nEventId, void* pEventParams ){
BOOL bResult = FALSE;
pStm->base.nSourceState = MainStm_S4;
switch( nEventId ){
case ContextImpl_E0:{
MainStm_BgnTrans( pContextImpl, pStm, MainStm_S2, STATE_UNDEF );
MainStm_EndTrans( pContextImpl, pStm );
bResult = TRUE;
} break;
default: break;
}
return bResult ? bResult : MainStm_S2_EventProc( pContextImpl, pStm, nEventId, pEventParams );
}
...
static BOOL MainStm_StateDefaultTrans( ContextImpl* pContextImpl, MainStm* pStm ){
BOOL bResult = FALSE;
pStm->base.nSourceState = pStm->base.nCurrentState;
pStm->base.nLCAState = STATE_UNDEF;
do{
if( pStm->base.nPseudostate == MainStm_S2 ){
MainStm_BgnTrans( pContextImpl, pStm, MainStm_S6, MainStm_InitPt );
MainStm_EndTrans( pContextImpl, pStm );
bResult = TRUE;
}else if( pStm->base.nCurrentState == MainStm_S2 && pStm->base.nPseudostate == MainStm_InitPt ){
MainStm_BgnTrans( pContextImpl, pStm, MainStm_S3, STATE_UNDEF );
MainStm_EndTrans( pContextImpl, pStm );
bResult = TRUE;
}else{
} }while( FALSE );
return bResult;
}
class MainStm: public Statemachine {
public:
class S2: public StmTop { using TThisState = S2; using TSuperState = StmTop;
...
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
switch( nEventId ){
case E2:{
pStm->BgnTrans( pContext, S5::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult;
}
};
...
class S3: public S2 { using TThisState = S3; using TSuperState = S2;
...
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
switch( nEventId ){
case E0:{
pStm->BgnTrans( pContext, S4::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
case E1:{
pStm->BgnTrans( pContext, S5::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult ? bResult : TSuperState::EventProc( pContext, pStm, nEventId, pParams );
}
};
class S4: public S2 { using TThisState = S4; using TSuperState = S2;
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
switch( nEventId ){
case E0:{
pStm->BgnTrans( pContext, S2::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult ? bResult : TSuperState::EventProc( pContext, pStm, nEventId, pParams );
}
};
virtual bool DefaultTrans( Context* pContext ){
bool bResult = false;
Statemachine* pStm = this;
do {
if (m_pPseudostate == MainStm::S2::GetInstance()) {
pStm->BgnTrans( pContext, S6::GetInstance(), InitPt::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} else if (m_pCurrentState == S2::GetInstance() && m_pPseudostate == MainStm::InitPt::GetInstance()) {
pStm->BgnTrans( pContext, S3::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} else {
}
} while (false);
return bResult;
}
...
};
There is no special adaption on Submachine State notation.
public: enum _EventId {
E0,
E2,
E3,
E4,
evNum
};
class SharedStm: public Statemachine {
public:
class SharedTop: public TopState{ using TThisState = SharedTop;
public: static TopState* GetInstance() { static TThisState singleInstance; return &singleInstance; }
};
class Entry1: public Pseudostate<Entry1>{};
class Exit1: public Pseudostate<Exit1>{};
class InitPt: public Pseudostate<InitPt>{};
class Shared1: public SharedTop { using TThisState = Shared1; using TSuperState = SharedTop;
...
};
class Shared2: public SharedTop { using TThisState = Shared2; using TSuperState = SharedTop;
public: static TopState* GetInstance() { static TThisState singleInstance; return &singleInstance; }
virtual void Entry( Context* pContext, Statemachine* pStm ){
...
}
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
switch( nEventId ){
case E2:{
pStm->BgnTrans( pContext, SharedTop::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
case E3:{
pStm->BgnTrans( pContext, SharedTop::GetInstance() );
pStm->m_pParentStm->m_pPseudostate = SharedStm::Exit1::GetInstance();
pStm->EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult;
}
virtual void Exit(Context* pContext, Statemachine* pStm) {
...
}
};
virtual bool DefaultTrans( Context* pContext ){
bool bResult = false;
Statemachine* pStm = this;
do {
if (m_pPseudostate == SharedStm::Entry1::GetInstance()) {
pStm->BgnTrans( pContext, Shared1::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} else if (m_pCurrentState == SharedTop::GetInstance() && m_pPseudostate == SharedStm::InitPt::GetInstance()) {
pStm->BgnTrans( pContext, Shared1::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} else if (m_pCurrentState != m_pPseudostate && dynamic_cast<SharedTop*>(m_pPseudostate) != NULL) {
pStm->BgnTrans( pContext, dynamic_cast<TopState*>(m_pPseudostate) );
pStm->EndTrans( pContext );
bResult = true;
} else {
}
} while (false);
return bResult;
}
virtual bool Reset(Context* pContext, Statemachine* pParentStm, StateBase* pEntryPoint) {
m_pParentStm = pParentStm;
if (pEntryPoint == null) {
if (IsFinished()) {
m_pPseudostate = InitPt::GetInstance();
}
} else {
if (IsFinished()) {
m_pPseudostate = pEntryPoint;
return false;
} else {
m_pPseudostate = pEntryPoint;
}
}
if (pEntryPoint != null) {
}
return RunToCompletion(pContext);
}
virtual bool EventProc(Context* pContext, int nEventId, EventParams* pParams){
bool bResult = false;
m_pLCAState = TopState::GetInstance();
bResult = m_pCurrentState->EventProc(pContext, this, nEventId, pParams);
RunToCompletion(pContext);
return bResult;
}
template<class TCompositeState = TopState>
bool IsInRecur() {
if (IsIn<TCompositeState>()) { return true; }
return false;
}
virtual bool Abort(Context* pContext) {
m_pSourceState = SharedTop::GetInstance();
BgnTrans(pContext, SharedTop::GetInstance());
EndTrans(pContext);
return true;
}
virtual bool IsFinished() {
return m_pCurrentState == SharedTop::GetInstance() && m_pCurrentState == m_pPseudostate;
}
SharedStm(): Statemachine(SharedTop::GetInstance(), SharedTop::GetInstance()) {}
};
class MainStm: public Statemachine {
public:
class MainTop: public TopState{ using TThisState = MainTop;
public: static TopState* GetInstance() { static TThisState singleInstance; return &singleInstance; }
};
SharedStm m_S6SharedStm;
SharedStm m_S9SharedStm;
class S3: public MainTop { using TThisState = S3; using TSuperState = MainTop;
public: static TopState* GetInstance() { static TThisState singleInstance; return &singleInstance; }
virtual void Entry( Context* pContext, Statemachine* pStm ){
...
}
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
switch( nEventId ){
case E0:{
pStm->BgnTrans( pContext, S6::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult;
}
virtual void Exit(Context* pContext, Statemachine* pStm) {
...
}
};
class S4: public MainTop { using TThisState = S4; using TSuperState = MainTop;
...
};
class S6: public MainTop { using TThisState = S6; using TSuperState = MainTop;
public: static TopState* GetInstance() { static TThisState singleInstance; return &singleInstance; }
virtual void Entry( Context* pContext, Statemachine* pStm ){
...
}
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
switch( nEventId ){
case E3:{
pStm->BgnTrans( pContext, S9::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
case E4:{
pStm->BgnTrans( pContext, S4::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult;
}
virtual void Exit(Context* pContext, Statemachine* pStm) {
...
}
};
class S10: public MainTop { using TThisState = S10; using TSuperState = MainTop;
...
};
class S5: public MainTop { using TThisState = S5; using TSuperState = MainTop;
public: static TopState* GetInstance() { static TThisState singleInstance; return &singleInstance; }
virtual void Entry( Context* pContext, Statemachine* pStm ){
...
}
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
switch( nEventId ){
case E2:{
pStm->BgnTrans( pContext, S6::GetInstance() );
((MainStm*)pStm)->m_S6SharedStm.Reset(pContext, pStm, SharedStm::Entry1::GetInstance());
pStm->EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult;
}
virtual void Exit(Context* pContext, Statemachine* pStm) {
...
}
};
class S9: public MainTop { using TThisState = S9; using TSuperState = MainTop;
public: static TopState* GetInstance() { static TThisState singleInstance; return &singleInstance; }
virtual void Entry( Context* pContext, Statemachine* pStm ){
...
}
virtual bool EventProc( Context* pContext, Statemachine* pStm, EventId nEventId, EventParams* pParams ){
bool bResult = false;
pStm->m_pSourceState = TThisState::GetInstance();
return bResult;
}
virtual void Exit(Context* pContext, Statemachine* pStm) {
...
}
};
virtual bool DefaultTrans( Context* pContext ){
bool bResult = false;
Statemachine* pStm = this;
bResult |= m_S6SharedStm.DefaultTrans( pContext );
bResult |= m_S9SharedStm.DefaultTrans( pContext );
do {
if (m_pCurrentState == S6::GetInstance() && m_pPseudostate == MainStm::Exit1::GetInstance()) {
pStm->BgnTrans( pContext, S9::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} else if (m_pPseudostate == MainStm::S9::GetInstance()) {
if( !m_S9SharedStm.IsFinished() ){ break; }
pStm->BgnTrans( pContext, S10::GetInstance() );
pStm->EndTrans( pContext );
bResult = true;
} else if (m_pCurrentState != m_pPseudostate && dynamic_cast<MainTop*>(m_pPseudostate) != NULL) {
pStm->BgnTrans( pContext, dynamic_cast<TopState*>(m_pPseudostate) );
pStm->EndTrans( pContext );
bResult = true;
} else {
}
} while (false);
return bResult;
}
virtual bool Reset(Context* pContext, Statemachine* pParentStm, StateBase* pEntryPoint) {
...
}
virtual bool EventProc(Context* pContext, int nEventId, EventParams* pParams){
bool bResult = false;
m_pLCAState = TopState::GetInstance();
bResult |= m_S6SharedStm.EventProc( pContext, nEventId, pParams );
bResult |= m_S9SharedStm.EventProc( pContext, nEventId, pParams );
bResult = m_pCurrentState->EventProc(pContext, this, nEventId, pParams);
RunToCompletion(pContext);
return bResult;
}
template<class TCompositeState = TopState>
bool IsInRecur() {
if (m_S6SharedStm.IsInRecur<TCompositeState>()) { return true; }
if (m_S9SharedStm.IsInRecur<TCompositeState>()) { return true; }
if (IsIn<TCompositeState>()) { return true; }
return false;
}
...
};
Join's input must have one come from main-machine (might has pseudo-state interfered) the others would come from sub-machines directly without any pseudostate interfere.
static class MainStm extends Statemachine {
S111Stm m_S111S111Stm = new S111Stm();
S112Stm m_S112S112Stm = new S112Stm();
public static class S11 extends StmTop {
private static TopState singleInstance = new S11();
public static TopState GetInstance() { return singleInstance; }
public void Entry(Context pContext, Statemachine pStm){
if( pStm.IsEnterable(GetInstance()) ){
((MainStm)pStm).m_S111S111Stm.Reset( pContext, pStm, null );
((MainStm)pStm).m_S112S112Stm.Reset( pContext, pStm, null );
}
}
public boolean EventProc( Context pContext, Statemachine pStm, int nEventId, EventParams pParams ){
boolean bResult = false;
pStm.m_pSourceState = GetInstance();
return bResult;
}
public void Exit(Context pContext, Statemachine pStm) {
if (pStm.IsExitable(GetInstance())) {
((MainStm)pStm).m_S111S111Stm.Abort( pContext );
((MainStm)pStm).m_S112S112Stm.Abort( pContext );
}
}
};
...
public static class S13 extends S11 {
private static TopState singleInstance = new S13();
public static TopState GetInstance() { return singleInstance; }
public void Entry(Context pContext, Statemachine pStm){
if( pStm.IsEnterable(GetInstance()) ){
super.Entry( pContext, pStm );
}
}
public boolean EventProc( Context pContext, Statemachine pStm, int nEventId, EventParams pParams ){
boolean bResult = false;
pStm.m_pSourceState = GetInstance();
switch( _EventId.values()[nEventId] ){
case E5:{
if (((ContextImpl)pContext).IsIn(S111Stm.S15.GetInstance())) {
pStm.BgnTrans( pContext, S20.GetInstance() );
pStm.EndTrans( pContext );
bResult = true;
}
} break;
default: break;
}
return bResult ? bResult : super.EventProc( pContext, pStm, nEventId, pParams );
}
public void Exit(Context pContext, Statemachine pStm) {
if (pStm.IsExitable(GetInstance())) {
super.Exit(pContext, pStm);
}
}
};
public static class S9 extends StmTop {
private static TopState singleInstance = new S9();
public static TopState GetInstance() { return singleInstance; }
public void Entry(Context pContext, Statemachine pStm){
if( pStm.IsEnterable(GetInstance()) ){
System.out.println(GetInstance().getClass() + "entry");
}
}
public boolean EventProc( Context pContext, Statemachine pStm, int nEventId, EventParams pParams ){
boolean bResult = false;
pStm.m_pSourceState = GetInstance();
switch( _EventId.values()[nEventId] ){
case E3:{
pStm.BgnTrans( pContext, S11.GetInstance(), InitPt.GetInstance() );
((MainStm)pStm).m_S111S111Stm.Reset(pContext, pStm, S111Stm.S14.GetInstance());
((MainStm)pStm).m_S112S112Stm.Reset(pContext, pStm, S112Stm.S16.GetInstance());
pStm.EndTrans( pContext );
bResult = true;
} break;
default: break;
}
return bResult;
}
public void Exit(Context pContext, Statemachine pStm) {
if (pStm.IsExitable(GetInstance())) {
System.out.println(GetInstance().getClass() + "exit");
}
}
};
public boolean DefaultTrans( Context pContext ){
boolean bResult = false;
Statemachine pStm = this;
bResult |= m_S111S111Stm.DefaultTrans( pContext );
bResult |= m_S112S112Stm.DefaultTrans( pContext );
do {
if (m_pPseudostate == MainStm.S11.GetInstance()) {
if( !m_S111S111Stm.IsFinished() ){ break; }
if( !m_S112S112Stm.IsFinished() ){ break; }
pStm.BgnTrans( pContext, StmTop.GetInstance() );
pStm.EndTrans( pContext );
bResult = true;
} else if (m_pCurrentState == S11.GetInstance() && m_pPseudostate == MainStm.InitPt.GetInstance()) {
pStm.BgnTrans( pContext, S12.GetInstance() );
pStm.EndTrans( pContext );
bResult = true;
} else if (m_pCurrentState != m_pPseudostate && m_pPseudostate instanceof StmTop) {
pStm.BgnTrans( pContext, (TopState)m_pPseudostate );
pStm.EndTrans( pContext );
} else {
}
} while (false);
return bResult;
}
}
Parent-machine
Current State
IsFinished
Transition Control: Least Common Ancestor (LCA) State
Transition Control: Source State
Transition Control: Target State
Transition Control: Target Pseudostate, a Temporary Stop