CcosSMachine.cpp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852
  1. // CcosSMachine.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include "CcosSMachine.h"
  4. #include "common_api.h"
  5. #include <sstream>
  6. using namespace std;
  7. //Log4CPP::Logger* mLog::gLogger = nullptr;
  8. //-----------------------------
  9. CcosStMEvt::CcosStMEvt()
  10. {
  11. m_pEvt = new ResDataObject();
  12. m_pInfo = new ResDataObject();
  13. }
  14. CcosStMEvt::CcosStMEvt(const CcosStMEvt &tValue)
  15. {
  16. m_pEvt = new ResDataObject();
  17. m_pInfo = new ResDataObject();
  18. (*m_pEvt) = (*tValue.m_pEvt);
  19. (*m_pInfo) = (*tValue.m_pInfo);
  20. }
  21. CcosStMEvt::~CcosStMEvt()
  22. {
  23. delete m_pEvt;
  24. m_pEvt = NULL;
  25. delete m_pInfo;
  26. m_pInfo = NULL;
  27. }
  28. bool CcosStMEvt::SetEvt(const char* pKey, int Val, const char *pInfo)
  29. {
  30. m_pEvt->clear();
  31. m_pInfo->clear();
  32. if (pKey)
  33. {
  34. m_pEvt->add(pKey, Val);
  35. m_pInfo->add(pKey, Val);
  36. }
  37. else
  38. {
  39. //m_pEvt->add("", Val);
  40. //m_pInfo->add("", Val);
  41. return true;
  42. }
  43. if (pInfo)
  44. {
  45. m_pInfo->add(CcosStmEvtInfo, pInfo);
  46. }
  47. else
  48. {
  49. m_pInfo->add(CcosStmEvtInfo, "");
  50. }
  51. return true;
  52. }
  53. bool CcosStMEvt::IsEmpty()
  54. {
  55. return (m_pEvt->size() == 0);
  56. }
  57. bool CcosStMEvt::SetEvt(const char* pKey, const char *pVal, const char *pInfo)
  58. {
  59. bool ret = true;
  60. m_pEvt->clear();
  61. m_pInfo->clear();
  62. if (pKey == NULL)
  63. {
  64. return true;
  65. }
  66. if (pVal)
  67. {
  68. ret = m_pEvt->add(pKey, pVal);
  69. m_pInfo->add(pKey, pVal);
  70. }
  71. else
  72. {
  73. ret = m_pEvt->add(pKey, "");
  74. m_pInfo->add(pKey, "");
  75. }
  76. if (pInfo)
  77. {
  78. m_pInfo->add(CcosStmEvtInfo, pInfo);
  79. }
  80. else
  81. {
  82. m_pInfo->add(CcosStmEvtInfo, "");
  83. }
  84. return ret;
  85. }
  86. ResDataObject& CcosStMEvt::GetEvtContext()
  87. {
  88. return (*m_pEvt);
  89. }
  90. CcosStMEvt& CcosStMEvt::operator = (const CcosStMEvt &tValue)
  91. {
  92. if (this != &tValue)
  93. {
  94. (*m_pEvt) = (*tValue.m_pEvt);
  95. (*m_pInfo) = (*tValue.m_pInfo);
  96. }
  97. return (*this);
  98. }
  99. bool CcosStMEvt::operator == (const CcosStMEvt &Obj)
  100. {
  101. return (*m_pEvt == (*(Obj.m_pEvt)));
  102. }
  103. const char *CcosStMEvt::encode()
  104. {
  105. return m_pInfo->encode();
  106. }
  107. bool CcosStMEvt::decode(const char *pdata)
  108. {
  109. ResDataObject Obj;
  110. bool ret = m_pInfo->decode(pdata);
  111. if (ret)
  112. {
  113. size_t size = m_pInfo->size();
  114. if ((size > 0) && (size <= 2))
  115. {
  116. ret = false;
  117. string strStmEvtInfo = CcosStmEvtInfo;
  118. for (size_t i = 0; i < size; i++)
  119. {
  120. const char *pKey = (*m_pInfo).GetKey(i);
  121. if (strStmEvtInfo == pKey)
  122. {
  123. continue;
  124. }
  125. m_pEvt->clear();
  126. m_pEvt->add(pKey, (*m_pInfo)[i]);
  127. ret = true;
  128. }
  129. }
  130. else
  131. {
  132. ret = false;
  133. }
  134. }
  135. if (ret == false)
  136. {
  137. m_pEvt->clear();
  138. m_pInfo->clear();
  139. }
  140. return ret;
  141. }
  142. //-----------------------------
  143. CcosStMRouteLine::CcosStMRouteLine()
  144. {
  145. m_ActiveState = false;
  146. m_InRoute = true;
  147. m_pEvt = new CcosStMEvt();
  148. m_pSrcRoutePos = new string();
  149. m_pGuard = new string();
  150. m_pDesRoutePos = new string();
  151. m_Timeout = TIMEOUT_TEMP;
  152. }
  153. CcosStMRouteLine::CcosStMRouteLine(const CcosStMRouteLine &tValue)
  154. {
  155. m_ActiveState = false;
  156. m_InRoute = true;
  157. m_pEvt = new CcosStMEvt();
  158. m_pSrcRoutePos = new string();
  159. m_pGuard = new string();
  160. m_pDesRoutePos = new string();
  161. m_Timeout = TIMEOUT_TEMP;
  162. if (tValue.m_InRoute)
  163. {
  164. SetRoute(*(tValue.m_pEvt), tValue.m_pSrcRoutePos->c_str(), tValue.m_pGuard->c_str(), tValue.m_pDesRoutePos->c_str());
  165. }
  166. else
  167. {
  168. SetRoute(*(tValue.m_pEvt), tValue.m_pGuard->c_str(), tValue.m_pDesRoutePos->c_str());
  169. }
  170. }
  171. CcosStMRouteLine::~CcosStMRouteLine()
  172. {
  173. delete m_pEvt;
  174. delete m_pSrcRoutePos;
  175. delete m_pDesRoutePos;
  176. delete m_pGuard;
  177. }
  178. void CcosStMRouteLine::SetRoute(CcosStMEvt &evt, const char* pGuard, const char* pDes)
  179. {
  180. m_InRoute = true;
  181. (*m_pSrcRoutePos) = "";
  182. (*m_pEvt) = evt;
  183. if (pGuard)
  184. {
  185. (*m_pGuard) = pGuard;
  186. }
  187. else
  188. {
  189. (*m_pGuard) = "";
  190. }
  191. if (pDes)
  192. {
  193. (*m_pDesRoutePos) = pDes;
  194. }
  195. else
  196. {
  197. (*m_pDesRoutePos) = "";
  198. }
  199. }
  200. void CcosStMRouteLine::SetRoute(CcosStMEvt &evt, const char* pSrc, const char* pGuard, const char* pDes)
  201. {
  202. m_InRoute = false;
  203. (*m_pEvt) = evt;
  204. if (pSrc)
  205. {
  206. (*m_pSrcRoutePos) = pSrc;
  207. }
  208. else
  209. {
  210. (*m_pSrcRoutePos) = "";
  211. }
  212. if (pGuard)
  213. {
  214. (*m_pGuard) = pGuard;
  215. }
  216. else
  217. {
  218. (*m_pGuard) = "";
  219. }
  220. if (pDes)
  221. {
  222. (*m_pDesRoutePos) = pDes;
  223. }
  224. else
  225. {
  226. (*m_pDesRoutePos) = "";
  227. }
  228. }
  229. const char* CcosStMRouteLine::GetDesName()
  230. {
  231. return m_pDesRoutePos->c_str();
  232. }
  233. const char* CcosStMRouteLine::GetSrcName()
  234. {
  235. if (m_InRoute == false)
  236. {
  237. return m_pSrcRoutePos->c_str();
  238. }
  239. return NULL;
  240. }
  241. const char* CcosStMRouteLine::GetGuardName()
  242. {
  243. return m_pGuard->c_str();
  244. }
  245. //true:in,false:out
  246. bool CcosStMRouteLine::GetRouteType()
  247. {
  248. return m_InRoute;
  249. }
  250. CcosStMRouteLine::operator CcosStMEvt *()
  251. {
  252. return m_pEvt;
  253. }
  254. CcosStMRouteLine& CcosStMRouteLine::operator = (const CcosStMRouteLine &tValue)
  255. {
  256. if (&tValue != this)
  257. {
  258. if (tValue.m_InRoute)
  259. {
  260. SetRoute(*(tValue.m_pEvt), tValue.m_pSrcRoutePos->c_str(), tValue.m_pGuard->c_str(), tValue.m_pDesRoutePos->c_str());
  261. }
  262. else
  263. {
  264. SetRoute(*(tValue.m_pEvt), tValue.m_pGuard->c_str(), tValue.m_pDesRoutePos->c_str());
  265. }
  266. }
  267. return (*this);
  268. }
  269. void CcosStMRouteLine::Active(bool state, DWORD timeout)
  270. {
  271. m_ActiveState = state;
  272. if (m_ActiveState == false)
  273. {
  274. m_Timeout = timeout;
  275. }
  276. else
  277. {
  278. //get maximum timeperiod
  279. if (timeout > m_Timeout)
  280. {
  281. m_Timeout = timeout;
  282. }
  283. }
  284. }
  285. bool CcosStMRouteLine::GetActiveState()
  286. {
  287. return m_ActiveState;
  288. }
  289. DWORD CcosStMRouteLine::GetTimeout()
  290. {
  291. return m_Timeout;
  292. }
  293. //================================
  294. CcosStMRoutePos::CcosStMRoutePos()
  295. {
  296. m_ActiveState = false;
  297. m_pRoutePosName = new string();
  298. m_pOutRouteLineVec = new vector<CcosStMRouteLine *>();
  299. m_Timeout = TIMEOUT_TEMP;
  300. }
  301. CcosStMRoutePos::CcosStMRoutePos(const char *pName)
  302. {
  303. m_ActiveState = false;
  304. m_pRoutePosName = new string();
  305. (*m_pRoutePosName) = pName;
  306. m_pOutRouteLineVec = new vector<CcosStMRouteLine *>();
  307. m_Timeout = TIMEOUT_TEMP;
  308. }
  309. CcosStMRoutePos::~CcosStMRoutePos()
  310. {
  311. delete m_pRoutePosName;
  312. m_pRoutePosName = NULL;
  313. if (m_pOutRouteLineVec != NULL)
  314. {
  315. if (m_pOutRouteLineVec->size() > 0)
  316. {
  317. for (size_t i = 0; i < m_pOutRouteLineVec->size(); i++)
  318. {
  319. CcosStMRouteLine *p = (*m_pOutRouteLineVec)[i];
  320. delete p;
  321. }
  322. }
  323. delete m_pOutRouteLineVec;
  324. m_pOutRouteLineVec = NULL;
  325. }
  326. }
  327. void CcosStMRoutePos::Active(bool state,DWORD timeout)
  328. {
  329. m_ActiveState = state;
  330. if (m_ActiveState == false)
  331. {
  332. m_Timeout = timeout;
  333. }
  334. else
  335. {
  336. //get maximum timeperiod
  337. if (timeout > m_Timeout)
  338. {
  339. m_Timeout = timeout;
  340. }
  341. }
  342. }
  343. bool CcosStMRoutePos::GetActiveState()
  344. {
  345. return m_ActiveState;
  346. }
  347. bool CcosStMRoutePos::IsSMachine()
  348. {
  349. return false;
  350. }
  351. bool CcosStMRoutePos::PosAddOutRouteLine(CcosStMEvt &Evt, const char *pSrcPosName, const char *pGuardName, const char *pDesPosName)
  352. {
  353. CcosStMRouteLine *pLine = new CcosStMRouteLine();
  354. pLine->SetRoute(Evt, pSrcPosName, pGuardName, pDesPosName);
  355. m_pOutRouteLineVec->push_back(pLine);
  356. return true;
  357. }
  358. void CcosStMRoutePos::SetName(const char *pName)
  359. {
  360. (*m_pRoutePosName) = pName;
  361. }
  362. const char* CcosStMRoutePos::GetName()
  363. {
  364. return m_pRoutePosName->c_str();
  365. }
  366. DWORD CcosStMRoutePos::GetRouteLineCount()
  367. {
  368. if (m_pOutRouteLineVec)
  369. {
  370. return (DWORD)m_pOutRouteLineVec->size();
  371. }
  372. return 0;
  373. }
  374. CcosStMRouteLine **CcosStMRoutePos::GetOutRouteLineVec()
  375. {
  376. if (m_pOutRouteLineVec)
  377. {
  378. if (m_pOutRouteLineVec->size() > 0)
  379. {
  380. return &((*m_pOutRouteLineVec)[0]);
  381. }
  382. }
  383. return NULL;
  384. }
  385. CcosStMRouteLine *CcosStMRoutePos::operator [](CcosStMEvt &Evt)
  386. {
  387. if (m_pOutRouteLineVec)
  388. {
  389. if (m_pOutRouteLineVec->size() > 0)
  390. {
  391. for (size_t i = 0; i < m_pOutRouteLineVec->size(); i++)
  392. {
  393. if ((*(CcosStMEvt *)(*(*m_pOutRouteLineVec)[i])) == Evt)
  394. {
  395. return (*m_pOutRouteLineVec)[i];
  396. }
  397. }
  398. }
  399. }
  400. return NULL;
  401. }
  402. DWORD CcosStMRoutePos::GetTimeout()
  403. {
  404. return m_Timeout;
  405. }
  406. //================================
  407. CcosSMachineIF::CcosSMachineIF()
  408. {
  409. m_pStateMachineName = new string();
  410. m_pParent = 0;
  411. m_pCurrentRoutePos = NULL;
  412. //evt list
  413. m_pArrivedEvts = new MsgCircle<CcosStMEvt>();
  414. //routepos
  415. m_pRoutePosMap = new map<string, CcosStMRoutePos*>();
  416. CcosStMRoutePos *p = NULL;
  417. p = new CcosStMRoutePos(CcosStmEntryPosName);
  418. p->Active(true, TIMEOUT_TEMP);
  419. (*m_pRoutePosMap)[CcosStmEntryPosName] = p;
  420. //printf(" == this[% 08X] Add Route Pos [%s] \n", this, CcosStmEntryPosName);
  421. p = new CcosStMRoutePos(CcosStmExitPosName);
  422. p->Active(true, TIMEOUT_TEMP);
  423. (*m_pRoutePosMap)[CcosStmExitPosName] = p;
  424. //inline
  425. m_pRouteInLineMap = new vector<CcosStMRouteLine*>();
  426. //external
  427. m_RouteExternalEvtCount = 0;
  428. m_pRouteExternalMap = NULL;
  429. //running state
  430. m_RunningState = LinuxEvent::CreateEvent(LinuxEvent::MANUAL_RESET,false);
  431. m_StateCangeEvt = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, false);
  432. }
  433. CcosSMachineIF::~CcosSMachineIF()
  434. {
  435. delete m_pStateMachineName;
  436. m_pStateMachineName = 0;
  437. //cp
  438. m_pCurrentRoutePos = NULL;
  439. //external
  440. m_RouteExternalEvtCount = 0;
  441. m_pRouteExternalMap = NULL;
  442. //clear inline path
  443. for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  444. {
  445. delete (*m_pRouteInLineMap)[i];
  446. }
  447. delete m_pRouteInLineMap;
  448. m_pRouteInLineMap = NULL;
  449. //clear routepos
  450. map<string, CcosStMRoutePos*>::iterator iter = m_pRoutePosMap->begin();
  451. while (iter != m_pRoutePosMap->end())
  452. {
  453. if (iter->second->IsSMachine())
  454. {
  455. CcosSubSMachine* pSub = (CcosSubSMachine*)iter->second;
  456. delete pSub;
  457. }
  458. else
  459. {
  460. delete iter->second;
  461. }
  462. ++iter;
  463. }
  464. delete m_pRoutePosMap;
  465. m_pRoutePosMap = NULL;
  466. //evt list
  467. delete m_pArrivedEvts;
  468. m_pArrivedEvts = NULL;
  469. return;
  470. }
  471. void CcosSMachineIF::SetStateMachineName(const char *pszName)
  472. {
  473. (*m_pStateMachineName) = pszName;
  474. }
  475. const char *CcosSMachineIF::GetStateMachineName()
  476. {
  477. return m_pStateMachineName->c_str();
  478. }
  479. void CcosSMachineIF::SetParentSMachine(CcosSMachineIF *pParent)
  480. {
  481. m_pParent = pParent;
  482. }
  483. void CcosSMachineIF::PushStateChange(ResDataObject &ChangedPos)
  484. {
  485. if (m_pParent)
  486. {
  487. m_pParent->PushStateChange(ChangedPos);
  488. }
  489. }
  490. bool CcosSMachineIF::IsSMachine()
  491. {
  492. return true;
  493. }
  494. std::shared_ptr<LinuxEvent> CcosSMachineIF::GetStateChangeEvtHandle()
  495. {
  496. return m_StateCangeEvt;
  497. }
  498. void CcosSMachineIF::SetRunningState(bool Running)
  499. {
  500. Thread_Lock();
  501. if (Running)
  502. {
  503. m_RunningState->SetEvent();
  504. }
  505. else
  506. {
  507. m_RunningState->ResetEvent();
  508. }
  509. Thread_UnLock();
  510. }
  511. bool CcosSMachineIF::GetRunningState(DWORD waittime)
  512. {
  513. bool ret = (m_RunningState-> Wait(waittime));
  514. if (ret == false)
  515. {
  516. //printf("GetRunningState Failed.WTF??\n");
  517. }
  518. return ret;
  519. }
  520. //init state machine
  521. //第一个节点的接入比较特殊,所以做了个函数
  522. bool CcosSMachineIF::AddEntryRoutePos(CcosStMRoutePos *pPos)
  523. {
  524. if (strlen(pPos->GetName()) == 0)
  525. {
  526. return false;
  527. }
  528. if ((*m_pRoutePosMap)[CcosStmEntryPosName]->GetRouteLineCount() > 0)
  529. {
  530. return false;
  531. }
  532. //add pos
  533. (*m_pRoutePosMap)[pPos->GetName()] = pPos;
  534. CcosStMEvt evt;
  535. //make a line
  536. (*m_pRoutePosMap)[CcosStmEntryPosName]->PosAddOutRouteLine(evt, CcosStmEntryPosName, NULL, pPos->GetName());
  537. return true;
  538. }
  539. bool CcosSMachineIF::AddRoutePos(CcosStMRoutePos *pPos)
  540. {
  541. if (strlen(pPos->GetName()) == 0)
  542. {
  543. return false;
  544. }
  545. //add pos
  546. //printf("=== this [%08X] Add RoutePos [%s] \n",this, pPos->GetName());
  547. if (string(pPos->GetName()) == "FrameStart")
  548. {
  549. //printf("stop");
  550. }
  551. (*m_pRoutePosMap)[pPos->GetName()] = pPos;
  552. return true;
  553. }
  554. bool CcosSMachineIF::AddInRouteLine(CcosStMEvt &Evt, const char *pGuardName, const char *pDesPosName)
  555. {
  556. CcosStMRouteLine *pLine = new CcosStMRouteLine();
  557. pLine->SetRoute(Evt, pGuardName, pDesPosName);
  558. pLine->Active(true, 0);//timeout没必要,因为是全局事件
  559. m_pRouteInLineMap->push_back(pLine);
  560. return true;
  561. }
  562. bool CcosSMachineIF::AddOutRouteLine(CcosStMEvt &Evt, const char *pSrcPosName, const char *pGuardName, const char *pDesPosName)
  563. {
  564. bool ret = true;
  565. try{
  566. auto route = (*m_pRoutePosMap)[pSrcPosName];
  567. auto itf = m_pRoutePosMap->find(pSrcPosName);
  568. if (itf != m_pRoutePosMap->end())
  569. {
  570. //printf("\n Got it %s \n", pSrcPosName);
  571. }
  572. else
  573. {
  574. //printf("\n Route Pos %s has not set....\n", pSrcPosName);
  575. }
  576. ret = route->PosAddOutRouteLine(Evt, pSrcPosName, pGuardName, pDesPosName);
  577. }
  578. catch (...)
  579. {
  580. ret = false;
  581. }
  582. return ret;
  583. }
  584. //active state machine
  585. bool CcosSMachineIF::ActiveRoutePos(const char *pPosName, DWORD timeout)
  586. {
  587. bool ret = true;
  588. try{
  589. map<string, CcosStMRoutePos*>::iterator iterOut = m_pRoutePosMap->find(pPosName);
  590. if (iterOut != m_pRoutePosMap->end())
  591. {
  592. (*m_pRoutePosMap)[pPosName]->Active(true, timeout);
  593. }
  594. //find sub route machine
  595. iterOut = (*m_pRoutePosMap).begin();
  596. while (iterOut != (*m_pRoutePosMap).end())
  597. {
  598. if (iterOut->second->IsSMachine() == true)
  599. {
  600. CcosSubSMachine *pSub = (CcosSubSMachine *)(iterOut->second);
  601. pSub->ActiveRoutePos(pPosName, timeout);
  602. }
  603. ++iterOut;
  604. }
  605. }
  606. catch (...)
  607. {
  608. ret = false;
  609. }
  610. return ret;
  611. }
  612. //bool CcosSMachineIF::ActiveInRouteLine(CcosStMEvt &Evt, DWORD timeout)
  613. //{
  614. // bool ret = false;
  615. // try{
  616. // //find In Route Line
  617. // for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  618. // {
  619. // if ((*(CcosStMEvt*)(*(*m_pRouteInLineMap)[i])) == Evt)
  620. // {
  621. // (*m_pRouteInLineMap)[i]->Active(true,timeout);
  622. //
  623. // ret = true;
  624. //
  625. // break;
  626. // }
  627. // }
  628. //
  629. // }
  630. // catch (...)
  631. // {
  632. // ret = false;
  633. // }
  634. //
  635. // return ret;
  636. //
  637. //}
  638. bool CcosSMachineIF::ActiveRouteLine(CcosStMEvt &Evt, DWORD timeout)
  639. {
  640. bool ret = true;
  641. try{
  642. //out path
  643. map<string, CcosStMRoutePos*>::iterator iterOut = (*m_pRoutePosMap).begin();
  644. while (iterOut != (*m_pRoutePosMap).end())
  645. {
  646. if (iterOut->second->IsSMachine() == false)
  647. {
  648. DWORD RouteCount = iterOut->second->GetRouteLineCount();
  649. CcosStMRouteLine **RouteLines = iterOut->second->GetOutRouteLineVec();
  650. for (DWORD i = 0; i < RouteCount; i++)
  651. {
  652. if ((*(CcosStMEvt *)(*(RouteLines[i]))) == Evt)
  653. {
  654. RouteLines[i]->Active(true, timeout);
  655. }
  656. }
  657. }
  658. else
  659. {
  660. //子对象自行激活自己
  661. //CcosSubSMachine *pSub = (CcosSubSMachine *)(iterOut->second);
  662. //pSub->ActiveRouteLine(Evt, timeout);
  663. }
  664. ++iterOut;
  665. }
  666. //in path
  667. for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  668. {
  669. if ((*(CcosStMEvt *)(*((*m_pRouteInLineMap)[i]))) == Evt)
  670. {
  671. (*m_pRouteInLineMap)[i]->Active(true, timeout);
  672. }
  673. }
  674. //CcosStMRouteLine* pLine = (*(*m_pRoutePosMap)[pPosName])[Evt];
  675. //if (pLine)
  676. //{
  677. // pLine->Active(true, timeout);
  678. // ret = true;
  679. //}
  680. }
  681. catch (...)
  682. {
  683. ret = false;
  684. }
  685. return ret;
  686. }
  687. bool CcosSMachineIF::DeActiveAll()
  688. {
  689. bool ret = true;
  690. try{
  691. //out path
  692. map<string, CcosStMRoutePos*>::iterator iterOut = (*m_pRoutePosMap).begin();
  693. while (iterOut != (*m_pRoutePosMap).end())
  694. {
  695. if (iterOut->second->IsSMachine() == false)
  696. {
  697. //deactive pos
  698. iterOut->second->Active(false, 0);
  699. //deactive line
  700. DWORD RouteCount = iterOut->second->GetRouteLineCount();
  701. CcosStMRouteLine **RouteLines = iterOut->second->GetOutRouteLineVec();
  702. for (DWORD i = 0; i < RouteCount; i++)
  703. {
  704. RouteLines[i]->Active(false, 0);
  705. }
  706. }
  707. else
  708. {
  709. CcosSubSMachine *pSub = (CcosSubSMachine *)(iterOut->second);
  710. pSub->DeActiveAll();
  711. }
  712. ++iterOut;
  713. }
  714. //in path
  715. for (size_t i = 0; i < m_pRouteInLineMap->size(); i++)
  716. {
  717. (*m_pRouteInLineMap)[i]->Active(false, 0);
  718. }
  719. }
  720. catch (...)
  721. {
  722. ret = false;
  723. }
  724. return ret;
  725. }
  726. void CcosSMachineIF::ClearState(bool bClearEvent)
  727. {
  728. Thread_Lock();
  729. SetRunningState(false);
  730. map<string, CcosStMRoutePos*>::iterator iterOut = (*m_pRoutePosMap).begin();
  731. while (iterOut != (*m_pRoutePosMap).end())
  732. {
  733. if (iterOut->second->IsSMachine())
  734. {
  735. CcosSubSMachine *pSub = (CcosSubSMachine *)(iterOut->second);
  736. pSub->ClearState(bClearEvent);
  737. }
  738. ++iterOut;
  739. }
  740. m_pCurrentRoutePos = NULL;
  741. if(bClearEvent)
  742. m_pArrivedEvts->Clear();
  743. m_RouteExternalEvtCount = 0;
  744. m_pRouteExternalMap = NULL;
  745. Thread_UnLock();
  746. }
  747. std::shared_ptr<LinuxEvent> CcosSMachineIF::GetEvtNotifyHandle()
  748. {
  749. return (*m_pArrivedEvts).GetNotifyHandle();
  750. }
  751. bool CcosSMachineIF::PeekEvent(CcosStMEvt &Evt)
  752. {
  753. //check it's existance
  754. return (*m_pArrivedEvts).Peek(Evt);
  755. }
  756. //evt
  757. bool CcosSMachineIF::PopEvent(CcosStMEvt &Evt)
  758. {
  759. return (*m_pArrivedEvts).DeQueue(Evt);
  760. }
  761. bool CcosSMachineIF::PushEvent(CcosStMEvt &Evt)
  762. {
  763. bool ret = false;
  764. Thread_Lock();
  765. ResDataObject& EvtContext = Evt.GetEvtContext();
  766. //mLog::FINFO("Push Key[{$}]:Val[{$}]", EvtContext.GetKey(0), (const char*)EvtContext[0]);
  767. if (m_pCurrentRoutePos)
  768. {
  769. if (m_pCurrentRoutePos->IsSMachine())
  770. {
  771. CcosSubSMachine* pMachine = (CcosSubSMachine*)m_pCurrentRoutePos;
  772. pMachine->Thread_Lock();
  773. if (pMachine->GetRunningState() == true)
  774. {
  775. //mLog::FINFO("Enter SubStateMachine ");
  776. ret = pMachine->PushEvent(Evt);
  777. pMachine->Thread_UnLock();
  778. Thread_UnLock();
  779. return ret;
  780. }
  781. pMachine->Thread_UnLock();
  782. }
  783. }
  784. Thread_UnLock();
  785. //check it's existance
  786. (*m_pArrivedEvts).Lock();
  787. DWORD size = (*m_pArrivedEvts).size();
  788. for (DWORD i = 0; i < size; i++)
  789. {
  790. if ((*m_pArrivedEvts)[i] == Evt)
  791. {
  792. (*m_pArrivedEvts).UnLock();
  793. return ret;
  794. }
  795. }
  796. ret = true;
  797. //mLog::FINFO("m_pArrivedEvts InQueue This Event");
  798. (*m_pArrivedEvts).InQueue(Evt);
  799. (*m_pArrivedEvts).UnLock();
  800. return true;
  801. }
  802. //for state machine thread
  803. CCOSSTMRET CcosSMachineIF::StateMachineEntry(DWORD timeout)
  804. {
  805. return CCOSSMRET_OK;
  806. }
  807. CCOSSTMRET CcosSMachineIF::StateMachineExit(DWORD timeout)
  808. {
  809. return CCOSSMRET_OK;
  810. }
  811. CCOSSTMRET CcosSMachineIF::StateMachineAction(const char *pAction, DWORD timeout)
  812. {
  813. return CCOSSMRET_OK;
  814. }
  815. CCOSSTMRET CcosSMachineIF::StateMachineGuard(const char *pGuard, DWORD timeout)
  816. {
  817. return CCOSSMRET_OK;
  818. }
  819. /// <summary>
  820. /// 实际的状态机等待事件
  821. /// </summary>
  822. /// <param name="pLocalEvts"></param>
  823. /// <param name="CountOfLocal"></param>
  824. /// <param name="pExternalEvts"></param>
  825. /// <param name="CountOfExternal"></param>
  826. /// <param name="pOutpathEvts"></param>
  827. /// <param name="CountOfOutpath"></param>
  828. /// <param name="timeout"></param>
  829. /// <param name="Evt"></param>
  830. /// <returns>
  831. /// 返回值为负:退出状态机;返回值为等到的 事件的下标
  832. /// </returns>
  833. int CcosSMachineIF::StateMachineWaitForEvents(
  834. CcosStMRouteLine *pLocalEvts[], DWORD CountOfLocal,
  835. CcosStMRouteLine *pExternalEvts[], DWORD CountOfExternal,
  836. CcosStMRouteLine *pOutpathEvts[], DWORD CountOfOutpath,
  837. DWORD timeout, CcosStMEvt& Evt
  838. )
  839. {
  840. //执行最基础的处理
  841. return -1;
  842. }
  843. CcosStMRoutePos *CcosSMachineIF::GetCurrentRoutePos()
  844. {
  845. return m_pCurrentRoutePos;
  846. }
  847. CCOSSTMRET CcosSMachineIF::TransToPos(const char *pPosName)
  848. {
  849. CCOSSTMRET ret = CCOSSMRET_OK;
  850. //des check
  851. try{
  852. Thread_Lock();
  853. m_pCurrentRoutePos = (*m_pRoutePosMap)[string(pPosName)];
  854. Thread_UnLock();
  855. m_StateCangeEvt->SetEvent();
  856. //printf("Trans To %s \n", pPosName);
  857. }
  858. catch (...)
  859. {
  860. assert(0);//never gonna reach
  861. ret = CCOSSMRET_NG;
  862. }
  863. return ret;
  864. }
  865. void CcosSMachineIF::PostError(const char *pErrorVal, const char *pErrorInfo)
  866. {
  867. CcosStMEvt evt;
  868. if (pErrorVal)
  869. {
  870. //printf("--PostError:%s--\n", pErrorVal);
  871. }
  872. else
  873. {
  874. //printf("--PostError:Empty--\n");
  875. }
  876. evt.SetEvt(CcosErrorType, pErrorVal,pErrorInfo);
  877. PushEvent(evt);
  878. }
  879. CcosStMRouteLine *CcosSMachineIF::GetEntryRouteLine()
  880. {
  881. //routepos
  882. CcosStMRoutePos *pFirst = (*m_pRoutePosMap)[string(CcosStmEntryPosName)];
  883. if (pFirst)
  884. {
  885. if (pFirst->GetRouteLineCount() == 1)
  886. {
  887. return ((m_pCurrentRoutePos->GetOutRouteLineVec())[0]);
  888. }
  889. }
  890. return NULL;
  891. }
  892. void CcosSMachineIF::CopyEvtTo(CcosSMachineIF *pDes)
  893. {
  894. //排序上先ORG的消息,然后des的消息
  895. bool ret = true;
  896. CcosStMEvt Evt;
  897. //mLog::FINFO("Begin from {$} To {$}", GetStateMachineName(), pDes->GetStateMachineName());
  898. //copy des to org
  899. while (ret)
  900. {
  901. ret = pDes->PopEvent(Evt);
  902. if (ret)
  903. {
  904. PushEvent(Evt);
  905. }
  906. }
  907. //org -> des
  908. ret = true;
  909. while (ret)
  910. {
  911. ret = PopEvent(Evt);
  912. if (ret)
  913. {
  914. pDes->PushEvent(Evt);
  915. }
  916. }
  917. //mLog::FINFO("End with {$}", GetStateMachineName());
  918. }
  919. //检查:路径,状态点,以及它们的ActiveState
  920. bool CcosSMachineIF::PrePareStateMachine()
  921. {
  922. //状态点的检查
  923. map<string, CcosStMRoutePos*>::iterator iter = m_pRoutePosMap->begin();
  924. while (iter != m_pRoutePosMap->end())
  925. {
  926. if (iter->second->IsSMachine())
  927. {
  928. //sub machine
  929. CcosSubSMachine* pSub = static_cast<CcosSubSMachine*>(iter->second);
  930. if (pSub->PrePareStateMachine() == false)
  931. {
  932. ostringstream buf;
  933. buf << "Sub StateMachine Error.Name:" << (iter->second)->GetName();
  934. PostError(CcosFrameError,buf.str().c_str());
  935. //mLog::FERROR("Post FrameError.{$}",buf.str().c_str());
  936. return false;//submachine err
  937. }
  938. }
  939. else
  940. {
  941. //route pos
  942. bool RouteLineActived = false;
  943. //OutRouteLine的检查
  944. DWORD VecCount = iter->second->GetRouteLineCount();
  945. CcosStMRouteLine **pVec = iter->second->GetOutRouteLineVec();
  946. for (DWORD i = 0; i < VecCount; i++)
  947. {
  948. //Activestate
  949. RouteLineActived |= pVec[i]->GetActiveState();
  950. //Des的有效性
  951. const char *pDes = pVec[i]->GetDesName();
  952. map<string, CcosStMRoutePos*>::iterator desok = m_pRoutePosMap->find(string(pDes));
  953. if (desok == m_pRoutePosMap->end())
  954. {
  955. //no des
  956. //ostringstream buf;
  957. string buf;
  958. buf = "No Destination of RouteLine.RouteName:" + string(iter->second->GetName()) + "DesName:" + string(pDes);
  959. PostError(CcosFrameError, buf.c_str());
  960. //mLog::FERROR("Post FrameError.{$}", buf.c_str());
  961. return false;
  962. }
  963. }
  964. //多个路径情况下,是否有一个Active
  965. if (VecCount > 1)
  966. {
  967. if (RouteLineActived == false)
  968. {
  969. string buf;
  970. buf = "No Specific Route Actived in Multiple OutRouteLines.RouteName:" + string(iter->second->GetName());
  971. PostError(CcosFrameError, buf.c_str());
  972. //mLog::FERROR("Post FrameError.{$}", buf.c_str());
  973. return false;
  974. }
  975. }
  976. }
  977. ++iter;
  978. }
  979. //InRouteLine的检查
  980. for (DWORD i = 0; i < m_pRouteInLineMap->size(); i++)
  981. {
  982. //Des的有效性
  983. const char *pDes = (*m_pRouteInLineMap)[i]->GetDesName();
  984. map<string, CcosStMRoutePos*>::iterator desok = m_pRoutePosMap->find(string(pDes));
  985. if (desok == m_pRoutePosMap->end())
  986. {
  987. //no des
  988. string buf;
  989. buf = "No Destination of InRouteLine.DesName:" + string(pDes);
  990. PostError(CcosFrameError, buf.c_str());
  991. //mLog::FERROR("Post FrameError.{$}", buf.c_str());
  992. return false;
  993. }
  994. }
  995. //第一个RouteLine
  996. // 允许有多个
  997. //DWORD firstRTLCount = (*m_pRoutePosMap)[CcosStmEntryPosName]->GetRouteLineCount();
  998. //if (firstRTLCount == 0 || firstRTLCount > 1)
  999. //{
  1000. // string buf;
  1001. // buf = "No First RouteLine or Multiple Routeline";
  1002. // PostError(CcosFrameError, buf.c_str());
  1003. // //mLog::FERROR("Post FrameError.{$}", buf.c_str());
  1004. // return false;
  1005. //}
  1006. //无法检查全局ERROR事件的状态点
  1007. return true;
  1008. }
  1009. DWORD CalcMaximumTimeout(CcosStMRouteLine **pVec,DWORD Count)
  1010. {
  1011. DWORD timeout = 0;
  1012. if (pVec != NULL && Count > 0)
  1013. {
  1014. for (DWORD i = 0; i < Count; i++)
  1015. {
  1016. if (pVec[i]->GetActiveState())
  1017. {
  1018. if (pVec[i]->GetTimeout() > timeout)
  1019. {
  1020. timeout = pVec[i]->GetTimeout();
  1021. }
  1022. }
  1023. }
  1024. }
  1025. return timeout;
  1026. }
  1027. /// <summary>
  1028. /// 状态机顶层等待事件
  1029. /// </summary>
  1030. /// <param name="ExtEvtIndex"></param>
  1031. /// <param name="Evt"></param>
  1032. /// <returns>实际的状态机 跳转到的状态</returns>
  1033. CcosStMRouteLine* CcosSMachineIF::StateMachineWaitForEvents(int &ExtEvtIndex, CcosStMEvt& Evt)
  1034. {
  1035. ExtEvtIndex = -1;
  1036. //mLog::FINFO("Begin with {$}", GetStateMachineName());
  1037. //after state action,do notify hit a state pos.
  1038. CcosStMRoutePos *pCurPos = GetCurrentRoutePos();
  1039. if (pCurPos)
  1040. {
  1041. ResDataObject StatePos;
  1042. StatePos.add(GetStateMachineName(), pCurPos->GetName());
  1043. PushStateChange(StatePos);
  1044. //mLog::FINFO("PushStateChange {$} with {$}", pCurPos->GetName(), GetStateMachineName());
  1045. }
  1046. CcosStMRouteLine **pLocal = NULL;
  1047. DWORD LocalCount = (DWORD)m_pRouteInLineMap->size();
  1048. if (LocalCount > 0)
  1049. {
  1050. pLocal = &((*m_pRouteInLineMap)[0]);
  1051. }
  1052. DWORD OutLineCount = m_pCurrentRoutePos->GetRouteLineCount();
  1053. CcosStMRouteLine **pOutline = m_pCurrentRoutePos->GetOutRouteLineVec();
  1054. DWORD MaxTimeout = CalcMaximumTimeout(pLocal, LocalCount);//local
  1055. DWORD timeout = CalcMaximumTimeout(pOutline, OutLineCount);//outline
  1056. if (timeout > MaxTimeout)
  1057. {
  1058. MaxTimeout = timeout;
  1059. }
  1060. timeout = CalcMaximumTimeout(m_pRouteExternalMap, (DWORD)m_RouteExternalEvtCount);//external
  1061. if (timeout > MaxTimeout)
  1062. {
  1063. MaxTimeout = timeout;
  1064. }
  1065. //mLog::FINFO("Wait for Events LocalCount={$} OutLineCount={$} MaxTimeout={$} m_RouteExternalEvtCount={$}",
  1066. //LocalCount, OutLineCount, MaxTimeout, m_RouteExternalEvtCount);
  1067. for (int i = 0; i < 2; i++)
  1068. {
  1069. int ret = 0;
  1070. ret = StateMachineWaitForEvents(
  1071. pLocal, LocalCount,
  1072. m_pRouteExternalMap, (DWORD)m_RouteExternalEvtCount,
  1073. pOutline, OutLineCount,
  1074. MaxTimeout, Evt);
  1075. //mLog::FINFO("StateMachine {$} WaitForEvents Return={$}", GetStateMachineName(), ret);
  1076. if (ret >= 0)
  1077. {
  1078. if ((DWORD)ret < LocalCount)
  1079. {
  1080. //local
  1081. return pLocal[ret];
  1082. }
  1083. else if ((DWORD)ret < LocalCount + m_RouteExternalEvtCount)
  1084. {
  1085. //external
  1086. ExtEvtIndex = ret - LocalCount;
  1087. return NULL;
  1088. }
  1089. //outline
  1090. ret -= (LocalCount + (DWORD)m_RouteExternalEvtCount);
  1091. return pOutline[ret];
  1092. }
  1093. else if (ret == -1)
  1094. {
  1095. PostError(CcosFrameError);
  1096. //mLog::FERROR("Timeout .Post FrameError.");
  1097. }
  1098. else if (ret == -2)
  1099. {
  1100. PostError(CcosFrameError);
  1101. //mLog::FERROR("Device Error .Post FrameError.");
  1102. }
  1103. else if (ret == -3)
  1104. {
  1105. ExtEvtIndex = -2;//thread exit
  1106. return NULL;
  1107. }
  1108. }
  1109. assert(0);//必须要有异常处理的方案,没有情况直接蹦.
  1110. //mLog::FERROR("No Exption Method.");
  1111. return NULL;
  1112. }
  1113. int CcosSMachineIF::EnterSubStateMachine(std::shared_ptr<LinuxEvent> ThreadExitEvt, CcosStMEvt& Evt)
  1114. {
  1115. CcosSubSMachine* pSub = (CcosSubSMachine*)m_pCurrentRoutePos;
  1116. size_t WaitCount = m_RouteExternalEvtCount + m_pRouteInLineMap->size();
  1117. vector<CcosStMRouteLine *> ExternalWaitEvts;
  1118. //merge externalevts + internalevts
  1119. for (DWORD i = 0; i < m_RouteExternalEvtCount; i++)
  1120. {
  1121. ExternalWaitEvts.push_back(m_pRouteExternalMap[i]);
  1122. }
  1123. for (DWORD i = 0; i < m_pRouteInLineMap->size(); i++)
  1124. {
  1125. ExternalWaitEvts.push_back((*m_pRouteInLineMap)[i]);
  1126. }
  1127. pSub->PushEvent(Evt);
  1128. return pSub->ExecStateMachine(ThreadExitEvt,&(ExternalWaitEvts[0]), WaitCount, false);
  1129. }
  1130. /// <summary>
  1131. /// 状态机主体执行函数,也可以是子状态机
  1132. /// </summary>
  1133. /// <param name="ThreadExitEvt"></param>
  1134. /// <param name="pExternalWaitEvts"></param>
  1135. /// <param name="WaitCount"></param>
  1136. /// <param name="bClear"></param>
  1137. /// <returns></returns>
  1138. int CcosSMachineIF::ExecStateMachine(std::shared_ptr<LinuxEvent> ThreadExitEvt, CcosStMRouteLine *pExternalWaitEvts[], size_t WaitCount, bool bClear)
  1139. {
  1140. CCOSSTMRET ret = CCOSSMRET_OK;
  1141. ClearState(bClear);
  1142. SetRunningState(true);
  1143. if (pExternalWaitEvts != NULL && WaitCount > 0)
  1144. {
  1145. m_RouteExternalEvtCount = WaitCount;
  1146. m_pRouteExternalMap = &pExternalWaitEvts[0];
  1147. }
  1148. //m_pCurrentRoutePos = (*m_pRoutePosMap)[string(CcosStmEntryPosName)];
  1149. TransToPos(CcosStmEntryPosName);
  1150. //入口Action
  1151. ret = StateMachineEntry(m_pCurrentRoutePos->GetTimeout());
  1152. if (ret != CCOSSMRET_OK)
  1153. {
  1154. PostError(CcosFrameError);
  1155. //mLog::FERROR("StateMachineEntry Failed.");
  1156. }
  1157. do
  1158. {
  1159. //wait events
  1160. int RouteWay = -1;
  1161. CcosStMEvt Evt;
  1162. Evt.SetEvt("TestNoFind", "");
  1163. CcosStMRouteLine *pRouteLine = StateMachineWaitForEvents(RouteWay, Evt);
  1164. RouteLine_Process:
  1165. if (RouteWay >= 0)
  1166. {
  1167. //External way
  1168. //goto exitpos
  1169. //mLog::FINFO("StateMachineWaitForEvents got external evt.exit sub state machine [{$}].", Evt.GetEvtContext().encode());
  1170. TransToPos(CcosStmExitPosName);
  1171. //run action without results
  1172. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  1173. //一旦在Exit出错,会再次进入WaitEvt,再执行Exit,.........dead loop
  1174. //if (ret != CCOSSMRET_OK)
  1175. //{
  1176. // continue;
  1177. //}
  1178. SetRunningState(false);
  1179. return RouteWay;
  1180. }
  1181. else if (RouteWay == -1)
  1182. {
  1183. //this machine
  1184. if (pRouteLine->GetActiveState())
  1185. {
  1186. //Guard
  1187. const char *pGuard = pRouteLine->GetGuardName();
  1188. if (pGuard != NULL && strlen(pGuard) > 0)
  1189. {
  1190. ret = StateMachineGuard(pGuard, TIMEOUT_TEMP);
  1191. if (ret != CCOSSMRET_OK)
  1192. {
  1193. continue;
  1194. }
  1195. }
  1196. }
  1197. //TransToPos
  1198. TransToPos(pRouteLine->GetDesName());
  1199. //mLog::FINFO("TransToPos:{$} from evnt {$}", pRouteLine->GetDesName(), Evt.GetEvtContext().encode());
  1200. if (string(CcosStmExitPosName) == m_pCurrentRoutePos->GetName())
  1201. {
  1202. //exit
  1203. //run action without results
  1204. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  1205. //check ret
  1206. if (ret != CCOSSMRET_OK)
  1207. {
  1208. PostError(CcosFrameError);
  1209. //mLog::FERROR("PostError CcosFrameError .curPos:{$}", m_pCurrentRoutePos->GetName());
  1210. continue;
  1211. }
  1212. //退出的时候,把事件带出去
  1213. PushEvent(Evt);
  1214. //exit here
  1215. SetRunningState(false);
  1216. return -1;
  1217. }
  1218. //statepos or statemachine
  1219. if (m_pCurrentRoutePos->GetActiveState())
  1220. {
  1221. if (m_pCurrentRoutePos->IsSMachine())
  1222. {
  1223. //子状态机嵌套
  1224. //copy evt in
  1225. CopyEvtTo((CcosSubSMachine*)m_pCurrentRoutePos);
  1226. //mLog::FINFO("Enter Sub StateMachine to {$} from Evt[{$}]", m_pCurrentRoutePos->GetName(), Evt.GetEvtContext().GetKey(0));
  1227. //run sub state machine
  1228. int ExitWay = EnterSubStateMachine(ThreadExitEvt, Evt);
  1229. //mLog::FINFO("exit from Sub StateMachine.{$},ret:{$}", m_pCurrentRoutePos->GetName(),ExitWay);
  1230. //copy evt out
  1231. ((CcosSubSMachine*)m_pCurrentRoutePos)->CopyEvtTo(this);
  1232. //trans to position
  1233. if (ExitWay >= 0)
  1234. {
  1235. if ((size_t)ExitWay < m_RouteExternalEvtCount)
  1236. {
  1237. //mLog::FINFO("exit from statemachine.{$} from event {$}", m_pCurrentRoutePos->GetName(), Evt.GetEvtContext().encode());
  1238. //external evt
  1239. TransToPos(CcosStmExitPosName);
  1240. //run action without results
  1241. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  1242. //一旦在Exit出错,会再次进入WaitEvt,再执行Exit,.........dead loop
  1243. //if (ret != CCOSSMRET_OK)
  1244. //{
  1245. // continue;
  1246. //}
  1247. SetRunningState(false);
  1248. return ExitWay;
  1249. }
  1250. else
  1251. {
  1252. //local evt
  1253. //trans to pos
  1254. RouteWay = -1;
  1255. pRouteLine = (*m_pRouteInLineMap)[ExitWay - m_RouteExternalEvtCount];
  1256. goto RouteLine_Process;
  1257. }
  1258. }
  1259. else
  1260. {
  1261. //outline .normal exit from statemachine
  1262. //mLog::FINFO("exit from sub statemachine");
  1263. }
  1264. }
  1265. else
  1266. {
  1267. //just route pos
  1268. //check exitposition
  1269. //if (string(CcosStmExitPosName) == m_pCurrentRoutePos->GetName())
  1270. //{
  1271. // //exit
  1272. // //run action without results
  1273. // ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  1274. // //check ret
  1275. // if (ret != CCOSSMRET_OK)
  1276. // {
  1277. // PostError(CcosFrameError);
  1278. // continue;
  1279. // }
  1280. // //exit here
  1281. // SetRunningState(false);
  1282. // return -1;
  1283. //}
  1284. //run action
  1285. ret = StateMachineAction(m_pCurrentRoutePos->GetName(), m_pCurrentRoutePos->GetTimeout());
  1286. //mLog::FINFO("SmAction:{$}.RET:{$}", m_pCurrentRoutePos->GetName(),(int)ret);
  1287. //check ret
  1288. if (ret != CCOSSMRET_OK)
  1289. {
  1290. if (ret == CCOSSMRET_EXIT)
  1291. {
  1292. //exit thread
  1293. //goto exitpos
  1294. TransToPos(CcosStmExitPosName);
  1295. //run action without results
  1296. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  1297. SetRunningState(false);
  1298. return -1;
  1299. }
  1300. PostError(CcosFrameError);
  1301. //mLog::FERROR("StateMachineAction Error Post CcosFrameError .curPos:{$}", m_pCurrentRoutePos->GetName());
  1302. }
  1303. }
  1304. }
  1305. }
  1306. else
  1307. {
  1308. //exit thread
  1309. //goto exitpos
  1310. TransToPos(CcosStmExitPosName);
  1311. //run action without results
  1312. ret = StateMachineExit(m_pCurrentRoutePos->GetTimeout());
  1313. SetRunningState(false);
  1314. return -1;
  1315. }
  1316. } while (1);
  1317. SetRunningState(false);
  1318. return -1;
  1319. }
  1320. //-------------------------------------
  1321. CcosSMachine::CcosSMachine()
  1322. {
  1323. m_pStatePosList = new MsgQueue<ResDataObject>();
  1324. m_StateQuedEvent = LinuxEvent::CreateEvent(LinuxEvent::MANUAL_RESET,false);
  1325. //if (//mLog::gLogger == nullptr)
  1326. //{
  1327. // string strLogPath = GetProcessDirectory() + R"(\Conf\Log4CPP.Config.xml)";
  1328. // //LogHost = ((string)getRootpath()).c_str();
  1329. // //if (LogHost.length() <= 1)
  1330. // //{
  1331. // // char szName[256];
  1332. // // sprintf(szName, "/LogicDevice_%08d", GetCurrentProcessId());
  1333. // // LogHost = szName;
  1334. // //}
  1335. // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "StateMachine");
  1336. // //Log4CPP::GlobalContext::Map::Set("LogHost", LogHost.c_str());
  1337. // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogHost"), "StateMachine");
  1338. // auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str());
  1339. // //mLog::gLogger = Log4CPP::LogManager::GetLogger("StateMachine");
  1340. // //mLog::FINFO("Code Build datetime [{$} {$}]", __DATE__, __TIME__);
  1341. //}
  1342. }
  1343. CcosSMachine::~CcosSMachine()
  1344. {
  1345. delete m_pStatePosList;
  1346. //if (GetLogger() != 0)
  1347. //{
  1348. // ReleseLogger((Logger*)GetLogger());
  1349. // SetLogger(0);
  1350. //}
  1351. }
  1352. void CcosSMachine::SetStateMachineLog(const char *pszLogTitle)
  1353. {
  1354. //if (GetLogger() == 0)
  1355. //{
  1356. // string logfile = GetProcessDirectory() + "\\logs\\";
  1357. // logfile = FormatstdString("%s%s.log", logfile.c_str(), pszLogTitle);
  1358. // Logger *pLog = CreateLogger();
  1359. // pLog->SetLogFilepath(logfile.c_str());
  1360. // SetLogger(pLog);
  1361. //}
  1362. }
  1363. bool CcosSMachine::OnStartThread()
  1364. {
  1365. return PrePareStateMachine();
  1366. }
  1367. bool CcosSMachine::Exec()
  1368. {
  1369. ExecStateMachine(GetExitEvt(),NULL, 0);
  1370. return false;
  1371. }
  1372. void CcosSMachine::PushStateChange(ResDataObject &ChangedPos)
  1373. {
  1374. m_pStatePosList->InQueue(ChangedPos);
  1375. m_StateQuedEvent->SetEvent();
  1376. }
  1377. bool CcosSMachine::PopStateChange(ResDataObject &LastPos)
  1378. {
  1379. bool ret = false;
  1380. if (m_pStatePosList->size() > 0)
  1381. {
  1382. m_pStatePosList->DeQueue(LastPos);
  1383. m_LastHitStatePos = LastPos;
  1384. ret = true;
  1385. }
  1386. if (m_pStatePosList->size() == 0)
  1387. {
  1388. m_StateQuedEvent->ResetEvent();
  1389. }
  1390. else
  1391. {
  1392. m_StateQuedEvent->SetEvent();
  1393. }
  1394. if (ret == false)
  1395. {
  1396. if (m_LastHitStatePos.size() > 0)
  1397. {
  1398. LastPos = m_LastHitStatePos;
  1399. ret = true;
  1400. }
  1401. }
  1402. return ret;
  1403. }
  1404. std::shared_ptr<LinuxEvent> CcosSMachine::GetStateQuedEvent()
  1405. {
  1406. return m_StateQuedEvent;
  1407. }
  1408. bool CcosSMachine::StartStateMachine(CcosStMRouteLine *pExternalWaitEvts[], DWORD WaitCount)
  1409. {
  1410. m_LastHitStatePos.clear();
  1411. if (WaitTheThreadEnd(0) == false)
  1412. {
  1413. //it's in running state
  1414. //printf("StartStateMachine Failed.it's in running state\n");
  1415. return false;
  1416. }
  1417. if (pExternalWaitEvts != NULL && WaitCount > 0)
  1418. {
  1419. m_RouteExternalEvtCount = WaitCount;
  1420. m_pRouteExternalMap = &pExternalWaitEvts[0];
  1421. }
  1422. bool ret = StartThread();
  1423. if (ret)
  1424. {
  1425. return GetRunningState(TIMEOUT_TEMP);
  1426. }
  1427. return ret;
  1428. }
  1429. void CcosSMachine::StopStateMachine(DWORD timeout)
  1430. {
  1431. //直接StopThread好像不是个办法,得让状态机退出前进行OnExit操作.
  1432. StopThread(timeout);
  1433. ClearState();
  1434. }
  1435. CcosSubSMachine::CcosSubSMachine(void)
  1436. {
  1437. }
  1438. CcosSubSMachine::CcosSubSMachine(const char *pName) : CcosStMRoutePos(pName)
  1439. {
  1440. SetStateMachineName(pName);
  1441. }
  1442. CcosSubSMachine::~CcosSubSMachine(void)
  1443. {
  1444. }
  1445. bool CcosSubSMachine::IsSMachine()
  1446. {
  1447. return true;
  1448. }