CcosSMachineV3.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. // CcosSMachine.cpp : 定义 DLL 应用程序的导出函数。
  2. //
  3. #include <sstream>
  4. #include "stdafx.h"
  5. #include "common_api.h"
  6. #include "CcosSMachineV3.h"
  7. #include "CcosThread.h"
  8. using namespace std;
  9. //Log4CPP::Logger* //mLog::gLogger = nullptr;
  10. static string glo_runHistory;
  11. static string glo_eventList;
  12. #define Wxx_Test 0
  13. //-----------------标准状态机--------------------
  14. CcosSMachine::CcosSMachine()
  15. {
  16. try {
  17. // if (//mLog::gLogger == nullptr)
  18. // {
  19. // string strLogPath = GetProcessDirectory() + R"(\Conf\Log4CPP.Config.xml)";
  20. // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogFileName"), "StateMachineV3");
  21. // //Log4CPP::GlobalContext::Map::Set("LogHost", LogHost.c_str());
  22. //#if !Wxx_Test
  23. // Log4CPP::ThreadContext::Map::Set(ECOM::Utility::Hash("LogHost"), "StateMachineV3");
  24. // auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str());
  25. // //mLog::gLogger = Log4CPP::LogManager::GetLogger("Platform");
  26. //#else
  27. // auto rc = Log4CPP::LogManager::LoadConfigFile(strLogPath.c_str());
  28. // //mLog::gLogger = Log4CPP::LogManager::GetLogger("StateMachineV3");
  29. //#endif
  30. // }
  31. m_hTransStateEvt = LinuxEvent::CreateEvent(LinuxEvent::AUTO_RESET, false);
  32. m_hRunningEvt = LinuxEvent::CreateEvent(LinuxEvent::MANUAL_RESET, false);
  33. m_strName = "CcosSMachineV3";
  34. m_nSMState = SMST_NULL;
  35. //mLog::FDEBUG("StateMachine:[SMST_NULL:{$}]", (int)SMST_NULL);
  36. }
  37. catch (...)
  38. {
  39. //mLog::FERROR("CcosSMachine crash");
  40. }
  41. }
  42. CcosSMachine::~CcosSMachine()
  43. {
  44. /*if (m_pUIDebugObj)
  45. {
  46. if(m_pUIDebugObj->GetTID())
  47. m_pUIDebugObj->StopThread();
  48. delete m_pUIDebugObj;
  49. m_pUIDebugObj = nullptr;
  50. }*/
  51. StopStateMachine(STATEMACHINE_DefState_TIMEOUT);
  52. }
  53. bool CcosSMachine::Exec()
  54. {
  55. ExecStateMachine();
  56. return false;
  57. }
  58. bool CcosSMachine::OnStartThread()
  59. {
  60. if (CCOSSMRET_SUCCESS == StateMachineEntry(STATEMACHINE_DefState_TIMEOUT)) //进入流程跳转
  61. {
  62. return true;
  63. }
  64. else
  65. {
  66. //mLog::FERROR("StateMachineEntry Failed");
  67. return false;
  68. }
  69. }
  70. bool CcosSMachine::OnEndThread()
  71. {
  72. //防止ExecStateMachine处于等待
  73. if (CCOSSMRET_SUCCESS == StateMachineExit(STATEMACHINE_DefState_TIMEOUT))//退出流程跳转
  74. return true;
  75. else
  76. return false;
  77. }
  78. void CcosSMachine::ClearState()
  79. {
  80. Thread_Lock();
  81. m_EventsList.clear();
  82. m_EventsList.reserve(STATEMACHINE_MaxWaitEventList);
  83. m_StateMap.clear();
  84. m_DeviceMap.clear();
  85. m_AttributeCountMap.clear();
  86. Thread_UnLock();
  87. }
  88. CCOSSTMRET CcosSMachine::StateMachineEntry(DWORD timeout)
  89. {
  90. //mLog::FDEBUG("Enter StateMachine");
  91. CCOSSTMRET ret = CCOSSMRET_FAILED;
  92. //跳转至起始状态
  93. if (m_nSMState.load() >= SMST_BEGIN && m_nSMState.load() < SMST_END)
  94. {
  95. //mLog::FWARN("wrong state[{$}] can't -> SMST_BEGIN", (int)m_nSMState.load());
  96. }
  97. else
  98. {
  99. //mLog::FDEBUG("StateMachine:[SMST_BEGIN:{$}]", (int)SMST_BEGIN);
  100. m_nSMState = SMST_BEGIN;
  101. m_strCurrentState.clear();
  102. //给client池设置上层退出事件
  103. m_DevicePool.SetTopExitHandle(GetExitEvt());
  104. //提前将不存在设备的属性关联的条件设置为true
  105. for (auto& item : m_EventsList)
  106. {
  107. if (item.GetType() == EventType_Conditions)
  108. {
  109. map<string, stru_Condition>* coditionsMap = item.GetCoditionsMap();
  110. if (coditionsMap)
  111. {
  112. for (auto& finder : (*coditionsMap))
  113. {
  114. auto checker = m_AttributeCountMap.find(finder.second.m_Key);
  115. if (checker != m_AttributeCountMap.end())
  116. {
  117. if (checker->second <= 0)
  118. {
  119. finder.second.m_Result = true;
  120. item.CaculateCondition();
  121. }
  122. }
  123. }
  124. }
  125. }
  126. }
  127. //检查是否有直接跳转至下一个状态,有则激活
  128. CheckExternal();
  129. //状态跳转至起始状态
  130. ret = TransToPos(m_strBeginState.c_str());
  131. if (ret == CCOSSMRET_SUCCESS)//跳转成功后执行初始状态动作
  132. {
  133. ret = StateMachineAction(m_strBeginState.c_str(), timeout);
  134. }
  135. if (ret == CCOSSMRET_SUCCESS)//给client池设置属性获取后的处理接口
  136. {
  137. auto NotfiyProcess = [this](string& Pathkey, string& Context) -> void
  138. {
  139. WaitNotfiyProcess(Pathkey, Context);
  140. };
  141. if (!m_DevicePool.BeginNotifyLoop(NotfiyProcess))
  142. {
  143. ret = CCOSSMRET_FAILED;
  144. }
  145. }
  146. }
  147. return ret;
  148. }
  149. CCOSSTMRET CcosSMachine::StateMachineExit(DWORD timeout)
  150. {
  151. //mLog::FDEBUG("Exit StateMachine");
  152. //跳转至结束状态
  153. if (m_nSMState.load() == SMST_END)
  154. {
  155. //mLog::FDEBUG("StateMachine:[SMST_EXIT:{$}]", (int)SMST_EXIT);
  156. m_nSMState = SMST_EXIT;
  157. m_strCurrentState.clear();
  158. //结束client池属性获取循环
  159. m_DevicePool.EndNotifyLoop();
  160. }
  161. return CCOSSMRET_SUCCESS;
  162. }
  163. bool CcosSMachine::ExecStateMachine()
  164. {
  165. CCOSSTMRET ret = CCOSSMRET_NULL;
  166. try {
  167. //设置运行状态
  168. SetRunningState(true);
  169. do
  170. {
  171. //防止状态机流程状态跳转过快导致上层处理不过来
  172. if (m_hRunningEvt->Wait())
  173. {
  174. if (m_nSMState.load() == SMST_END || m_nSMState.load() == SMST_EXIT)
  175. {
  176. break;
  177. }
  178. }
  179. //获取当前状态关于超时的定义
  180. string timeoutState;
  181. DWORD confTimeout = GetCurrentStateTimeout(timeoutState);
  182. //检查是否有直接跳转至下一个状态,有则激活
  183. //string eventFrom;
  184. //GetCurrentState(eventFrom);
  185. //CheckExternal(eventFrom);
  186. //等待跳转到下一个状态条件触发
  187. string nextState;
  188. DWORD waitEventCount = m_hCurrentWaitEvtArray.size();
  189. if (waitEventCount <= 1 && confTimeout == INFINITE)//固定会有一个线程退出句柄
  190. {
  191. //mLog::FERROR("CurrentWaitEvtArray is empty and no TimeoutEvt");
  192. return false;
  193. }
  194. DWORD dwret = LinuxEvent::WaitForMultipleEvents(m_hCurrentWaitEvtArray,confTimeout);
  195. if (dwret >= WAIT_OBJECT_0 && dwret < WAIT_OBJECT_0 + waitEventCount)
  196. {
  197. int eventNumber = dwret - WAIT_OBJECT_0;
  198. if (eventNumber >= 0 && eventNumber < waitEventCount)
  199. {
  200. std::cout << "Triggered eventList[" << m_hCurrentWaitEvtArray[eventNumber] << "]" << std::endl;
  201. if (m_hCurrentWaitEvtArray[eventNumber] == GetExitEvt())//Exec结束所以退出
  202. {
  203. return false;
  204. }
  205. else//获取触发事件对应的To
  206. {
  207. for (auto& findItem : m_EventsList)
  208. {
  209. if (m_hCurrentWaitEvtArray[eventNumber] == findItem.GetTriggerHandle())
  210. {
  211. nextState = findItem.GetTo();
  212. //mLog::FDEBUG("wait Event[{$}] Triggered", findItem.GetName().c_str());
  213. if (findItem.GetFrom().empty())//全局事件只允许触发一次
  214. {
  215. findItem.ResetTrigger();
  216. }
  217. break;
  218. }
  219. }
  220. }
  221. }
  222. else
  223. {
  224. //mLog::FERROR("Trigger event number[{$}] not exist", eventNumber);
  225. }
  226. }
  227. else if (dwret == -1)
  228. {
  229. if (!timeoutState.empty())
  230. {
  231. nextState = timeoutState;
  232. //mLog::FDEBUG("status[{$}] wait[{$}] timeout", m_strCurrentState.c_str(), (int)confTimeout);
  233. }
  234. else
  235. {
  236. break;
  237. }
  238. }
  239. else
  240. {
  241. //mLog::FERROR("WaitForMultipleObjects get wrong [{$}] return", dwret);
  242. }
  243. //可以跳转至下一个状态
  244. if (!nextState.empty())
  245. {
  246. //获取当前状态
  247. string CurrentState;
  248. GetCurrentState(CurrentState);
  249. if (nextState == CurrentState)//状态跳转至自身为死循环了
  250. {
  251. //mLog::FERROR("StateMachinein loop[{$}]", nextState.c_str());
  252. return false;
  253. }
  254. if (TransToPos(nextState.c_str()) != CCOSSMRET_SUCCESS)//跳转至下一个状态
  255. {
  256. //mLog::FERROR("TransToPos[{$}] failed", nextState.c_str());
  257. return false;
  258. }
  259. //获取状态跳转后的超时定义
  260. confTimeout = GetCurrentStateTimeout(timeoutState);
  261. //执行新状态对应的方法
  262. ret = StateMachineAction(nextState.c_str(), confTimeout);
  263. switch (ret)
  264. {
  265. case CCOSSMRET_SUCCESS:
  266. {}break;
  267. case CCOSSMRET_TIMEOUT:
  268. case CCOSSMRET_FAILED:
  269. {
  270. if (!timeoutState.empty())
  271. {
  272. nextState = timeoutState;
  273. }
  274. else
  275. {
  276. break;
  277. }
  278. }break;
  279. case CCOSSMRET_EXIT:
  280. {
  281. return false;
  282. }break;
  283. default:
  284. break;
  285. }
  286. }
  287. if (m_strEndState == nextState)
  288. {
  289. break;
  290. }
  291. } while (m_nSMState.load() >= SMST_BEGIN && m_nSMState.load() < SMST_END);
  292. }
  293. catch (...)
  294. {
  295. //mLog::FERROR("ExecStateMachine crash");
  296. StopStateMachine(STATEMACHINE_DefState_TIMEOUT);
  297. }
  298. return true;
  299. }
  300. DWORD CcosSMachine::GetCurrentStateTimeout(string& timeoutState)
  301. {
  302. int timeout = INFINITE;
  303. string eventFrom; GetCurrentState(eventFrom);
  304. string eventTo;
  305. string confTimeout;
  306. for (auto& item : m_EventsList)
  307. {
  308. if (item.CheckTimeout(confTimeout, eventFrom, eventTo))
  309. {
  310. timeoutState = eventTo;
  311. timeout = atol(confTimeout.c_str());
  312. return timeout;
  313. }
  314. }
  315. return timeout;
  316. }
  317. CCOSSTMRET CcosSMachine::CheckExternal(string eventFrom)
  318. {
  319. string eventTo;
  320. int activeCount = 0;
  321. for (auto &item : m_EventsList)
  322. {
  323. if (item.CheckExternal(eventFrom, eventTo))
  324. {
  325. activeCount++;
  326. }
  327. }
  328. if(activeCount > 0)
  329. return CCOSSMRET_SUCCESS;
  330. else
  331. return CCOSSMRET_FAILED;
  332. }
  333. void CcosSMachine::WaitNotfiyProcess(string& Pathkey, string& Context)
  334. {
  335. string deviceKey = Pathkey;
  336. string strValue = Context;
  337. string eventFrom; GetCurrentState(eventFrom);
  338. //当前状态的事件检查
  339. for (auto& item : m_EventsList)
  340. {
  341. string eventTo;
  342. item.CheckConditions(deviceKey, strValue, eventFrom, eventTo);
  343. }
  344. }
  345. CCOSSTMRET CcosSMachine::TransToPos(const char* pPosName)
  346. {
  347. CCOSSTMRET ret = CCOSSMRET_NULL;
  348. try {
  349. auto findItem = m_StateMap.find(pPosName);
  350. if (findItem == m_StateMap.end())
  351. {
  352. ret = CCOSSMRET_EXIT;
  353. }
  354. else
  355. {
  356. Thread_Lock();
  357. //设置新事件
  358. m_strCurrentState = pPosName;
  359. Thread_UnLock();
  360. /*if (m_pUIDebugObj)
  361. {
  362. string temp(pPosName);
  363. glo_runHistory += (temp + "->");
  364. m_pUIDebugObj->SetRunHistory(glo_runHistory);
  365. }*/
  366. m_hCurrentWaitEvtArray.clear(); //清除之前的等待事件列表
  367. m_hCurrentWaitEvtArray.push_back(GetExitEvt());//设置Exec退出事件
  368. for (int i = 0; i < m_EventsList.size(); i++)//设置当前的等待事件表
  369. {
  370. vector<string> eventFrom = m_EventsList[i].GetFrom();
  371. if (eventFrom.empty() || std::find(eventFrom.begin(), eventFrom.end(), pPosName) != eventFrom.end())
  372. {
  373. if (m_EventsList[i].GetTriggerHandle())
  374. {
  375. m_hCurrentWaitEvtArray.push_back(m_EventsList[i].GetTriggerHandle());
  376. std::cout << "current wait eventList[" << m_hCurrentWaitEvtArray[i] << "]" << std::endl;
  377. glo_eventList += m_EventsList[i].GetName();
  378. }
  379. else
  380. {
  381. //mLog::FERROR("state[{$}] no TriggerHandle", m_EventsList[i].GetName().c_str());
  382. }
  383. }
  384. }
  385. /*if (m_pUIDebugObj)
  386. {
  387. m_pUIDebugObj->SetWaitEventList(glo_eventList);
  388. }*/
  389. //先停止后续流程跳转,给予上层订阅者执行时间
  390. SetRunningState(false);
  391. //再回调通知
  392. if (m_StateNotify != nullptr)
  393. {
  394. m_StateNotify(m_strMachineName.c_str(), pPosName);
  395. }
  396. //最后以事件通知上层订阅者(一般是子系统)
  397. m_hTransStateEvt->SetEvent();
  398. //mLog::FDEBUG("TransToPos:[{$}]", pPosName);
  399. ret = CCOSSMRET_SUCCESS;
  400. }
  401. }
  402. catch (...)
  403. {
  404. //mLog::FERROR("TransToPos crash");
  405. ret = CCOSSMRET_NULL;
  406. }
  407. return ret;
  408. }
  409. CCOSSTMRET CcosSMachine::StateMachineAction(const char* pState, DWORD timeout)
  410. {
  411. CCOSSTMRET ret = CCOSSMRET_NULL;
  412. auto findItem = m_StateMap.find(pState);
  413. if (findItem != m_StateMap.end())
  414. {
  415. //查找状态中的动作定义
  416. if (findItem->second.GetFirstOf(ConfItem_Actions) >= 0)
  417. {
  418. ResDataObject reqAction = findItem->second[ConfItem_Actions];
  419. ResDataObject resAction;
  420. //执行动作
  421. ret = m_DevicePool.StateMachineAction(reqAction, resAction, timeout);
  422. switch (ret)
  423. {
  424. case CCOSSMRET_SUCCESS:
  425. {
  426. //触发Action执行结果判断
  427. for (int aidx = 0; aidx < resAction.size(); aidx++)
  428. {
  429. string key = resAction.GetKey(aidx);
  430. string deviceName = key.substr(0, key.find(ConfItem_delim));
  431. string actionKey = key.substr(key.find(ConfItem_delim) + 1, key.length());
  432. string actionRet = (string)resAction[aidx];
  433. string eventFrom; GetCurrentState(eventFrom);
  434. for (auto &item : m_EventsList)
  435. {
  436. string eventTo;
  437. string deviceNotfiyKey;
  438. item.CheckConditions(deviceNotfiyKey, actionRet, eventFrom, eventTo);
  439. }
  440. }
  441. }break;
  442. case CCOSSMRET_TIMEOUT:
  443. {}break;
  444. case CCOSSMRET_FAILED:
  445. {}break;
  446. case CCOSSMRET_EXIT:
  447. {}break;
  448. default:
  449. break;
  450. }
  451. }
  452. }
  453. else
  454. {
  455. //mLog::FERROR("Unrecognized state[{$}]", pState);
  456. }
  457. return ret;
  458. }
  459. //=============对外提供接口=============
  460. void CcosSMachine::SetDebugMode(bool bEnable)
  461. {
  462. if (m_bDebugEnable != bEnable)
  463. {
  464. m_bDebugEnable = bEnable;
  465. //mLog::FDEBUG("SetDebugMode[{$}]", m_bDebugEnable);
  466. if (m_bDebugEnable)
  467. {
  468. auto FUN_DlgCallBack = [this](string name, string value) -> void
  469. {
  470. if (name == "TriggerEvent")
  471. {
  472. TriggerEvent(value);
  473. }
  474. else if (name == "SetRunningState")
  475. {
  476. SetRunningState(true);
  477. }
  478. };
  479. /*m_pUIDebugObj = new SMachineDlg("Ccos State Mechine Debug", "CcosStateMechineDlg", FUN_DlgCallBack);
  480. m_pUIDebugObj->StartThread();*/
  481. }
  482. else
  483. {
  484. /*if (m_pUIDebugObj)
  485. {
  486. m_pUIDebugObj->StopThread();
  487. delete m_pUIDebugObj;
  488. }*/
  489. }
  490. }
  491. }
  492. bool CcosSMachine::Reset(DWORD Timeout)
  493. {
  494. for (auto& item : m_EventsList)
  495. {
  496. item.ResetTrigger();
  497. }
  498. return true;
  499. }
  500. bool CcosSMachine::TriggerEvent(string EventName)
  501. {
  502. //mLog::FDEBUG("TriggerEvent:[{$}]", EventName.c_str());
  503. if (m_nSMState.load() >= SMST_BEGIN && m_nSMState.load() <= SMST_END)
  504. {
  505. for (auto& item : m_EventsList)
  506. {
  507. if (item.GetName() == EventName)
  508. {
  509. item.SetTrigger();
  510. return true;
  511. }
  512. }
  513. }
  514. else
  515. {
  516. //mLog::FWARN("wrong state[{$}] can't TriggerEvent",(int)m_nSMState.load());
  517. }
  518. return false;
  519. }
  520. void CcosSMachine::GetStateMachineState(SMSTATETYPE& state)
  521. {
  522. state = m_nSMState;
  523. }
  524. //从状态机定义中加载当前状态机定义
  525. bool CcosSMachine::LoadMachine(ResDataObject& Machine)
  526. {
  527. //mLog::FDEBUG("Enter LoadMachine");
  528. if (m_nSMState.load() < SMST_BEGIN || m_nSMState.load() >= SMST_END)
  529. {
  530. m_nSMState = SMST_INIT;
  531. //mLog::FDEBUG("StateMachine:[SMST_INIT:{$}]", (int)SMST_INIT);
  532. glo_runHistory.clear();
  533. glo_eventList.clear();
  534. if (Machine.GetFirstOf(ConfItem_MachineName) >= 0)
  535. {
  536. string tempName = (string)Machine[ConfItem_MachineName];
  537. if (m_strMachineName != tempName)
  538. {
  539. m_strMachineName = tempName;
  540. }
  541. else
  542. {
  543. //mLog::FDEBUG("same workFlow file[{$}],didn't reload", m_strMachineName.c_str());
  544. Reset(STATEMACHINE_DefState_TIMEOUT);
  545. return true;
  546. }
  547. }
  548. ClearState();
  549. if (Machine.GetFirstOf(ConfItem_Variable) >= 0)
  550. {
  551. m_resUserVariable = Machine[ConfItem_Variable];
  552. }
  553. if (Machine.GetFirstOf(ConfItem_States) >= 0)
  554. {
  555. ResDataObject stats;
  556. stats = Machine[ConfItem_States];
  557. for (int i = 0; i < stats.size(); i++)
  558. {
  559. string stateName = stats.GetKey(i);
  560. if (stateName == ConfItem_Begin)
  561. {
  562. m_strBeginState = (string)stats[i];
  563. }
  564. else if (stateName == ConfItem_End)
  565. {
  566. m_strEndState = (string)stats[i];
  567. }
  568. else
  569. {
  570. ResDataObject stateDefine = stats[i];
  571. m_StateMap[stateName] = stateDefine;
  572. //mLog::FDEBUG("get State[{$}]", stateName.c_str());
  573. if (stateDefine.GetFirstOf(ConfItem_Events) >= 0)
  574. {
  575. ResDataObject stateEvt = stateDefine[ConfItem_Events];
  576. int count = stateEvt.size();
  577. for (int i = 0; i < count; i++)
  578. {
  579. if (m_EventsList.size() <= STATEMACHINE_MaxWaitEventList)
  580. {
  581. string eventName = stateEvt.GetKey(i);
  582. m_EventsList.emplace_back(eventName, &(stateEvt[i]), &m_AttributeCountMap); //容器扩张导致会调用copy construct, 导致所有的m_hTriggered丢失
  583. //mLog::FDEBUG("get member event[{$}]", eventName.c_str());
  584. }
  585. else
  586. {
  587. //mLog::FDEBUG("eventList[size:{$}]too big", m_EventsList.size());
  588. }
  589. }
  590. }
  591. }
  592. }
  593. }
  594. if (Machine.GetFirstOf(ConfItem_Events) >= 0)
  595. {
  596. ResDataObject evts = Machine[ConfItem_Events];
  597. for (int i = 0; i < evts.size(); i++)
  598. {
  599. if (m_EventsList.size() <= STATEMACHINE_MaxWaitEventList)
  600. {
  601. string eventName = evts.GetKey(i);
  602. m_EventsList.emplace_back(eventName, &(evts[i]), &m_AttributeCountMap);
  603. //mLog::FDEBUG("get global event[{$}]", eventName.c_str());
  604. }
  605. else
  606. {
  607. //mLog::FDEBUG("eventList[size:{$}]too big", m_EventsList.size());
  608. }
  609. }
  610. }
  611. if (Machine.GetFirstOf(ConfItem_DevList) >= 0)
  612. {
  613. ResDataObject devs = Machine[ConfItem_DevList];
  614. if (devs.size() > 0)
  615. {
  616. AddDevices(devs, "");
  617. }
  618. }
  619. }
  620. else
  621. {
  622. //mLog::FWARN("wrong state[{$}] can't -> SMST_INIT", (int)m_nSMState.load());
  623. }
  624. return true;
  625. }
  626. //设置用户变量,只提供根一层的Key
  627. void CcosSMachine::SetUserVariable(const char* pKey, ResDataObject& resValue)
  628. {
  629. int vidx = m_resUserVariable.GetFirstOf(pKey);
  630. if (vidx < 0)
  631. m_resUserVariable.add(pKey, resValue);
  632. }
  633. //读取用户变量值,只提供根一层的Key
  634. void CcosSMachine::GetUserVariable(const char* pKey, ResDataObject& resValue)
  635. {
  636. if (pKey == nullptr)
  637. {
  638. resValue = m_resUserVariable;
  639. return;
  640. }
  641. int vidx = m_resUserVariable.GetFirstOf(pKey);
  642. if (vidx >= 0)
  643. resValue = m_resUserVariable[vidx];
  644. }
  645. void CcosSMachine::SetStateMachineName(string Name)
  646. {
  647. m_strMachineName = Name;
  648. }
  649. string CcosSMachine::GetStateMachineName()
  650. {
  651. return m_strMachineName;
  652. }
  653. void CcosSMachine::SetNotifyCallback(StateChangedCallback callback)
  654. {
  655. m_StateNotify = callback;
  656. }
  657. bool CcosSMachine::AddStateActions(ResDataObject& ActionMap)
  658. {
  659. if (ActionMap.GetFirstOf(ConfItem_States) >= 0)
  660. {
  661. ResDataObject globalstatus;
  662. globalstatus = ActionMap[ConfItem_States];
  663. for (int i = 0; i < globalstatus.size(); i++)
  664. {
  665. string stateName = globalstatus.GetKey(i);
  666. if (stateName == ConfItem_Begin)
  667. {
  668. m_strBeginState = (string)globalstatus[i];
  669. }
  670. else if (stateName == ConfItem_End)
  671. {
  672. m_strEndState = (string)globalstatus[i];
  673. }
  674. else
  675. {
  676. ResDataObject stateDefine = globalstatus[i];
  677. m_StateMap[stateName] = stateDefine;
  678. //mLog::FDEBUG("get State[{$}]", stateName.c_str());
  679. }
  680. }
  681. }
  682. return true;
  683. }
  684. bool CcosSMachine::AddStateEvents(ResDataObject& EventMap)
  685. {
  686. if (EventMap.GetFirstOf(ConfItem_Events) >= 0)
  687. {
  688. ResDataObject globalEvt = EventMap[ConfItem_Events];
  689. for (int i = 0; i < globalEvt.size(); i++)
  690. {
  691. if (m_EventsList.size() <= STATEMACHINE_MaxWaitEventList)
  692. {
  693. string eventName = globalEvt.GetKey(i);
  694. m_EventsList.emplace_back(eventName, &(globalEvt[i]), &m_AttributeCountMap);
  695. //mLog::FDEBUG("get event[{$}]", eventName.c_str());
  696. }
  697. else
  698. {
  699. //mLog::FDEBUG("eventList[size:{$}]too big", m_EventsList.size());
  700. }
  701. }
  702. }
  703. return true;
  704. }
  705. bool CcosSMachine::AddDevices(ResDataObject& DevList, string WS)
  706. {
  707. if (m_nSMState.load() == SMST_INIT)
  708. {
  709. //mLog::FDEBUG("AddDevices:deviceCount[{$}], WorkStation[{$}]", (int)DevList.size(), WS.c_str());
  710. if (m_EventsList.empty())
  711. {
  712. //mLog::FWARN("must LoadMachine first");
  713. return false;
  714. }
  715. m_DeviceMap.clear();
  716. for (int devIdx = 0; devIdx < DevList.size(); devIdx++)
  717. {
  718. string strDeviceType = DevList.GetKey(devIdx);
  719. string strDevicePath = DevList[devIdx].encode();
  720. m_DeviceMap[strDeviceType] = strDevicePath;
  721. }
  722. ResDataObject tempAttributes;
  723. for (auto& item : m_AttributeCountMap)
  724. {
  725. string devType = item.first.substr(0, item.first.find(ConfItem_delim));
  726. string attr = item.first.substr(item.first.find(ConfItem_delim) + 1, item.first.length());
  727. tempAttributes.add(devType.c_str(), attr.c_str());
  728. if (m_DeviceMap.find(devType) == m_DeviceMap.end())//不存在的设备判断条件默认为真
  729. {
  730. //mLog::FWARN("device[{$}] not exist, Condition with Attribute[{$}] default true", devType.c_str(), item.first.c_str());
  731. item.second = 0;
  732. }
  733. }
  734. if (!m_DevicePool.SetDeviceAttributes(DevList, tempAttributes, WS))
  735. {
  736. //mLog::FERROR("can't apply DeviceList of config file");
  737. return false;
  738. }
  739. }
  740. else
  741. {
  742. //mLog::FWARN("wrong state[{$}] can't AddDevices", (int)m_nSMState.load());
  743. }
  744. return true;
  745. }
  746. //检查:路径,状态点,以及它们的ActiveState
  747. bool CcosSMachine::PrePareStateMachine()
  748. {
  749. //设备属性初始化
  750. for (auto &item : m_EventsList)
  751. {
  752. //使用Get?
  753. }
  754. return true;
  755. }
  756. bool CcosSMachine::StartStateMachine()
  757. {
  758. bool ret = true;
  759. if (m_nSMState.load() == SMST_INIT)
  760. {
  761. if (WaitTheThreadEnd(0) == false)
  762. {
  763. //mLog::FERROR("StartStateMachine Failed.it's in running state");
  764. return false;
  765. }
  766. ret = StartThread();
  767. }
  768. else
  769. {
  770. //mLog::FWARN("wrong state[{$}] can't StartStateMachine", (int)m_nSMState.load());
  771. }
  772. return ret;
  773. }
  774. std::shared_ptr<LinuxEvent> CcosSMachine::GetStateTransEvent()
  775. {
  776. return m_hTransStateEvt;
  777. }
  778. void CcosSMachine::GetCurrentState(string& State)
  779. {
  780. Thread_Lock();
  781. State = m_strCurrentState;
  782. Thread_UnLock();
  783. }
  784. void CcosSMachine::SetRunningState(bool Running)
  785. {
  786. if (m_nSMState.load() >= SMST_BEGIN && m_nSMState.load() <= SMST_END)
  787. {
  788. if (Running)
  789. {
  790. if (m_nSMState != SMST_RUN)
  791. {
  792. //mLog::FDEBUG("StateMachine:[SMST_RUN:{$}]", (int)SMST_RUN);
  793. m_nSMState = SMST_RUN;
  794. m_hRunningEvt->SetEvent();
  795. }
  796. }
  797. else
  798. {
  799. if (m_nSMState != SMST_STOP)
  800. {
  801. //mLog::FDEBUG("StateMachine:[SMST_STOP:{$}]", (int)SMST_STOP);
  802. m_nSMState = SMST_STOP;
  803. m_hRunningEvt->ResetEvent();
  804. }
  805. }
  806. }
  807. else
  808. {
  809. //mLog::FWARN("wrong state[{$}] can't -> SMST_RUN or SMST_STOP", (int)m_nSMState.load());
  810. }
  811. }
  812. void CcosSMachine::StopStateMachine(DWORD timeout)
  813. {
  814. if (m_nSMState.load() >= SMST_BEGIN && m_nSMState.load() < SMST_END)
  815. {
  816. //mLog::FDEBUG("StateMachine:[SMST_END:{$}]", (int)SMST_END);
  817. m_nSMState = SMST_END;
  818. SetRunningState(true);
  819. StopThread(timeout);
  820. m_StateNotify == nullptr;
  821. Reset(STATEMACHINE_DefState_TIMEOUT);
  822. //mLog::FDEBUG("StateMachine:[SMST_EXIT:{$}]", (int)SMST_EXIT);
  823. m_nSMState = SMST_EXIT;
  824. }
  825. else
  826. {
  827. //mLog::FWARN("StopStateMachine: already stop");
  828. }
  829. }
  830. #if Debug_HTTP
  831. RET_STATUS CcosSMachine::OnUpdate(const char* pszProperty, const char* pszValueUpdate, ResDataObject& resRespons)
  832. {
  833. return RET_STATUS::RET_SUCCEED;
  834. }
  835. RET_STATUS CcosSMachine::OnDel(const char* pszPropery, ResDataObject& resDelValue, ResDataObject& resResponse)
  836. {
  837. return RET_STATUS::RET_SUCCEED;
  838. }
  839. RET_STATUS CcosSMachine::OnAdd(const char* pszPropery, ResDataObject& reAddValue, ResDataObject& resResponse)
  840. {
  841. return RET_STATUS::RET_SUCCEED;
  842. }
  843. RET_STATUS CcosSMachine::SetItem(const char* pszPropery, ResDataObject& resSetValue, ResDataObject& resResponse)
  844. {
  845. return RET_STATUS::RET_SUCCEED;
  846. }
  847. RET_STATUS CcosSMachine::GetItem(const char* pszPropery, ResDataObject& resResponse)
  848. {
  849. return RET_STATUS::RET_SUCCEED;
  850. }
  851. RET_STATUS CcosSMachine::OnAction(const char* pszActionName, const char* pszParams, ResDataObject& resResponse)
  852. {
  853. return RET_STATUS::RET_SUCCEED;
  854. }
  855. #endif
  856. extern "C" void* CreateCcosSMachine()
  857. {
  858. return new CcosSMachine();
  859. }
  860. extern "C" void DeleteCcosSMachine(void* ptr)
  861. {
  862. if (ptr)
  863. {
  864. delete (CcosSMachine*)ptr;
  865. ptr = nullptr;
  866. }
  867. }