#include "stdafx.h" #include "DiosSMachineV3.h" DiosSMachineIF::DiosSMachineIF() { m_pStateMachineName = new string(); //m_pParent = 0; m_pCurrentRoutePos = NULL; //evt list m_pArrivedEvts = new MsgCircle(); //routepos m_pRoutePosMap = new map(); DiosStMRoutePos* p = NULL; //状态机开始的时候才赋值 //p = new DiosStMRoutePos(DiosStmEntryPosName); //p->Active(true, TIMEOUT_TEMP); //(*m_pRoutePosMap)[DiosStmEntryPosName] = p; //p = new DiosStMRoutePos(DiosStmExitPosName); //p->Active(true, TIMEOUT_TEMP); //(*m_pRoutePosMap)[DiosStmExitPosName] = p; //inline //m_pRouteInLineMap = new vector(); m_pGlobalRoute = nullptr; // new DiosStMRoutePos("Global"); //external //m_RouteExternalEvtCount = 0; //m_pRouteExternalMap = NULL; //running state m_RunningState = CreateEvent(0, 1, 0, 0); m_StateCangeEvt = CreateEvent(0, 0, 0, 0); m_strCurrentPos = ""; m_StateNotify = nullptr; } DiosSMachineIF::~DiosSMachineIF() { delete m_pStateMachineName; m_pStateMachineName = 0; //cp m_pCurrentRoutePos = NULL; //external //m_RouteExternalEvtCount = 0; //m_pRouteExternalMap = NULL; //clear inline path //for (size_t i = 0; i < m_pRouteInLineMap->size(); i++) //{ // delete (*m_pRouteInLineMap)[i]; //} //delete m_pRouteInLineMap; //m_pRouteInLineMap = NULL; delete m_pGlobalRoute; m_pGlobalRoute = NULL; //clear routepos map::iterator iter = m_pRoutePosMap->begin(); while (iter != m_pRoutePosMap->end()) { //if (iter->second->IsSMachine()) //{ // DiosSubSMachine* pSub = (DiosSubSMachine*)iter->second; // delete pSub; //} //else { delete iter->second; } ++iter; } delete m_pRoutePosMap; m_pRoutePosMap = NULL; //evt list delete m_pArrivedEvts; m_pArrivedEvts = NULL; CloseHandle(m_RunningState); CloseHandle(m_StateCangeEvt); return; } void DiosSMachineIF::SetStateMachineName(const char* pszName) { (*m_pStateMachineName) = pszName; } const char* DiosSMachineIF::GetStateMachineName() { return m_pStateMachineName->c_str(); } void DiosSMachineIF::SetMachineName(const char* pszEntryName, const char* pszExitName) //设置状态机名称及进出状态名称 { m_StmEntryPosName = pszEntryName; m_StmExitPosName = pszExitName; } //设置用户变量,只提供根一层的Key void DiosSMachineIF::SetUserVariable(const char* pKey, ResDataObject& resValue) { int vidx = m_resUserVariable.GetFirstOf(pKey); if (vidx < 0) m_resUserVariable.add(pKey, resValue); else m_resSystemVariable.update(pKey, resValue); } //读取用户变量值,只提供根一层的Key void DiosSMachineIF::GetUserVariable(const char* pKey, ResDataObject& resValue) { if (pKey == nullptr) { resValue = m_resUserVariable; return; } int vidx = m_resUserVariable.GetFirstOf(pKey); if (vidx >= 0) resValue = m_resUserVariable[vidx]; } //读取系统变量,只提供跟一层的Key void DiosSMachineIF::GetSystemVariable(const char* pKey, ResDataObject& resValue) //读取系统变量 { if (pKey == nullptr) { resValue = m_resSystemVariable; return; } int vidx = m_resSystemVariable.GetFirstOf(pKey); if (vidx >= 0) resValue = m_resSystemVariable[vidx]; } void DiosSMachineIF::EnableEvent(const char* pszGlobalEvent, bool state) { /*auto it = m_pRouteInLineMap->begin(); while (it != m_pRouteInLineMap->end()) { (*it)->Active(state, 0); it++; }*/ m_pGlobalRoute->Active(state, 0); } //void DiosSMachineIF::SetParentSMachine(DiosSMachineIF* pParent) //{ // m_pParent = pParent; //} void DiosSMachineIF::PushStateChange(ResDataObject& ChangedPos) { //if (m_pParent) //{ // m_pParent->PushStateChange(ChangedPos); //} } //bool DiosSMachineIF::IsSMachine() //{ // return true; //} HANDLE DiosSMachineIF::GetStateChangeEvtHandle() { return m_StateCangeEvt; } void DiosSMachineIF::SetRunningState(bool Running) { Thread_Lock(); if (Running) { SetEvent(m_RunningState); } else { ResetEvent(m_RunningState); } Thread_UnLock(); } bool DiosSMachineIF::GetRunningState(DWORD waittime) { bool ret = (WaitForSingleObject(m_RunningState, waittime) == WAIT_OBJECT_0); if (ret == false) { printf("GetRunningState Failed.WTF??\n"); } return ret; } //init state machine //第一个节点的接入比较特殊,所以做了个函数 bool DiosSMachineIF::AddEntryRoutePos(DiosStMRoutePos* pPos) { if (strlen(pPos->GetName()) == 0) { return false; } if ((*m_pRoutePosMap)[m_StmEntryPosName]->GetRouteLineCount() > 0) { return false; } //add pos //(*m_pRoutePosMap)[pPos->GetName()] = pPos; //DiosStMEvt evt; //make a line //(*m_pRoutePosMap)[m_StmEntryPosName]->PosAddOutRouteLine(evt, m_StmEntryPosName.c_str(), NULL, pPos->GetName()); return true; } bool DiosSMachineIF::AddRoutePos(DiosStMRoutePos* pPos) { if (strlen(pPos->GetName()) == 0) { return false; } //add pos (*m_pRoutePosMap)[pPos->GetName()] = pPos; return true; } bool DiosSMachineIF::AddInRouteLine(DiosStMEvt& Evt, const char* pGuardName, const char* pDesPosName) { DiosStMRouteLine* pLine = new DiosStMRouteLine(); pLine->SetRoute(Evt, pGuardName, pDesPosName); pLine->Active(true, 0);//timeout没必要,因为是全局事件 //m_pRouteInLineMap->push_back(pLine); m_pGlobalRoute->PosAddOutRouteLine(&Evt, "Global", pGuardName, pDesPosName); return true; } bool DiosSMachineIF::AddOutRouteLine(DiosStMEvt* Evt, const char* pSrcPosName, const char* pGuardName, const char* pDesPosName) { bool ret = true; try { ret = (*m_pRoutePosMap)[pSrcPosName]->PosAddOutRouteLine(Evt, pSrcPosName, pGuardName, pDesPosName); } catch (...) { ret = false; } return ret; } //active state machine bool DiosSMachineIF::ActiveRoutePos(const char* pPosName, DWORD timeout) { bool ret = true; try { map::iterator iterOut = m_pRoutePosMap->find(pPosName); if (iterOut != m_pRoutePosMap->end()) { (*m_pRoutePosMap)[pPosName]->Active(true, timeout); } ////find sub route machine //iterOut = (*m_pRoutePosMap).begin(); //while (iterOut != (*m_pRoutePosMap).end()) //{ // if (iterOut->second->IsSMachine() == true) // { // DiosSubSMachine* pSub = (DiosSubSMachine*)(iterOut->second); // pSub->ActiveRoutePos(pPosName, timeout); // } // ++iterOut; //} } catch (...) { ret = false; } return ret; } //bool DiosSMachineIF::ActiveInRouteLine(DiosStMEvt &Evt, DWORD timeout) //{ // bool ret = false; // try{ // //find In Route Line // for (size_t i = 0; i < m_pRouteInLineMap->size(); i++) // { // if ((*(DiosStMEvt*)(*(*m_pRouteInLineMap)[i])) == Evt) // { // (*m_pRouteInLineMap)[i]->Active(true,timeout); // // ret = true; // // break; // } // } // // } // catch (...) // { // ret = false; // } // // return ret; // //} bool DiosSMachineIF::ActiveRouteLine(DiosStMEvt& Evt, DWORD timeout) { bool ret = true; try { //out path map::iterator iterOut = (*m_pRoutePosMap).begin(); while (iterOut != (*m_pRoutePosMap).end()) { if (iterOut->second->IsSMachine() == false) { DWORD RouteCount = iterOut->second->GetRouteLineCount(); DiosStMRouteLine** RouteLines = iterOut->second->GetOutRouteLineVec(); for (DWORD i = 0; i < RouteCount; i++) { if ((*(DiosStMEvt*)(*(RouteLines[i]))) == Evt) { RouteLines[i]->Active(true, timeout); } } } else { //子对象自行激活自己 //DiosSubSMachine *pSub = (DiosSubSMachine *)(iterOut->second); //pSub->ActiveRouteLine(Evt, timeout); } ++iterOut; } //in path //for (size_t i = 0; i < m_pRouteInLineMap->size(); i++) //{ // if ((*(DiosStMEvt*)(*((*m_pRouteInLineMap)[i]))) == Evt) // { // (*m_pRouteInLineMap)[i]->Active(true, timeout); // } //} DWORD RouteCount = m_pGlobalRoute->GetRouteLineCount(); DiosStMRouteLine** RouteLines = m_pGlobalRoute->GetOutRouteLineVec(); for (DWORD i = 0; i < RouteCount; i++) { if ((*(DiosStMEvt*)(*(RouteLines[i]))) == Evt) { RouteLines[i]->Active(true, timeout); } } //DiosStMRouteLine* pLine = (*(*m_pRoutePosMap)[pPosName])[Evt]; //if (pLine) //{ // pLine->Active(true, timeout); // ret = true; //} } catch (...) { ret = false; } return ret; } bool DiosSMachineIF::DeActiveAll() { bool ret = true; try { //out path map::iterator iterOut = (*m_pRoutePosMap).begin(); while (iterOut != (*m_pRoutePosMap).end()) { //if (iterOut->second->IsSMachine() == false) { //deactive pos iterOut->second->Active(false, 0); //deactive line DWORD RouteCount = iterOut->second->GetRouteLineCount(); DiosStMRouteLine** RouteLines = iterOut->second->GetOutRouteLineVec(); for (DWORD i = 0; i < RouteCount; i++) { RouteLines[i]->Active(false, 0); } } //else //{ // DiosSubSMachine* pSub = (DiosSubSMachine*)(iterOut->second); // pSub->DeActiveAll(); //} ++iterOut; } //in path //for (size_t i = 0; i < m_pRouteInLineMap->size(); i++) //{ // (*m_pRouteInLineMap)[i]->Active(false, 0); //} DWORD RouteCount = m_pGlobalRoute->GetRouteLineCount(); DiosStMRouteLine** RouteLines = m_pGlobalRoute->GetOutRouteLineVec(); for (DWORD i = 0; i < RouteCount; i++) { RouteLines[i]->Active(false, 0); } } catch (...) { ret = false; } return ret; } void DiosSMachineIF::ClearState() { Thread_Lock(); SetRunningState(false); map::iterator iterOut = (*m_pRoutePosMap).begin(); //while (iterOut != (*m_pRoutePosMap).end()) //{ // if (iterOut->second->IsSMachine()) // { // DiosSubSMachine* pSub = (DiosSubSMachine*)(iterOut->second); // pSub->ClearState(); // } // ++iterOut; //} auto iter = m_pRoutePosMap->find(m_StmEntryPosName); if (iter != m_pRoutePosMap->end()) { delete (*m_pRoutePosMap)[m_StmEntryPosName] ; m_pRoutePosMap->erase(iter); //(*m_pRoutePosMap)[m_StmEntryPosName] = nullptr; } iter = m_pRoutePosMap->find(m_StmExitPosName); if (iter != m_pRoutePosMap->end()) { delete (*m_pRoutePosMap)[m_StmExitPosName]; m_pRoutePosMap->erase(iter);// m_StmExitPosName] = nullptr; } m_pCurrentRoutePos = NULL; m_strCurrentPos = ""; m_pArrivedEvts->Clear(); //m_RouteExternalEvtCount = 0; //m_pRouteExternalMap = NULL; Thread_UnLock(); } HANDLE DiosSMachineIF::GetEvtNotifyHandle() { return (*m_pArrivedEvts).GetNotifyHandle(); } bool DiosSMachineIF::PeekEvent(DiosStMEvt& Evt) { //check it's existance return (*m_pArrivedEvts).Peek(Evt); } //evt bool DiosSMachineIF::PopEvent(DiosStMEvt& Evt) { return (*m_pArrivedEvts).DeQueue(Evt); } bool DiosSMachineIF::PushEvent(DiosStMEvt& Evt) { bool ret = false; Thread_Lock(); /*if (m_pCurrentRoutePos) { if (m_pCurrentRoutePos->IsSMachine()) { DiosSubSMachine* pMachine = (DiosSubSMachine*)m_pCurrentRoutePos; pMachine->Thread_Lock(); if (pMachine->GetRunningState() == true) { ret = pMachine->PushEvent(Evt); pMachine->Thread_UnLock(); Thread_UnLock(); return ret; } pMachine->Thread_UnLock(); } } Thread_UnLock();*/ //check it's existance (*m_pArrivedEvts).Lock(); DWORD size = (*m_pArrivedEvts).size(); for (DWORD i = 0; i < size; i++) { if ((*m_pArrivedEvts)[i] == Evt) { (*m_pArrivedEvts).UnLock(); return ret; } } ret = true; (*m_pArrivedEvts).InQueue(Evt); (*m_pArrivedEvts).UnLock(); return true; } //for state machine thread DIOSSTMRET DiosSMachineIF::StateMachineEntry(DWORD timeout) { m_pCurrentRoutePos->DoIn(this); return m_pCurrentRoutePos->DoAction(this); } DIOSSTMRET DiosSMachineIF::StateMachineExit(DWORD timeout) { return DIOSSMRET_OK; } DIOSSTMRET DiosSMachineIF::StateMachineAction(const char* pAction, DWORD timeout) { return m_pCurrentRoutePos->DoAction(this); } DIOSSTMRET DiosSMachineIF::StateMachineGuard(const char* pGuard, DWORD timeout) { return DIOSSMRET_OK; } //int DiosSMachineIF::StateMachineWaitForEvents( // DiosStMRouteLine* pLocalEvts[], DWORD CountOfLocal, // //DiosStMRouteLine* pExternalEvts[], DWORD CountOfExternal, // DiosStMRouteLine* pOutpathEvts[], DWORD CountOfOutpath, // DWORD timeout //) //{ // //执行最基础的处理 // return -1; //} DiosStMRoutePos* DiosSMachineIF::GetCurrentRoutePos() { return m_pCurrentRoutePos; } DIOSSTMRET DiosSMachineIF::TransToPos(const char* pPosName) { DIOSSTMRET ret = DIOSSMRET_OK; //des check try { Thread_Lock(); m_pCurrentRoutePos->DoOut(this); m_pCurrentRoutePos = (*m_pRoutePosMap)[string(pPosName)]; m_pCurrentRoutePos->DoIn(this); //要通知设备池,设置新的事件列表 m_strCurrentPos = pPosName; Thread_UnLock(); //先回调再通知 if (m_StateNotify != nullptr) { m_StateNotify(m_pStateMachineName->c_str(), m_strCurrentPos.c_str()); } SetEvent(m_StateCangeEvt); printf("Trans To %s \n", pPosName); } catch (...) { assert(0);//never gonna reach ret = DIOSSMRET_NG; } return ret; } //这里的Error必须是状态机的Error,而不是业务方面的错误,比如action失败,不算 void DiosSMachineIF::PostError(const char* pErrorVal, const char* pErrorInfo) { /* DiosStMEvt evt; if (pErrorVal) { printf("--PostError:%s--\n", pErrorVal); } else { printf("--PostError:Empty--\n"); } evt.SetEvt(DiosErrorType, pErrorVal, pErrorInfo); PushEvent(evt);*/ } DiosStMRouteLine* DiosSMachineIF::GetEntryRouteLine() { //routepos DiosStMRoutePos* pFirst = (*m_pRoutePosMap)[m_StmEntryPosName]; if (pFirst) { if (pFirst->GetRouteLineCount() == 1) { return ((m_pCurrentRoutePos->GetOutRouteLineVec())[0]); } } return NULL; } //void DiosSMachineIF::CopyEvtTo(DiosSMachineIF* pDes) //{ // //排序上先ORG的消息,然后des的消息 // bool ret = true; // DiosStMEvt Evt; // // //copy des to org // while (ret) // { // ret = pDes->PopEvent(Evt); // if (ret) // { // PushEvent(Evt); // } // } // // // //org -> des // ret = true; // while (ret) // { // ret = PopEvent(Evt); // if (ret) // { // pDes->PushEvent(Evt); // } // } // //} //检查:路径,状态点,以及它们的ActiveState bool DiosSMachineIF::PrePareStateMachine() { /**/ //DiosStMRoutePos* p = NULL; //p = new DiosStMRoutePos(m_StmEntryPosName.c_str(), m_pDevicePool); //p->Active(true, TIMEOUT_TEMP); //(*m_pRoutePosMap)[m_StmEntryPosName] = p; //p = new DiosStMRoutePos(m_StmExitPosName.c_str(), m_pDevicePool); //p->Active(true, TIMEOUT_TEMP); //(*m_pRoutePosMap)[m_StmExitPosName] = p; //状态点的检查 map::iterator iter = m_pRoutePosMap->begin(); while (iter != m_pRoutePosMap->end()) { //if (iter->second->IsSMachine()) //{ // //sub machine // DiosSubSMachine* pSub = static_cast(iter->second); // if (pSub->PrePareStateMachine() == false) // { // ostringstream buf; // buf << "Sub StateMachine Error.Name:" << (iter->second)->GetName(); // //PostError(DiosFrameError, buf.str().c_str()); // mLog::FERROR("Post FrameError.%s", buf.str().c_str()); // return false;//submachine err // } //} //else { //route pos bool RouteLineActived = false; //OutRouteLine的检查 DWORD VecCount = iter->second->GetRouteLineCount(); DiosStMRouteLine** pVec = iter->second->GetOutRouteLineVec(); for (DWORD i = 0; i < VecCount; i++) { //Activestate RouteLineActived |= pVec[i]->GetActiveState(); //Des的有效性 const char* pDes = pVec[i]->GetDesName(); map::iterator desok = m_pRoutePosMap->find(string(pDes)); if (desok == m_pRoutePosMap->end()) { //no des ostringstream buf; buf << "No Destination of RouteLine.RouteName:" << iter->second->GetName() << "DesName:" << pDes; //PostError(DiosFrameError, buf.str().c_str()); mLog::FERROR("Post FrameError.%s", buf.str().c_str()); return false; } } //多个路径情况下,是否有一个Active if (VecCount > 1) { if (RouteLineActived == false) { ostringstream buf; buf << "No Specific Route Actived in Multiple OutRouteLines.RouteName:" << iter->second->GetName(); //PostError(DiosFrameError, buf.str().c_str()); mLog::FERROR("Post FrameError.%s", buf.str().c_str()); return false; } } } ++iter; } //InRouteLine的检查 DWORD RouteCount = m_pGlobalRoute->GetRouteLineCount(); DiosStMRouteLine** RouteLines = m_pGlobalRoute->GetOutRouteLineVec(); for (DWORD i = 0; i < RouteCount; i++) { //Des的有效性 const char* pDes = RouteLines[i]->GetDesName(); map::iterator desok = m_pRoutePosMap->find(string(pDes)); if (desok == m_pRoutePosMap->end()) { //no des ostringstream buf; buf << "No Destination of InRouteLine.DesName:" << pDes; //PostError(DiosFrameError, buf.str().c_str()); mLog::FERROR("Post FrameError.%s", buf.str().c_str()); return false; } } //第一个RouteLine DWORD firstRTLCount = (*m_pRoutePosMap)[m_StmEntryPosName]->GetRouteLineCount(); if (firstRTLCount == 0 || firstRTLCount > 1) { ostringstream buf; buf << "No First RouteLine or Multiple Routeline"; //PostError(DiosFrameError, buf.str().c_str()); mLog::FERROR("Post FrameError.%s", buf.str().c_str()); return false; } //无法检查全局ERROR事件的状态点 return true; } DWORD CalcMaximumTimeout(DiosStMRouteLine** pVec, DWORD Count) { DWORD timeout = 0; if (pVec != NULL && Count > 0) { for (DWORD i = 0; i < Count; i++) { if (pVec[i]->GetActiveState()) { if (pVec[i]->GetTimeout() > timeout) { timeout = pVec[i]->GetTimeout(); } } } } return timeout; } /// /// 等待全局事件和当前状态的事件的发生 /// 可能是当前状态的常规跳转,也可能是全局事件的跳转 /// /// 实际发生的事件触发的目标状态路由 DiosStMRouteLine* DiosSMachineIF::StateMachineWaitForEvents() { //当前状态的事件列表 DiosStMRouteLine *pNextLine = m_pCurrentRoutePos->WaitFroNextState(100); if (pNextLine != nullptr) return pNextLine; pNextLine = WaitNotfiyProcess(); return pNextLine; } //DiosStMRouteLine* DiosSMachineIF::StateMachineWaitForEvents(int& ExtEvtIndex) //{ // ExtEvtIndex = -1; // // //after state action,do notify hit a state pos. // DiosStMRoutePos* pCurPos = GetCurrentRoutePos(); // if (pCurPos) // { // ResDataObject StatePos; // StatePos.add(GetStateMachineName(), pCurPos->GetName()); // PushStateChange(StatePos); // } // // DiosStMRouteLine** pLocal = NULL; // DWORD LocalCount = (DWORD)m_pRouteInLineMap->size(); // if (LocalCount > 0) // { // pLocal = &((*m_pRouteInLineMap)[0]); // } // // DWORD OutLineCount = m_pCurrentRoutePos->GetRouteLineCount(); // DiosStMRouteLine** pOutline = m_pCurrentRoutePos->GetOutRouteLineVec(); // // // DWORD MaxTimeout = CalcMaximumTimeout(pLocal, LocalCount);//local // DWORD timeout = CalcMaximumTimeout(pOutline, OutLineCount);//outline // if (timeout > MaxTimeout) // { // MaxTimeout = timeout; // } // // //timeout = CalcMaximumTimeout(m_pRouteExternalMap, (DWORD)m_RouteExternalEvtCount);//external // //if (timeout > MaxTimeout) // //{ // // MaxTimeout = timeout; // //} // // for (int i = 0; i < 2; i++) // { // // int ret = 0; // // ret = StateMachineWaitForEvents( // pLocal, LocalCount, // //m_pRouteExternalMap, (DWORD)m_RouteExternalEvtCount, // pOutline, OutLineCount, // MaxTimeout); // // if (ret >= 0) // { // if ((DWORD)ret < LocalCount) // { // //local // return pLocal[ret]; // } // //else if ((DWORD)ret < LocalCount + m_RouteExternalEvtCount) // //{ // // //external // // ExtEvtIndex = ret - LocalCount; // // return NULL; // //} // // //outline // ret -= (LocalCount /*+ (DWORD)m_RouteExternalEvtCount*/); // return pOutline[ret]; //第几条出事件路由 // } // else if (ret == -1) // { // //PostError(DiosFrameError); // // mLog::FERROR("Timeout .Post FrameError."); // // } // else if (ret == -2) // { // //PostError(DiosFrameError); // // mLog::FERROR("Device Error .Post FrameError."); // // } // else if (ret == -3) // { // ExtEvtIndex = -2;//thread exit // return NULL; // } // // // // } // // assert(0);//必须要有异常处理的方案,没有情况直接蹦. // mLog::FERROR("No Exption Method."); // // return NULL; //} //INT DiosSMachineIF::EnterSubStateMachine(HANDLE ThreadExitEvt) //{ // DiosSubSMachine* pSub = (DiosSubSMachine*)m_pCurrentRoutePos; // // size_t WaitCount = m_RouteExternalEvtCount + m_pRouteInLineMap->size(); // vector ExternalWaitEvts; // // //merge externalevts + internalevts // for (DWORD i = 0; i < m_RouteExternalEvtCount; i++) // { // ExternalWaitEvts.push_back(m_pRouteExternalMap[i]); // } // // for (DWORD i = 0; i < m_pRouteInLineMap->size(); i++) // { // ExternalWaitEvts.push_back((*m_pRouteInLineMap)[i]); // } // // return pSub->ExecStateMachine(ThreadExitEvt, &(ExternalWaitEvts[0]), WaitCount); // //} void DiosSMachineIF::SetDebugMode(bool bEnable) { m_bDebugEnable = bEnable; } //设置状态断点,IN/ACTION/OUT 三个断点位置可以设置 void DiosSMachineIF::EnableBreakPoint(const char* pState, bool bBreakInEable, bool bActionInEnable, bool bBreakOutEnable) { auto it = m_pRoutePosMap->find(pState); if (it != m_pRoutePosMap->end()) { DiosStMRoutePos* pPos = it->second; pPos->SetBreak(bBreakInEable, bActionInEnable, bBreakOutEnable); } } //继续运行,当处于中断状态时 void DiosSMachineIF::Continue() { SetEvent(m_hBreaked); } //获取状态的所有事件的激活值 void DiosSMachineIF::GetEventStatus(const char* pState, const char* pszEvent) { } //获取当前断点位置 void DiosSMachineIF::GetCurrentBreak() { } //等待继续事件触发 void DiosSMachineIF::WaitContinue() { WaitForSingleObject(m_hBreaked, INFINITE); } INT DiosSMachineIF::ExecStateMachine(HANDLE ThreadExitEvt/*, DiosStMRouteLine* pExternalWaitEvts[], size_t WaitCount*/) { DIOSSTMRET ret = DIOSSMRET_OK; ClearState(); SetRunningState(true); //if (pExternalWaitEvts != NULL && WaitCount > 0) //{ // m_RouteExternalEvtCount = WaitCount; // m_pRouteExternalMap = &pExternalWaitEvts[0]; //} //m_pCurrentRoutePos = (*m_pRoutePosMap)[string(DiosStmEntryPosName)]; TransToPos(m_StmEntryPosName.c_str()); //入口Action,执行入口的Action ret = StateMachineEntry(m_pCurrentRoutePos->GetTimeout()); if (ret != DIOSSMRET_OK) { //PostError(DiosFrameError); mLog::FERROR("StateMachineEntry Failed."); return -1; } do { //wait events DiosStMRouteLine* pRouteLine = StateMachineWaitForEvents(); //m_pCurrentRoutePos->WaitFroNextState(1000); //(RouteWay); if (pRouteLine == nullptr) { //没有事件触发跳转到下一个状态 m_pCurrentRoutePos->CheckTimeout(); //如果需要继续运行,则下一个等待循环 if (WaitForSingleObject(m_RunningState, 1) == WAIT_OBJECT_0) continue; mLog::FINFO("StateMachineWaitForEvents got external evt.exit sub state machine."); TransToPos(m_StmExitPosName.c_str()); //run action without results ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout()); //SetRunningState(false); return -1; } else { //this machine if (pRouteLine->GetActiveState()) { //Guard const char* pGuard = pRouteLine->GetGuardName(); if (pGuard != NULL && strlen(pGuard) > 0) { ret = StateMachineGuard(pGuard, TIMEOUT_TEMP); if (ret != DIOSSMRET_OK) { continue; } } } //TransToPos TransToPos(pRouteLine->GetDesName()); mLog::FINFO("TransToPos:%s", pRouteLine->GetDesName()); if (m_StmExitPosName == m_pCurrentRoutePos->GetName()) { //exit //run action without results ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout()); //check ret if (ret != DIOSSMRET_OK) { //PostError(DiosFrameError); mLog::FERROR("PostError DiosFrameError .curPos:%s", m_pCurrentRoutePos->GetName()); continue; } //exit here SetRunningState(false); return -1; } //statepos or statemachine if (m_pCurrentRoutePos->GetActiveState()) { //if (m_pCurrentRoutePos->IsSMachine()) //{ // //copy evt in // CopyEvtTo((DiosSubSMachine*)m_pCurrentRoutePos); // //run sub state machine // INT ExitWay = EnterSubStateMachine(ThreadExitEvt); // mLog::FINFO("exit from sub sm.%s,ret:%d", m_pCurrentRoutePos->GetName(), ExitWay); // //copy evt out // ((DiosSubSMachine*)m_pCurrentRoutePos)->CopyEvtTo(this); // //trans to position // if (ExitWay >= 0) // { // if ((size_t)ExitWay < m_RouteExternalEvtCount) // { // mLog::FINFO("exit from statemachine.%s", m_pCurrentRoutePos->GetName()); // //external evt // TransToPos(m_StmExitPosName.c_str()); // //run action without results // ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout()); // //一旦在Exit出错,会再次进入WaitEvt,再执行Exit,.........dead loop // //if (ret != DIOSSMRET_OK) // //{ // // continue; // //} // SetRunningState(false); // return ExitWay; // } // else // { // //local evt // //trans to pos // RouteWay = -1; // pRouteLine = (*m_pRouteInLineMap)[ExitWay - m_RouteExternalEvtCount]; // goto RouteLine_Process; // } // } // else // { // //outline .normal exit from statemachine // mLog::FINFO("exit from sub statemachine"); // } //} //else { //run action ret = m_pCurrentRoutePos->DoAction(this);// StateMachineAction(m_pCurrentRoutePos->GetName(), m_pCurrentRoutePos->GetTimeout()); mLog::FINFO("SmAction:%s.RET:%d", m_pCurrentRoutePos->GetName(), ret); //check ret if (ret != DIOSSMRET_OK) { if (ret == DIOSSMRET_EXIT) { //这个函数默认是不会返回EXIT的,除非重写了 //exit thread //goto exitpos TransToPos(m_StmExitPosName.c_str()); //run action without results ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout()); SetRunningState(false); return -1; } //执行Action出问题, //交给状态机的内部逻辑 //PostError(DiosFrameError); mLog::FERROR("StateMachineAction Exec Action Error .curPos:%s", m_pCurrentRoutePos->GetName()); } } } } } while (1); SetRunningState(false); return -1; } DiosStMRouteLine* DiosSMachineIF::WaitNotfiyProcess() { return nullptr; }