CcosSMachine.cpp 34 KB

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