DiosSMachineIF.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245
  1. #include "stdafx.h"
  2. #include "DiosSMachineV3.h"
  3. DiosSMachineIF::DiosSMachineIF()
  4. {
  5. m_pStateMachineName = new string();
  6. //m_pParent = 0;
  7. m_pCurrentRoutePos = NULL;
  8. //evt list
  9. m_pArrivedEvts = new MsgCircle<DiosStMEvt>();
  10. //routepos
  11. m_pRoutePosMap = new map<string, DiosStMRoutePos*>();
  12. DiosStMRoutePos* p = NULL;
  13. //状态机开始的时候才赋值
  14. //p = new DiosStMRoutePos(DiosStmEntryPosName);
  15. //p->Active(true, TIMEOUT_TEMP);
  16. //(*m_pRoutePosMap)[DiosStmEntryPosName] = p;
  17. //p = new DiosStMRoutePos(DiosStmExitPosName);
  18. //p->Active(true, TIMEOUT_TEMP);
  19. //(*m_pRoutePosMap)[DiosStmExitPosName] = p;
  20. //inline
  21. //m_pRouteInLineMap = new vector<DiosStMRouteLine*>();
  22. m_pGlobalRoute = nullptr; // new DiosStMRoutePos("Global");
  23. //external
  24. //m_RouteExternalEvtCount = 0;
  25. //m_pRouteExternalMap = NULL;
  26. //running state
  27. m_RunningState = CreateEvent(0, 1, 0, 0);
  28. m_StateCangeEvt = CreateEvent(0, 0, 0, 0);
  29. m_strCurrentPos = "";
  30. m_StateNotify = nullptr;
  31. }
  32. DiosSMachineIF::~DiosSMachineIF()
  33. {
  34. delete m_pStateMachineName;
  35. m_pStateMachineName = 0;
  36. //cp
  37. m_pCurrentRoutePos = NULL;
  38. //external
  39. //m_RouteExternalEvtCount = 0;
  40. //m_pRouteExternalMap = NULL;
  41. //clear inline path
  42. //for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  43. //{
  44. // delete (*m_pRouteInLineMap)[i];
  45. //}
  46. //delete m_pRouteInLineMap;
  47. //m_pRouteInLineMap = NULL;
  48. delete m_pGlobalRoute;
  49. m_pGlobalRoute = NULL;
  50. //clear routepos
  51. map<string, DiosStMRoutePos*>::iterator iter = m_pRoutePosMap->begin();
  52. while (iter != m_pRoutePosMap->end())
  53. {
  54. //if (iter->second->IsSMachine())
  55. //{
  56. // DiosSubSMachine* pSub = (DiosSubSMachine*)iter->second;
  57. // delete pSub;
  58. //}
  59. //else
  60. {
  61. delete iter->second;
  62. }
  63. ++iter;
  64. }
  65. delete m_pRoutePosMap;
  66. m_pRoutePosMap = NULL;
  67. //evt list
  68. delete m_pArrivedEvts;
  69. m_pArrivedEvts = NULL;
  70. CloseHandle(m_RunningState);
  71. CloseHandle(m_StateCangeEvt);
  72. return;
  73. }
  74. void DiosSMachineIF::SetStateMachineName(const char* pszName)
  75. {
  76. (*m_pStateMachineName) = pszName;
  77. }
  78. const char* DiosSMachineIF::GetStateMachineName()
  79. {
  80. return m_pStateMachineName->c_str();
  81. }
  82. void DiosSMachineIF::SetMachineName(const char* pszEntryName, const char* pszExitName) //设置状态机名称及进出状态名称
  83. {
  84. m_StmEntryPosName = pszEntryName;
  85. m_StmExitPosName = pszExitName;
  86. }
  87. //设置用户变量,只提供根一层的Key
  88. void DiosSMachineIF::SetUserVariable(const char* pKey, ResDataObject& resValue)
  89. {
  90. int vidx = m_resUserVariable.GetFirstOf(pKey);
  91. if (vidx < 0)
  92. m_resUserVariable.add(pKey, resValue);
  93. else
  94. m_resSystemVariable.update(pKey, resValue);
  95. }
  96. //读取用户变量值,只提供根一层的Key
  97. void DiosSMachineIF::GetUserVariable(const char* pKey, ResDataObject& resValue)
  98. {
  99. if (pKey == nullptr)
  100. {
  101. resValue = m_resUserVariable;
  102. return;
  103. }
  104. int vidx = m_resUserVariable.GetFirstOf(pKey);
  105. if (vidx >= 0)
  106. resValue = m_resUserVariable[vidx];
  107. }
  108. //读取系统变量,只提供跟一层的Key
  109. void DiosSMachineIF::GetSystemVariable(const char* pKey, ResDataObject& resValue) //读取系统变量
  110. {
  111. if (pKey == nullptr)
  112. {
  113. resValue = m_resSystemVariable;
  114. return;
  115. }
  116. int vidx = m_resSystemVariable.GetFirstOf(pKey);
  117. if (vidx >= 0)
  118. resValue = m_resSystemVariable[vidx];
  119. }
  120. void DiosSMachineIF::EnableEvent(const char* pszGlobalEvent, bool state)
  121. {
  122. /*auto it = m_pRouteInLineMap->begin();
  123. while (it != m_pRouteInLineMap->end())
  124. {
  125. (*it)->Active(state, 0);
  126. it++;
  127. }*/
  128. m_pGlobalRoute->Active(state, 0);
  129. }
  130. //void DiosSMachineIF::SetParentSMachine(DiosSMachineIF* pParent)
  131. //{
  132. // m_pParent = pParent;
  133. //}
  134. void DiosSMachineIF::PushStateChange(ResDataObject& ChangedPos)
  135. {
  136. //if (m_pParent)
  137. //{
  138. // m_pParent->PushStateChange(ChangedPos);
  139. //}
  140. }
  141. //bool DiosSMachineIF::IsSMachine()
  142. //{
  143. // return true;
  144. //}
  145. HANDLE DiosSMachineIF::GetStateChangeEvtHandle()
  146. {
  147. return m_StateCangeEvt;
  148. }
  149. void DiosSMachineIF::SetRunningState(bool Running)
  150. {
  151. Thread_Lock();
  152. if (Running)
  153. {
  154. SetEvent(m_RunningState);
  155. }
  156. else
  157. {
  158. ResetEvent(m_RunningState);
  159. }
  160. Thread_UnLock();
  161. }
  162. bool DiosSMachineIF::GetRunningState(DWORD waittime)
  163. {
  164. bool ret = (WaitForSingleObject(m_RunningState, waittime) == WAIT_OBJECT_0);
  165. if (ret == false)
  166. {
  167. printf("GetRunningState Failed.WTF??\n");
  168. }
  169. return ret;
  170. }
  171. //init state machine
  172. //第一个节点的接入比较特殊,所以做了个函数
  173. bool DiosSMachineIF::AddEntryRoutePos(DiosStMRoutePos* pPos)
  174. {
  175. if (strlen(pPos->GetName()) == 0)
  176. {
  177. return false;
  178. }
  179. if ((*m_pRoutePosMap)[m_StmEntryPosName]->GetRouteLineCount() > 0)
  180. {
  181. return false;
  182. }
  183. //add pos
  184. //(*m_pRoutePosMap)[pPos->GetName()] = pPos;
  185. //DiosStMEvt evt;
  186. //make a line
  187. //(*m_pRoutePosMap)[m_StmEntryPosName]->PosAddOutRouteLine(evt, m_StmEntryPosName.c_str(), NULL, pPos->GetName());
  188. return true;
  189. }
  190. bool DiosSMachineIF::AddRoutePos(DiosStMRoutePos* pPos)
  191. {
  192. if (strlen(pPos->GetName()) == 0)
  193. {
  194. return false;
  195. }
  196. //add pos
  197. (*m_pRoutePosMap)[pPos->GetName()] = pPos;
  198. return true;
  199. }
  200. bool DiosSMachineIF::AddInRouteLine(DiosStMEvt& Evt, const char* pGuardName, const char* pDesPosName)
  201. {
  202. DiosStMRouteLine* pLine = new DiosStMRouteLine();
  203. pLine->SetRoute(Evt, pGuardName, pDesPosName);
  204. pLine->Active(true, 0);//timeout没必要,因为是全局事件
  205. //m_pRouteInLineMap->push_back(pLine);
  206. m_pGlobalRoute->PosAddOutRouteLine(&Evt, "Global", pGuardName, pDesPosName);
  207. return true;
  208. }
  209. bool DiosSMachineIF::AddOutRouteLine(DiosStMEvt* Evt, const char* pSrcPosName, const char* pGuardName, const char* pDesPosName)
  210. {
  211. bool ret = true;
  212. try {
  213. ret = (*m_pRoutePosMap)[pSrcPosName]->PosAddOutRouteLine(Evt, pSrcPosName, pGuardName, pDesPosName);
  214. }
  215. catch (...)
  216. {
  217. ret = false;
  218. }
  219. return ret;
  220. }
  221. //active state machine
  222. bool DiosSMachineIF::ActiveRoutePos(const char* pPosName, DWORD timeout)
  223. {
  224. bool ret = true;
  225. try {
  226. map<string, DiosStMRoutePos*>::iterator iterOut = m_pRoutePosMap->find(pPosName);
  227. if (iterOut != m_pRoutePosMap->end())
  228. {
  229. (*m_pRoutePosMap)[pPosName]->Active(true, timeout);
  230. }
  231. ////find sub route machine
  232. //iterOut = (*m_pRoutePosMap).begin();
  233. //while (iterOut != (*m_pRoutePosMap).end())
  234. //{
  235. // if (iterOut->second->IsSMachine() == true)
  236. // {
  237. // DiosSubSMachine* pSub = (DiosSubSMachine*)(iterOut->second);
  238. // pSub->ActiveRoutePos(pPosName, timeout);
  239. // }
  240. // ++iterOut;
  241. //}
  242. }
  243. catch (...)
  244. {
  245. ret = false;
  246. }
  247. return ret;
  248. }
  249. //bool DiosSMachineIF::ActiveInRouteLine(DiosStMEvt &Evt, DWORD timeout)
  250. //{
  251. // bool ret = false;
  252. // try{
  253. // //find In Route Line
  254. // for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  255. // {
  256. // if ((*(DiosStMEvt*)(*(*m_pRouteInLineMap)[i])) == Evt)
  257. // {
  258. // (*m_pRouteInLineMap)[i]->Active(true,timeout);
  259. //
  260. // ret = true;
  261. //
  262. // break;
  263. // }
  264. // }
  265. //
  266. // }
  267. // catch (...)
  268. // {
  269. // ret = false;
  270. // }
  271. //
  272. // return ret;
  273. //
  274. //}
  275. bool DiosSMachineIF::ActiveRouteLine(DiosStMEvt& Evt, DWORD timeout)
  276. {
  277. bool ret = true;
  278. try {
  279. //out path
  280. map<string, DiosStMRoutePos*>::iterator iterOut = (*m_pRoutePosMap).begin();
  281. while (iterOut != (*m_pRoutePosMap).end())
  282. {
  283. if (iterOut->second->IsSMachine() == false)
  284. {
  285. DWORD RouteCount = iterOut->second->GetRouteLineCount();
  286. DiosStMRouteLine** RouteLines = iterOut->second->GetOutRouteLineVec();
  287. for (DWORD i = 0; i < RouteCount; i++)
  288. {
  289. if ((*(DiosStMEvt*)(*(RouteLines[i]))) == Evt)
  290. {
  291. RouteLines[i]->Active(true, timeout);
  292. }
  293. }
  294. }
  295. else
  296. {
  297. //子对象自行激活自己
  298. //DiosSubSMachine *pSub = (DiosSubSMachine *)(iterOut->second);
  299. //pSub->ActiveRouteLine(Evt, timeout);
  300. }
  301. ++iterOut;
  302. }
  303. //in path
  304. //for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  305. //{
  306. // if ((*(DiosStMEvt*)(*((*m_pRouteInLineMap)[i]))) == Evt)
  307. // {
  308. // (*m_pRouteInLineMap)[i]->Active(true, timeout);
  309. // }
  310. //}
  311. DWORD RouteCount = m_pGlobalRoute->GetRouteLineCount();
  312. DiosStMRouteLine** RouteLines = m_pGlobalRoute->GetOutRouteLineVec();
  313. for (DWORD i = 0; i < RouteCount; i++)
  314. {
  315. if ((*(DiosStMEvt*)(*(RouteLines[i]))) == Evt)
  316. {
  317. RouteLines[i]->Active(true, timeout);
  318. }
  319. }
  320. //DiosStMRouteLine* pLine = (*(*m_pRoutePosMap)[pPosName])[Evt];
  321. //if (pLine)
  322. //{
  323. // pLine->Active(true, timeout);
  324. // ret = true;
  325. //}
  326. }
  327. catch (...)
  328. {
  329. ret = false;
  330. }
  331. return ret;
  332. }
  333. bool DiosSMachineIF::DeActiveAll()
  334. {
  335. bool ret = true;
  336. try {
  337. //out path
  338. map<string, DiosStMRoutePos*>::iterator iterOut = (*m_pRoutePosMap).begin();
  339. while (iterOut != (*m_pRoutePosMap).end())
  340. {
  341. //if (iterOut->second->IsSMachine() == false)
  342. {
  343. //deactive pos
  344. iterOut->second->Active(false, 0);
  345. //deactive line
  346. DWORD RouteCount = iterOut->second->GetRouteLineCount();
  347. DiosStMRouteLine** RouteLines = iterOut->second->GetOutRouteLineVec();
  348. for (DWORD i = 0; i < RouteCount; i++)
  349. {
  350. RouteLines[i]->Active(false, 0);
  351. }
  352. }
  353. //else
  354. //{
  355. // DiosSubSMachine* pSub = (DiosSubSMachine*)(iterOut->second);
  356. // pSub->DeActiveAll();
  357. //}
  358. ++iterOut;
  359. }
  360. //in path
  361. //for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  362. //{
  363. // (*m_pRouteInLineMap)[i]->Active(false, 0);
  364. //}
  365. DWORD RouteCount = m_pGlobalRoute->GetRouteLineCount();
  366. DiosStMRouteLine** RouteLines = m_pGlobalRoute->GetOutRouteLineVec();
  367. for (DWORD i = 0; i < RouteCount; i++)
  368. {
  369. RouteLines[i]->Active(false, 0);
  370. }
  371. }
  372. catch (...)
  373. {
  374. ret = false;
  375. }
  376. return ret;
  377. }
  378. void DiosSMachineIF::ClearState()
  379. {
  380. Thread_Lock();
  381. SetRunningState(false);
  382. map<string, DiosStMRoutePos*>::iterator iterOut = (*m_pRoutePosMap).begin();
  383. //while (iterOut != (*m_pRoutePosMap).end())
  384. //{
  385. // if (iterOut->second->IsSMachine())
  386. // {
  387. // DiosSubSMachine* pSub = (DiosSubSMachine*)(iterOut->second);
  388. // pSub->ClearState();
  389. // }
  390. // ++iterOut;
  391. //}
  392. auto iter = m_pRoutePosMap->find(m_StmEntryPosName);
  393. if (iter != m_pRoutePosMap->end())
  394. {
  395. delete (*m_pRoutePosMap)[m_StmEntryPosName] ;
  396. m_pRoutePosMap->erase(iter);
  397. //(*m_pRoutePosMap)[m_StmEntryPosName] = nullptr;
  398. }
  399. iter = m_pRoutePosMap->find(m_StmExitPosName);
  400. if (iter != m_pRoutePosMap->end())
  401. {
  402. delete (*m_pRoutePosMap)[m_StmExitPosName];
  403. m_pRoutePosMap->erase(iter);// m_StmExitPosName] = nullptr;
  404. }
  405. m_pCurrentRoutePos = NULL;
  406. m_strCurrentPos = "";
  407. m_pArrivedEvts->Clear();
  408. //m_RouteExternalEvtCount = 0;
  409. //m_pRouteExternalMap = NULL;
  410. Thread_UnLock();
  411. }
  412. HANDLE DiosSMachineIF::GetEvtNotifyHandle()
  413. {
  414. return (*m_pArrivedEvts).GetNotifyHandle();
  415. }
  416. bool DiosSMachineIF::PeekEvent(DiosStMEvt& Evt)
  417. {
  418. //check it's existance
  419. return (*m_pArrivedEvts).Peek(Evt);
  420. }
  421. //evt
  422. bool DiosSMachineIF::PopEvent(DiosStMEvt& Evt)
  423. {
  424. return (*m_pArrivedEvts).DeQueue(Evt);
  425. }
  426. bool DiosSMachineIF::PushEvent(DiosStMEvt& Evt)
  427. {
  428. bool ret = false;
  429. Thread_Lock();
  430. /*if (m_pCurrentRoutePos)
  431. {
  432. if (m_pCurrentRoutePos->IsSMachine())
  433. {
  434. DiosSubSMachine* pMachine = (DiosSubSMachine*)m_pCurrentRoutePos;
  435. pMachine->Thread_Lock();
  436. if (pMachine->GetRunningState() == true)
  437. {
  438. ret = pMachine->PushEvent(Evt);
  439. pMachine->Thread_UnLock();
  440. Thread_UnLock();
  441. return ret;
  442. }
  443. pMachine->Thread_UnLock();
  444. }
  445. }
  446. Thread_UnLock();*/
  447. //check it's existance
  448. (*m_pArrivedEvts).Lock();
  449. DWORD size = (*m_pArrivedEvts).size();
  450. for (DWORD i = 0; i < size; i++)
  451. {
  452. if ((*m_pArrivedEvts)[i] == Evt)
  453. {
  454. (*m_pArrivedEvts).UnLock();
  455. return ret;
  456. }
  457. }
  458. ret = true;
  459. (*m_pArrivedEvts).InQueue(Evt);
  460. (*m_pArrivedEvts).UnLock();
  461. return true;
  462. }
  463. //for state machine thread
  464. DIOSSTMRET DiosSMachineIF::StateMachineEntry(DWORD timeout)
  465. {
  466. m_pCurrentRoutePos->DoIn(this);
  467. return m_pCurrentRoutePos->DoAction(this);
  468. }
  469. DIOSSTMRET DiosSMachineIF::StateMachineExit(DWORD timeout)
  470. {
  471. return DIOSSMRET_OK;
  472. }
  473. DIOSSTMRET DiosSMachineIF::StateMachineAction(const char* pAction, DWORD timeout)
  474. {
  475. return m_pCurrentRoutePos->DoAction(this);
  476. }
  477. DIOSSTMRET DiosSMachineIF::StateMachineGuard(const char* pGuard, DWORD timeout)
  478. {
  479. return DIOSSMRET_OK;
  480. }
  481. //int DiosSMachineIF::StateMachineWaitForEvents(
  482. // DiosStMRouteLine* pLocalEvts[], DWORD CountOfLocal,
  483. // //DiosStMRouteLine* pExternalEvts[], DWORD CountOfExternal,
  484. // DiosStMRouteLine* pOutpathEvts[], DWORD CountOfOutpath,
  485. // DWORD timeout
  486. //)
  487. //{
  488. // //执行最基础的处理
  489. // return -1;
  490. //}
  491. DiosStMRoutePos* DiosSMachineIF::GetCurrentRoutePos()
  492. {
  493. return m_pCurrentRoutePos;
  494. }
  495. DIOSSTMRET DiosSMachineIF::TransToPos(const char* pPosName)
  496. {
  497. DIOSSTMRET ret = DIOSSMRET_OK;
  498. //des check
  499. try {
  500. Thread_Lock();
  501. m_pCurrentRoutePos->DoOut(this);
  502. m_pCurrentRoutePos = (*m_pRoutePosMap)[string(pPosName)];
  503. m_pCurrentRoutePos->DoIn(this);
  504. //要通知设备池,设置新的事件列表
  505. m_strCurrentPos = pPosName;
  506. Thread_UnLock();
  507. //先回调再通知
  508. if (m_StateNotify != nullptr)
  509. {
  510. m_StateNotify(m_pStateMachineName->c_str(), m_strCurrentPos.c_str());
  511. }
  512. SetEvent(m_StateCangeEvt);
  513. printf("Trans To %s \n", pPosName);
  514. }
  515. catch (...)
  516. {
  517. assert(0);//never gonna reach
  518. ret = DIOSSMRET_NG;
  519. }
  520. return ret;
  521. }
  522. //这里的Error必须是状态机的Error,而不是业务方面的错误,比如action失败,不算
  523. void DiosSMachineIF::PostError(const char* pErrorVal, const char* pErrorInfo)
  524. {
  525. /*
  526. DiosStMEvt evt;
  527. if (pErrorVal)
  528. {
  529. printf("--PostError:%s--\n", pErrorVal);
  530. }
  531. else
  532. {
  533. printf("--PostError:Empty--\n");
  534. }
  535. evt.SetEvt(DiosErrorType, pErrorVal, pErrorInfo);
  536. PushEvent(evt);*/
  537. }
  538. DiosStMRouteLine* DiosSMachineIF::GetEntryRouteLine()
  539. {
  540. //routepos
  541. DiosStMRoutePos* pFirst = (*m_pRoutePosMap)[m_StmEntryPosName];
  542. if (pFirst)
  543. {
  544. if (pFirst->GetRouteLineCount() == 1)
  545. {
  546. return ((m_pCurrentRoutePos->GetOutRouteLineVec())[0]);
  547. }
  548. }
  549. return NULL;
  550. }
  551. //void DiosSMachineIF::CopyEvtTo(DiosSMachineIF* pDes)
  552. //{
  553. // //排序上先ORG的消息,然后des的消息
  554. // bool ret = true;
  555. // DiosStMEvt Evt;
  556. //
  557. // //copy des to org
  558. // while (ret)
  559. // {
  560. // ret = pDes->PopEvent(Evt);
  561. // if (ret)
  562. // {
  563. // PushEvent(Evt);
  564. // }
  565. // }
  566. //
  567. //
  568. // //org -> des
  569. // ret = true;
  570. // while (ret)
  571. // {
  572. // ret = PopEvent(Evt);
  573. // if (ret)
  574. // {
  575. // pDes->PushEvent(Evt);
  576. // }
  577. // }
  578. //
  579. //}
  580. //检查:路径,状态点,以及它们的ActiveState
  581. bool DiosSMachineIF::PrePareStateMachine()
  582. {
  583. /**/
  584. //DiosStMRoutePos* p = NULL;
  585. //p = new DiosStMRoutePos(m_StmEntryPosName.c_str(), m_pDevicePool);
  586. //p->Active(true, TIMEOUT_TEMP);
  587. //(*m_pRoutePosMap)[m_StmEntryPosName] = p;
  588. //p = new DiosStMRoutePos(m_StmExitPosName.c_str(), m_pDevicePool);
  589. //p->Active(true, TIMEOUT_TEMP);
  590. //(*m_pRoutePosMap)[m_StmExitPosName] = p;
  591. //状态点的检查
  592. map<string, DiosStMRoutePos*>::iterator iter = m_pRoutePosMap->begin();
  593. while (iter != m_pRoutePosMap->end())
  594. {
  595. //if (iter->second->IsSMachine())
  596. //{
  597. // //sub machine
  598. // DiosSubSMachine* pSub = static_cast<DiosSubSMachine*>(iter->second);
  599. // if (pSub->PrePareStateMachine() == false)
  600. // {
  601. // ostringstream buf;
  602. // buf << "Sub StateMachine Error.Name:" << (iter->second)->GetName();
  603. // //PostError(DiosFrameError, buf.str().c_str());
  604. // mLog::FERROR("Post FrameError.%s", buf.str().c_str());
  605. // return false;//submachine err
  606. // }
  607. //}
  608. //else
  609. {
  610. //route pos
  611. bool RouteLineActived = false;
  612. //OutRouteLine的检查
  613. DWORD VecCount = iter->second->GetRouteLineCount();
  614. DiosStMRouteLine** pVec = iter->second->GetOutRouteLineVec();
  615. for (DWORD i = 0; i < VecCount; i++)
  616. {
  617. //Activestate
  618. RouteLineActived |= pVec[i]->GetActiveState();
  619. //Des的有效性
  620. const char* pDes = pVec[i]->GetDesName();
  621. map<string, DiosStMRoutePos*>::iterator desok = m_pRoutePosMap->find(string(pDes));
  622. if (desok == m_pRoutePosMap->end())
  623. {
  624. //no des
  625. ostringstream buf;
  626. buf << "No Destination of RouteLine.RouteName:" << iter->second->GetName() << "DesName:" << pDes;
  627. //PostError(DiosFrameError, buf.str().c_str());
  628. mLog::FERROR("Post FrameError.%s", buf.str().c_str());
  629. return false;
  630. }
  631. }
  632. //多个路径情况下,是否有一个Active
  633. if (VecCount > 1)
  634. {
  635. if (RouteLineActived == false)
  636. {
  637. ostringstream buf;
  638. buf << "No Specific Route Actived in Multiple OutRouteLines.RouteName:" << iter->second->GetName();
  639. //PostError(DiosFrameError, buf.str().c_str());
  640. mLog::FERROR("Post FrameError.%s", buf.str().c_str());
  641. return false;
  642. }
  643. }
  644. }
  645. ++iter;
  646. }
  647. //InRouteLine的检查
  648. DWORD RouteCount = m_pGlobalRoute->GetRouteLineCount();
  649. DiosStMRouteLine** RouteLines = m_pGlobalRoute->GetOutRouteLineVec();
  650. for (DWORD i = 0; i < RouteCount; i++)
  651. {
  652. //Des的有效性
  653. const char* pDes = RouteLines[i]->GetDesName();
  654. map<string, DiosStMRoutePos*>::iterator desok = m_pRoutePosMap->find(string(pDes));
  655. if (desok == m_pRoutePosMap->end())
  656. {
  657. //no des
  658. ostringstream buf;
  659. buf << "No Destination of InRouteLine.DesName:" << pDes;
  660. //PostError(DiosFrameError, buf.str().c_str());
  661. mLog::FERROR("Post FrameError.%s", buf.str().c_str());
  662. return false;
  663. }
  664. }
  665. //第一个RouteLine
  666. DWORD firstRTLCount = (*m_pRoutePosMap)[m_StmEntryPosName]->GetRouteLineCount();
  667. if (firstRTLCount == 0 || firstRTLCount > 1)
  668. {
  669. ostringstream buf;
  670. buf << "No First RouteLine or Multiple Routeline";
  671. //PostError(DiosFrameError, buf.str().c_str());
  672. mLog::FERROR("Post FrameError.%s", buf.str().c_str());
  673. return false;
  674. }
  675. //无法检查全局ERROR事件的状态点
  676. return true;
  677. }
  678. DWORD CalcMaximumTimeout(DiosStMRouteLine** pVec, DWORD Count)
  679. {
  680. DWORD timeout = 0;
  681. if (pVec != NULL && Count > 0)
  682. {
  683. for (DWORD i = 0; i < Count; i++)
  684. {
  685. if (pVec[i]->GetActiveState())
  686. {
  687. if (pVec[i]->GetTimeout() > timeout)
  688. {
  689. timeout = pVec[i]->GetTimeout();
  690. }
  691. }
  692. }
  693. }
  694. return timeout;
  695. }
  696. /// <summary>
  697. /// 等待全局事件和当前状态的事件的发生
  698. /// 可能是当前状态的常规跳转,也可能是全局事件的跳转
  699. /// </summary>
  700. /// <returns>实际发生的事件触发的目标状态路由</returns>
  701. DiosStMRouteLine* DiosSMachineIF::StateMachineWaitForEvents()
  702. {
  703. //当前状态的事件列表
  704. DiosStMRouteLine *pNextLine = m_pCurrentRoutePos->WaitFroNextState(100);
  705. if (pNextLine != nullptr)
  706. return pNextLine;
  707. pNextLine = WaitNotfiyProcess();
  708. return pNextLine;
  709. }
  710. //DiosStMRouteLine* DiosSMachineIF::StateMachineWaitForEvents(int& ExtEvtIndex)
  711. //{
  712. // ExtEvtIndex = -1;
  713. //
  714. // //after state action,do notify hit a state pos.
  715. // DiosStMRoutePos* pCurPos = GetCurrentRoutePos();
  716. // if (pCurPos)
  717. // {
  718. // ResDataObject StatePos;
  719. // StatePos.add(GetStateMachineName(), pCurPos->GetName());
  720. // PushStateChange(StatePos);
  721. // }
  722. //
  723. // DiosStMRouteLine** pLocal = NULL;
  724. // DWORD LocalCount = (DWORD)m_pRouteInLineMap->size();
  725. // if (LocalCount > 0)
  726. // {
  727. // pLocal = &((*m_pRouteInLineMap)[0]);
  728. // }
  729. //
  730. // DWORD OutLineCount = m_pCurrentRoutePos->GetRouteLineCount();
  731. // DiosStMRouteLine** pOutline = m_pCurrentRoutePos->GetOutRouteLineVec();
  732. //
  733. //
  734. // DWORD MaxTimeout = CalcMaximumTimeout(pLocal, LocalCount);//local
  735. // DWORD timeout = CalcMaximumTimeout(pOutline, OutLineCount);//outline
  736. // if (timeout > MaxTimeout)
  737. // {
  738. // MaxTimeout = timeout;
  739. // }
  740. //
  741. // //timeout = CalcMaximumTimeout(m_pRouteExternalMap, (DWORD)m_RouteExternalEvtCount);//external
  742. // //if (timeout > MaxTimeout)
  743. // //{
  744. // // MaxTimeout = timeout;
  745. // //}
  746. //
  747. // for (int i = 0; i < 2; i++)
  748. // {
  749. //
  750. // int ret = 0;
  751. //
  752. // ret = StateMachineWaitForEvents(
  753. // pLocal, LocalCount,
  754. // //m_pRouteExternalMap, (DWORD)m_RouteExternalEvtCount,
  755. // pOutline, OutLineCount,
  756. // MaxTimeout);
  757. //
  758. // if (ret >= 0)
  759. // {
  760. // if ((DWORD)ret < LocalCount)
  761. // {
  762. // //local
  763. // return pLocal[ret];
  764. // }
  765. // //else if ((DWORD)ret < LocalCount + m_RouteExternalEvtCount)
  766. // //{
  767. // // //external
  768. // // ExtEvtIndex = ret - LocalCount;
  769. // // return NULL;
  770. // //}
  771. //
  772. // //outline
  773. // ret -= (LocalCount /*+ (DWORD)m_RouteExternalEvtCount*/);
  774. // return pOutline[ret]; //第几条出事件路由
  775. // }
  776. // else if (ret == -1)
  777. // {
  778. // //PostError(DiosFrameError);
  779. //
  780. // mLog::FERROR("Timeout .Post FrameError.");
  781. //
  782. // }
  783. // else if (ret == -2)
  784. // {
  785. // //PostError(DiosFrameError);
  786. //
  787. // mLog::FERROR("Device Error .Post FrameError.");
  788. //
  789. // }
  790. // else if (ret == -3)
  791. // {
  792. // ExtEvtIndex = -2;//thread exit
  793. // return NULL;
  794. // }
  795. //
  796. //
  797. //
  798. // }
  799. //
  800. // assert(0);//必须要有异常处理的方案,没有情况直接蹦.
  801. // mLog::FERROR("No Exption Method.");
  802. //
  803. // return NULL;
  804. //}
  805. //INT DiosSMachineIF::EnterSubStateMachine(HANDLE ThreadExitEvt)
  806. //{
  807. // DiosSubSMachine* pSub = (DiosSubSMachine*)m_pCurrentRoutePos;
  808. //
  809. // size_t WaitCount = m_RouteExternalEvtCount + m_pRouteInLineMap->size();
  810. // vector<DiosStMRouteLine*> ExternalWaitEvts;
  811. //
  812. // //merge externalevts + internalevts
  813. // for (DWORD i = 0; i < m_RouteExternalEvtCount; i++)
  814. // {
  815. // ExternalWaitEvts.push_back(m_pRouteExternalMap[i]);
  816. // }
  817. //
  818. // for (DWORD i = 0; i < m_pRouteInLineMap->size(); i++)
  819. // {
  820. // ExternalWaitEvts.push_back((*m_pRouteInLineMap)[i]);
  821. // }
  822. //
  823. // return pSub->ExecStateMachine(ThreadExitEvt, &(ExternalWaitEvts[0]), WaitCount);
  824. //
  825. //}
  826. void DiosSMachineIF::SetDebugMode(bool bEnable)
  827. {
  828. m_bDebugEnable = bEnable;
  829. }
  830. //设置状态断点,IN/ACTION/OUT 三个断点位置可以设置
  831. void DiosSMachineIF::EnableBreakPoint(const char* pState, bool bBreakInEable, bool bActionInEnable, bool bBreakOutEnable)
  832. {
  833. auto it = m_pRoutePosMap->find(pState);
  834. if (it != m_pRoutePosMap->end())
  835. {
  836. DiosStMRoutePos* pPos = it->second;
  837. pPos->SetBreak(bBreakInEable, bActionInEnable, bBreakOutEnable);
  838. }
  839. }
  840. //继续运行,当处于中断状态时
  841. void DiosSMachineIF::Continue()
  842. {
  843. SetEvent(m_hBreaked);
  844. }
  845. //获取状态的所有事件的激活值
  846. void DiosSMachineIF::GetEventStatus(const char* pState, const char* pszEvent)
  847. {
  848. }
  849. //获取当前断点位置
  850. void DiosSMachineIF::GetCurrentBreak()
  851. {
  852. }
  853. //等待继续事件触发
  854. void DiosSMachineIF::WaitContinue()
  855. {
  856. WaitForSingleObject(m_hBreaked, INFINITE);
  857. }
  858. INT DiosSMachineIF::ExecStateMachine(HANDLE ThreadExitEvt/*, DiosStMRouteLine* pExternalWaitEvts[], size_t WaitCount*/)
  859. {
  860. DIOSSTMRET ret = DIOSSMRET_OK;
  861. ClearState();
  862. SetRunningState(true);
  863. //if (pExternalWaitEvts != NULL && WaitCount > 0)
  864. //{
  865. // m_RouteExternalEvtCount = WaitCount;
  866. // m_pRouteExternalMap = &pExternalWaitEvts[0];
  867. //}
  868. //m_pCurrentRoutePos = (*m_pRoutePosMap)[string(DiosStmEntryPosName)];
  869. TransToPos(m_StmEntryPosName.c_str());
  870. //入口Action,执行入口的Action
  871. ret = StateMachineEntry(m_pCurrentRoutePos->GetTimeout());
  872. if (ret != DIOSSMRET_OK)
  873. {
  874. //PostError(DiosFrameError);
  875. mLog::FERROR("StateMachineEntry Failed.");
  876. return -1;
  877. }
  878. do
  879. {
  880. //wait events
  881. DiosStMRouteLine* pRouteLine = StateMachineWaitForEvents(); //m_pCurrentRoutePos->WaitFroNextState(1000); //(RouteWay);
  882. if (pRouteLine == nullptr)
  883. {
  884. //没有事件触发跳转到下一个状态
  885. m_pCurrentRoutePos->CheckTimeout();
  886. //如果需要继续运行,则下一个等待循环
  887. if (WaitForSingleObject(m_RunningState, 1) == WAIT_OBJECT_0)
  888. continue;
  889. mLog::FINFO("StateMachineWaitForEvents got external evt.exit sub state machine.");
  890. TransToPos(m_StmExitPosName.c_str());
  891. //run action without results
  892. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  893. //SetRunningState(false);
  894. return -1;
  895. }
  896. else
  897. {
  898. //this machine
  899. if (pRouteLine->GetActiveState())
  900. {
  901. //Guard
  902. const char* pGuard = pRouteLine->GetGuardName();
  903. if (pGuard != NULL && strlen(pGuard) > 0)
  904. {
  905. ret = StateMachineGuard(pGuard, TIMEOUT_TEMP);
  906. if (ret != DIOSSMRET_OK)
  907. {
  908. continue;
  909. }
  910. }
  911. }
  912. //TransToPos
  913. TransToPos(pRouteLine->GetDesName());
  914. mLog::FINFO("TransToPos:%s", pRouteLine->GetDesName());
  915. if (m_StmExitPosName == m_pCurrentRoutePos->GetName())
  916. {
  917. //exit
  918. //run action without results
  919. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  920. //check ret
  921. if (ret != DIOSSMRET_OK)
  922. {
  923. //PostError(DiosFrameError);
  924. mLog::FERROR("PostError DiosFrameError .curPos:%s", m_pCurrentRoutePos->GetName());
  925. continue;
  926. }
  927. //exit here
  928. SetRunningState(false);
  929. return -1;
  930. }
  931. //statepos or statemachine
  932. if (m_pCurrentRoutePos->GetActiveState())
  933. {
  934. //if (m_pCurrentRoutePos->IsSMachine())
  935. //{
  936. // //copy evt in
  937. // CopyEvtTo((DiosSubSMachine*)m_pCurrentRoutePos);
  938. // //run sub state machine
  939. // INT ExitWay = EnterSubStateMachine(ThreadExitEvt);
  940. // mLog::FINFO("exit from sub sm.%s,ret:%d", m_pCurrentRoutePos->GetName(), ExitWay);
  941. // //copy evt out
  942. // ((DiosSubSMachine*)m_pCurrentRoutePos)->CopyEvtTo(this);
  943. // //trans to position
  944. // if (ExitWay >= 0)
  945. // {
  946. // if ((size_t)ExitWay < m_RouteExternalEvtCount)
  947. // {
  948. // mLog::FINFO("exit from statemachine.%s", m_pCurrentRoutePos->GetName());
  949. // //external evt
  950. // TransToPos(m_StmExitPosName.c_str());
  951. // //run action without results
  952. // ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  953. // //一旦在Exit出错,会再次进入WaitEvt,再执行Exit,.........dead loop
  954. // //if (ret != DIOSSMRET_OK)
  955. // //{
  956. // // continue;
  957. // //}
  958. // SetRunningState(false);
  959. // return ExitWay;
  960. // }
  961. // else
  962. // {
  963. // //local evt
  964. // //trans to pos
  965. // RouteWay = -1;
  966. // pRouteLine = (*m_pRouteInLineMap)[ExitWay - m_RouteExternalEvtCount];
  967. // goto RouteLine_Process;
  968. // }
  969. // }
  970. // else
  971. // {
  972. // //outline .normal exit from statemachine
  973. // mLog::FINFO("exit from sub statemachine");
  974. // }
  975. //}
  976. //else
  977. {
  978. //run action
  979. ret = m_pCurrentRoutePos->DoAction(this);// StateMachineAction(m_pCurrentRoutePos->GetName(), m_pCurrentRoutePos->GetTimeout());
  980. mLog::FINFO("SmAction:%s.RET:%d", m_pCurrentRoutePos->GetName(), ret);
  981. //check ret
  982. if (ret != DIOSSMRET_OK)
  983. {
  984. if (ret == DIOSSMRET_EXIT)
  985. {
  986. //这个函数默认是不会返回EXIT的,除非重写了
  987. //exit thread
  988. //goto exitpos
  989. TransToPos(m_StmExitPosName.c_str());
  990. //run action without results
  991. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  992. SetRunningState(false);
  993. return -1;
  994. }
  995. //执行Action出问题,
  996. //交给状态机的内部逻辑
  997. //PostError(DiosFrameError);
  998. mLog::FERROR("StateMachineAction Exec Action Error .curPos:%s", m_pCurrentRoutePos->GetName());
  999. }
  1000. }
  1001. }
  1002. }
  1003. } while (1);
  1004. SetRunningState(false);
  1005. return -1;
  1006. }
  1007. DiosStMRouteLine* DiosSMachineIF::WaitNotfiyProcess()
  1008. {
  1009. return nullptr;
  1010. }