123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245 |
- #include "stdafx.h"
- #include "DiosSMachineV3.h"
- DiosSMachineIF::DiosSMachineIF()
- {
- m_pStateMachineName = new string();
- //m_pParent = 0;
- m_pCurrentRoutePos = NULL;
- //evt list
- m_pArrivedEvts = new MsgCircle<DiosStMEvt>();
- //routepos
- m_pRoutePosMap = new map<string, DiosStMRoutePos*>();
- 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<DiosStMRouteLine*>();
- 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<string, DiosStMRoutePos*>::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<string, DiosStMRoutePos*>::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<string, DiosStMRoutePos*>::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<string, DiosStMRoutePos*>::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<string, DiosStMRoutePos*>::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<string, DiosStMRoutePos*>::iterator iter = m_pRoutePosMap->begin();
- while (iter != m_pRoutePosMap->end())
- {
- //if (iter->second->IsSMachine())
- //{
- // //sub machine
- // DiosSubSMachine* pSub = static_cast<DiosSubSMachine*>(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<string, DiosStMRoutePos*>::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<string, DiosStMRoutePos*>::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;
- }
- /// <summary>
- /// 等待全局事件和当前状态的事件的发生
- /// 可能是当前状态的常规跳转,也可能是全局事件的跳转
- /// </summary>
- /// <returns>实际发生的事件触发的目标状态路由</returns>
- 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<DiosStMRouteLine*> 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;
- }
|