zf_fsm.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /**
  2. *****************************************************************************
  3. * @file zf_fsm.c
  4. * @author Zorb
  5. * @version V1.0.0
  6. * @date 2018-06-28
  7. * @brief 有限状态机的实现
  8. *****************************************************************************
  9. * @history
  10. *
  11. * 1. Date:2018-06-28
  12. * Author:Zorb
  13. * Modification:建立文件
  14. *
  15. *****************************************************************************
  16. */
  17. #include "zf_fsm.h"
  18. #include "zf_assert.h"
  19. #include "zf_debug.h"
  20. #include "zf_malloc.h"
  21. /******************************************************************************
  22. * 描述 :创建状态机(内部分配空间)
  23. * 参数 :(out)-ppFsm 状态机指针的指针
  24. * 返回 :-true 成功
  25. * -false 失败
  26. ******************************************************************************/
  27. bool Fsm_create(Fsm ** ppFsm)
  28. {
  29. Fsm *pFsm;
  30. ZF_ASSERT(ppFsm != (Fsm **)0)
  31. /* 分配空间 */
  32. pFsm = ZF_MALLOC(sizeof(Fsm));
  33. if (pFsm == NULL)
  34. {
  35. ZF_DEBUG(LOG_E, "malloc fsm space error\r\n");
  36. return false;
  37. }
  38. /* 初始化成员 */
  39. pFsm->Level = 1;
  40. pFsm->ChildList = NULL;
  41. pFsm->Owner = NULL;
  42. pFsm->OwnerTriggerState = NULL;
  43. pFsm->CurrentState = NULL;
  44. pFsm->IsRunning = false;
  45. /* 初始化方法 */
  46. pFsm->SetInitialState = Fsm_setInitialState;
  47. pFsm->Run = Fsm_run;
  48. pFsm->RunAll = Fsm_runAll;
  49. pFsm->Stop = Fsm_stop;
  50. pFsm->StopAll = Fsm_stopAll;
  51. pFsm->Dispose = Fsm_dispose;
  52. pFsm->DisposeAll = Fsm_disposeAll;
  53. pFsm->AddChild = Fsm_addChild;
  54. pFsm->RemoveChild = Fsm_removeChild;
  55. pFsm->Dispatch = Fsm_dispatch;
  56. pFsm->Transfer = Fsm_transfer;
  57. pFsm->TransferWithEvent = Fsm_transferWithEvent;
  58. /* 输出 */
  59. *ppFsm = pFsm;
  60. return true;
  61. }
  62. /******************************************************************************
  63. * 描述 :设置状态机初始状态
  64. * 参数 :(in)-pFsm 状态机指针
  65. * (in)-initialState 状态机初始状态
  66. * 返回 :-true 成功
  67. * -false 失败
  68. ******************************************************************************/
  69. void Fsm_setInitialState(Fsm * const pFsm, IFsmState initialState)
  70. {
  71. ZF_ASSERT(pFsm != (Fsm *)0)
  72. ZF_ASSERT(initialState != (IFsmState)0)
  73. pFsm->CurrentState = initialState;
  74. }
  75. /******************************************************************************
  76. * 描述 :运行当前状态机
  77. * 参数 :(in)-pFsm 状态机指针
  78. * 返回 :-true 成功
  79. * -false 失败
  80. ******************************************************************************/
  81. bool Fsm_run(Fsm * const pFsm)
  82. {
  83. /* 返回结果 */
  84. bool res = false;
  85. ZF_ASSERT(pFsm != (Fsm *)0)
  86. if (!pFsm->IsRunning)
  87. {
  88. pFsm->IsRunning = true;
  89. res = true;
  90. }
  91. return res;
  92. }
  93. /******************************************************************************
  94. * 描述 :运行当前状态机和子状态机
  95. * 参数 :(in)-pFsm 状态机指针
  96. * 返回 :-true 成功
  97. * -false 失败
  98. ******************************************************************************/
  99. bool Fsm_runAll(Fsm * const pFsm)
  100. {
  101. ZF_ASSERT(pFsm != (Fsm *)0)
  102. Fsm_run(pFsm);
  103. if (pFsm->ChildList != NULL && pFsm->ChildList->Count > 0)
  104. {
  105. uint32_t i;
  106. Fsm * pChildFsm;
  107. for (i = 0; i < pFsm->ChildList->Count; i++)
  108. {
  109. pChildFsm = (Fsm *)pFsm->ChildList
  110. ->GetElementDataAt(pFsm->ChildList, i);
  111. if (pChildFsm != NULL)
  112. {
  113. Fsm_runAll(pChildFsm);
  114. }
  115. }
  116. }
  117. return true;
  118. }
  119. /******************************************************************************
  120. * 描述 :停止当前状态机
  121. * 参数 :(in)-pFsm 状态机指针
  122. * 返回 :-true 成功
  123. * -false 失败
  124. ******************************************************************************/
  125. bool Fsm_stop(Fsm * const pFsm)
  126. {
  127. ZF_ASSERT(pFsm != (Fsm *)0)
  128. pFsm->IsRunning = false;
  129. return true;
  130. }
  131. /******************************************************************************
  132. * 描述 :停止当前状态机和子状态机
  133. * 参数 :(in)-pFsm 状态机指针
  134. * 返回 :-true 成功
  135. * -false 失败
  136. ******************************************************************************/
  137. bool Fsm_stopAll(Fsm * const pFsm)
  138. {
  139. ZF_ASSERT(pFsm != (Fsm *)0)
  140. Fsm_stop(pFsm);
  141. if (pFsm->ChildList != NULL && pFsm->ChildList->Count > 0)
  142. {
  143. uint32_t i;
  144. Fsm * pChildFsm;
  145. for (i = 0; i < pFsm->ChildList->Count; i++)
  146. {
  147. pChildFsm = (Fsm *)pFsm->ChildList
  148. ->GetElementDataAt(pFsm->ChildList, i);
  149. if (pChildFsm != NULL)
  150. {
  151. Fsm_stopAll(pChildFsm);
  152. }
  153. }
  154. }
  155. return true;
  156. }
  157. /******************************************************************************
  158. * 描述 :释放当前状态机
  159. * 参数 :(in)-pFsm 状态机指针
  160. * 返回 :-true 成功
  161. * -false 失败
  162. ******************************************************************************/
  163. bool Fsm_dispose(Fsm * const pFsm)
  164. {
  165. ZF_ASSERT(pFsm != (Fsm *)0)
  166. if (pFsm->ChildList != NULL)
  167. {
  168. pFsm->ChildList->Dispose(pFsm->ChildList);
  169. }
  170. ZF_FREE(pFsm);
  171. return true;
  172. }
  173. /******************************************************************************
  174. * 描述 :释放当前状态机和子状态机
  175. * 参数 :(in)-pFsm 状态机指针
  176. * 返回 :-true 成功
  177. * -false 失败
  178. ******************************************************************************/
  179. bool Fsm_disposeAll(Fsm * const pFsm)
  180. {
  181. ZF_ASSERT(pFsm != (Fsm *)0)
  182. if (pFsm->ChildList != NULL && pFsm->ChildList->Count > 0)
  183. {
  184. uint32_t i;
  185. Fsm * pChildFsm;
  186. for (i = 0; i < pFsm->ChildList->Count; i++)
  187. {
  188. pChildFsm = (Fsm *)pFsm->ChildList
  189. ->GetElementDataAt(pFsm->ChildList, i);
  190. if (pChildFsm != NULL)
  191. {
  192. Fsm_disposeAll(pChildFsm);
  193. }
  194. }
  195. }
  196. Fsm_dispose(pFsm);
  197. return true;
  198. }
  199. /******************************************************************************
  200. * 描述 :添加子状态机
  201. * 参数 :(in)-pFsm 状态机指针
  202. * (in)-pChildFsm 子状态机指针
  203. * 返回 :-true 成功
  204. * -false 失败
  205. ******************************************************************************/
  206. bool Fsm_addChild(Fsm * const pFsm, Fsm * const pChildFsm)
  207. {
  208. /* 返回结果 */
  209. bool res = false;
  210. List *pList;
  211. ListNode *pNode;
  212. ZF_ASSERT(pFsm != (Fsm *)0)
  213. ZF_ASSERT(pChildFsm != (Fsm *)0)
  214. if (pFsm->ChildList == NULL)
  215. {
  216. List_create(&pList);
  217. pFsm->ChildList = pList;
  218. }
  219. pList = pFsm->ChildList;
  220. if (pList != NULL)
  221. {
  222. List_mallocNode(&pNode, NULL, 0);
  223. if (pNode != NULL)
  224. {
  225. pNode->pData = (void *)pChildFsm;
  226. pNode->Size = sizeof(Fsm);
  227. pList->Add(pList, pNode);
  228. pChildFsm->Owner = pFsm;
  229. pChildFsm->Level = pFsm->Level + 1;
  230. res = true;
  231. }
  232. }
  233. return res;
  234. }
  235. /******************************************************************************
  236. * 描述 :移除子状态机(不释放空间)
  237. * 参数 :(in)-pFsm 状态机指针
  238. * (in)-pChildFsm 子状态机指针
  239. * 返回 :-true 成功
  240. * -false 失败
  241. ******************************************************************************/
  242. bool Fsm_removeChild(Fsm * const pFsm, Fsm * const pChildFsm)
  243. {
  244. /* 返回结果 */
  245. bool res = false;
  246. ZF_ASSERT(pFsm != (Fsm *)0)
  247. ZF_ASSERT(pChildFsm != (Fsm *)0)
  248. if (pFsm->ChildList != NULL && pFsm->ChildList->Count > 0)
  249. {
  250. ListNode *pNode;
  251. /* 移除状态机 */
  252. while(pFsm->ChildList
  253. ->GetElementByData(pFsm->ChildList, pChildFsm, &pNode))
  254. {
  255. if (pNode == NULL)
  256. {
  257. break;
  258. }
  259. if (!pFsm->ChildList->Delete(pFsm->ChildList, pNode))
  260. {
  261. ZF_DEBUG(LOG_E, "delete fsm node from list error\r\n");
  262. break;
  263. }
  264. res = true;
  265. }
  266. }
  267. return res;
  268. }
  269. /******************************************************************************
  270. * 描述 :调度状态机
  271. * 参数 :(in)-pFsm 状态机指针
  272. * (in)-signal 调度信号
  273. * 返回 :-true 成功
  274. * -false 失败
  275. ******************************************************************************/
  276. bool Fsm_dispatch(Fsm * const pFsm, FsmSignal const signal)
  277. {
  278. /* 返回结果 */
  279. bool res = false;
  280. ZF_ASSERT(pFsm != (Fsm *)0)
  281. if (pFsm->IsRunning)
  282. {
  283. if (pFsm->ChildList != NULL && pFsm->ChildList->Count > 0)
  284. {
  285. uint32_t i;
  286. Fsm * pChildFsm;
  287. for (i = 0; i < pFsm->ChildList->Count; i++)
  288. {
  289. pChildFsm = (Fsm *)pFsm->ChildList
  290. ->GetElementDataAt(pFsm->ChildList, i);
  291. if (pChildFsm != NULL)
  292. {
  293. Fsm_dispatch(pChildFsm, signal);
  294. }
  295. }
  296. }
  297. if (pFsm->CurrentState != NULL)
  298. {
  299. /* 1:根状态机时调度
  300. 2:没设置触发状态时调度
  301. 3:正在触发状态时调度
  302. */
  303. if (pFsm->Owner == NULL || pFsm->OwnerTriggerState == NULL
  304. || pFsm->OwnerTriggerState == pFsm->Owner->CurrentState)
  305. {
  306. pFsm->CurrentState(pFsm, signal);
  307. res = true;
  308. }
  309. }
  310. }
  311. return res;
  312. }
  313. /******************************************************************************
  314. * 描述 :状态转移
  315. * 参数 :(in)-pFsm 状态机指针
  316. * (in)-nextState 转移后状态
  317. * 返回 :-true 成功
  318. * -false 失败
  319. ******************************************************************************/
  320. void Fsm_transfer(Fsm * const pFsm, IFsmState nextState)
  321. {
  322. ZF_ASSERT(pFsm != (Fsm *)0)
  323. ZF_ASSERT(nextState != (IFsmState)0)
  324. pFsm->CurrentState = (IFsmState)nextState;
  325. }
  326. /******************************************************************************
  327. * 描述 :状态转移(触发转出和转入事件)
  328. * 参数 :(in)-pFsm 状态机指针
  329. * (in)-nextState 转移后状态
  330. * 返回 :-true 成功
  331. * -false 失败
  332. ******************************************************************************/
  333. void Fsm_transferWithEvent(Fsm * const pFsm, IFsmState nextState)
  334. {
  335. ZF_ASSERT(pFsm != (Fsm *)0)
  336. ZF_ASSERT(nextState != (IFsmState)0)
  337. Fsm_dispatch(pFsm, FSM_EXIT_SIG);
  338. Fsm_transfer(pFsm, nextState);
  339. Fsm_dispatch(pFsm, FSM_ENTER_SIG);
  340. }
  341. /******************************** END OF FILE ********************************/