SeqenecRoutine.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Specialized;
  4. using System.Linq;
  5. using System.Text;
  6. using Aitex.Core.RT.Event;
  7. using Aitex.Core.RT.Log;
  8. using Aitex.Core.Util;
  9. namespace Aitex.Core.RT.Routine
  10. {
  11. public class RoutineFaildException : ApplicationException
  12. {
  13. public RoutineFaildException() { }
  14. public RoutineFaildException(string message)
  15. : base(message) { }
  16. }
  17. public class RoutineBreakException : ApplicationException
  18. {
  19. public RoutineBreakException() { }
  20. public RoutineBreakException(string message)
  21. : base(message) { }
  22. }
  23. public enum RoutineState
  24. {
  25. Running,
  26. Failed,
  27. Timeout,
  28. Finished,
  29. }
  30. public class RoutineResult
  31. {
  32. public RoutineState Result;
  33. public string ErrorMessage;
  34. }
  35. public class SeqenecRoutine
  36. {
  37. //timer, 计算routine时间
  38. protected DeviceTimer counter = new DeviceTimer();
  39. protected DeviceTimer delayTimer = new DeviceTimer();
  40. private enum STATE
  41. {
  42. IDLE,
  43. WAIT,
  44. }
  45. private int _id; //step index
  46. private Stack<int> _steps = new Stack<int>();
  47. private STATE state; //step state //idel,wait,
  48. //loop control
  49. private int loop = 0;
  50. private int loopCount = 0;
  51. private int loopID = 0;
  52. private DeviceTimer timer = new DeviceTimer();
  53. public int LoopCounter { get { return loop; } }
  54. // public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }
  55. //状态持续时间,单位为秒
  56. public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }
  57. protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };
  58. public void Reset()
  59. {
  60. _id = 0;
  61. _steps.Clear();
  62. loop = 0;
  63. state = STATE.IDLE;
  64. counter.Start(60*60*100); //默认1小时
  65. RoutineToken.Result = RoutineState.Running;
  66. }
  67. protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)
  68. {
  69. if (!Acitve(id))
  70. return;
  71. result.Result = execution();
  72. }
  73. #region interface
  74. public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)
  75. {
  76. int idx = Convert.ToInt32(id);
  77. bool bActive = Acitve(idx);
  78. if (bActive)
  79. {
  80. if (!func())
  81. {
  82. return Tuple.Create(bActive, Result.FAIL); //执行错误
  83. }
  84. loopID = idx;
  85. loopCount = count;
  86. next();
  87. return Tuple.Create(true, Result.RUN);
  88. }
  89. return Tuple.Create(false, Result.RUN);
  90. }
  91. public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)
  92. {
  93. int idx = Convert.ToInt32(id);
  94. bool bActive = Acitve(idx);
  95. if (bActive)
  96. {
  97. if (++loop >= loopCount) //Loop 结束
  98. {
  99. if (!func())
  100. {
  101. return Tuple.Create(bActive, Result.FAIL); //执行错误
  102. }
  103. loop = 0;
  104. next();
  105. return Tuple.Create(true, Result.RUN);
  106. }
  107. //继续下一LOOP
  108. next(loopID);
  109. return Tuple.Create(true, Result.RUN);
  110. }
  111. return Tuple.Create(false, Result.RUN);
  112. }
  113. public Tuple<bool, Result> ExecuteAndWait<T>(T id, IRoutine routine)
  114. {
  115. int idx = Convert.ToInt32(id);
  116. bool bActive = Acitve(idx);
  117. if (bActive)
  118. {
  119. if (state == STATE.IDLE)
  120. {
  121. Result startRet = routine.Start();
  122. if (startRet == Result.FAIL)
  123. {
  124. return Tuple.Create(true, Result.FAIL); //执行错误
  125. }else if (startRet == Result.DONE)
  126. {
  127. next();
  128. return Tuple.Create(true, Result.DONE);
  129. }
  130. state = STATE.WAIT;
  131. }
  132. Result ret = routine.Monitor();
  133. if (ret == Result.DONE)
  134. {
  135. next();
  136. return Tuple.Create(true, Result.DONE);
  137. }
  138. else if (ret == Result.FAIL || ret == Result.TIMEOUT)
  139. {
  140. return Tuple.Create(true, Result.FAIL);
  141. }
  142. else
  143. {
  144. return Tuple.Create(true, Result.RUN);
  145. }
  146. }
  147. return Tuple.Create(false, Result.RUN);
  148. }
  149. public Tuple<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> routines)
  150. {
  151. int idx = Convert.ToInt32(id);
  152. bool bActive = Acitve(idx);
  153. if (bActive)
  154. {
  155. if (state == STATE.IDLE)
  156. {
  157. foreach (var item in routines)
  158. {
  159. if (item.Start() == Result.FAIL)
  160. return Tuple.Create(true, Result.FAIL);
  161. }
  162. state = STATE.WAIT;
  163. }
  164. //wait all sub failed or completedboo
  165. bool bFail = false;
  166. bool bDone = true;
  167. foreach (var item in routines)
  168. {
  169. Result ret = item.Monitor();
  170. bDone &= (ret == Result.FAIL || ret == Result.DONE);
  171. bFail |= ret == Result.FAIL;
  172. }
  173. if (bDone)
  174. {
  175. next();
  176. if(bFail)
  177. return Tuple.Create(true, Result.FAIL);
  178. return Tuple.Create(true, Result.DONE);
  179. }
  180. return Tuple.Create(true, Result.RUN);
  181. }
  182. return Tuple.Create(false, Result.RUN);
  183. }
  184. public Tuple<bool, Result> Check<T>(T id, Func<bool> func) //顺序执行
  185. {
  186. return Check(Check(Convert.ToInt32(id), func));
  187. }
  188. public Tuple<bool, Result> Execute<T>(T id, Func<bool> func) //顺序执行
  189. {
  190. return Check(execute(Convert.ToInt32(id), func));
  191. }
  192. public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  193. {
  194. return Check(wait(Convert.ToInt32(id), func, timeout));
  195. }
  196. public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition
  197. {
  198. return Check(wait(Convert.ToInt32(id), func, timeout));
  199. }
  200. public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, double timeout = int.MaxValue)
  201. {
  202. int idx = Convert.ToInt32(id);
  203. bool bActive = Acitve(idx);
  204. bool? bExecute = false;
  205. if (bActive)
  206. {
  207. if (state == STATE.IDLE)
  208. {
  209. if (!execute())
  210. {
  211. return Tuple.Create(bActive, Result.FAIL); //执行错误
  212. }
  213. timer.Start(timeout);
  214. state = STATE.WAIT;
  215. }
  216. bExecute = check();
  217. if (bExecute == null)
  218. {
  219. return Tuple.Create(bActive, Result.FAIL); //Termianate
  220. }
  221. else
  222. {
  223. if (bExecute.Value) //检查Success, next
  224. {
  225. next();
  226. return Tuple.Create(true, Result.RUN);
  227. }
  228. }
  229. if(timer.IsTimeout())
  230. return Tuple.Create(true, Result.TIMEOUT);
  231. return Tuple.Create(true, Result.RUN);
  232. }
  233. return Tuple.Create(false, Result.RUN);
  234. }
  235. public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<bool?> check, Func<double> time)
  236. {
  237. int idx = Convert.ToInt32(id);
  238. bool bActive = Acitve(idx);
  239. bool? bExecute = false;
  240. double timeout = 0;
  241. if (bActive)
  242. {
  243. if (state == STATE.IDLE)
  244. {
  245. timeout = time();
  246. if (!execute())
  247. {
  248. return Tuple.Create(true, Result.FAIL); //执行错误
  249. }
  250. timer.Start(timeout);
  251. state = STATE.WAIT;
  252. }
  253. bExecute = check();
  254. if (bExecute == null)
  255. {
  256. return Tuple.Create(true, Result.FAIL); //Termianate
  257. }
  258. if (bExecute.Value) //检查Success, next
  259. {
  260. next();
  261. return Tuple.Create(true, Result.RUN);
  262. }
  263. if (timer.IsTimeout())
  264. return Tuple.Create(true, Result.TIMEOUT);
  265. return Tuple.Create(true, Result.RUN);
  266. }
  267. return Tuple.Create(false, Result.RUN);
  268. }
  269. public Tuple<bool, Result> Wait<T>(T id, IRoutine rt)
  270. {
  271. int idx = Convert.ToInt32(id);
  272. bool bActive = Acitve(idx);
  273. if (bActive)
  274. {
  275. if (state == STATE.IDLE)
  276. {
  277. rt.Start();
  278. state = STATE.WAIT;
  279. }
  280. Result ret = rt.Monitor();
  281. return Tuple.Create(true, ret);
  282. }
  283. return Tuple.Create(false, Result.RUN);
  284. }
  285. //Monitor
  286. public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)
  287. {
  288. int idx = Convert.ToInt32(id);
  289. bool bActive = Acitve(idx);
  290. bool bCheck = false;
  291. if (bActive)
  292. {
  293. if (state == STATE.IDLE)
  294. {
  295. if ((func != null) && !func())
  296. {
  297. return Tuple.Create(true, Result.FAIL);
  298. }
  299. timer.Start(time);
  300. state = STATE.WAIT;
  301. }
  302. bCheck = check();
  303. if (!bCheck)
  304. {
  305. return Tuple.Create(true, Result.FAIL); //Termianate
  306. }
  307. if (timer.IsTimeout())
  308. {
  309. next();
  310. }
  311. return Tuple.Create(true, Result.RUN);
  312. }
  313. return Tuple.Create(false, Result.RUN);
  314. }
  315. //Delay
  316. public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)
  317. {
  318. int idx = Convert.ToInt32(id);
  319. bool bActive = Acitve(idx);
  320. if (bActive)
  321. {
  322. if (state == STATE.IDLE)
  323. {
  324. if ((func != null) && !func())
  325. {
  326. return Tuple.Create(true, Result.FAIL);
  327. }
  328. timer.Start(time);
  329. state = STATE.WAIT;
  330. }
  331. if (timer.IsTimeout())
  332. {
  333. next();
  334. }
  335. return Tuple.Create(true, Result.RUN);
  336. }
  337. return Tuple.Create(false, Result.RUN);
  338. }
  339. //先delay 再运行
  340. public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)
  341. {
  342. int idx = Convert.ToInt32(id);
  343. bool bActive = Acitve(idx);
  344. if (bActive)
  345. {
  346. if (state == STATE.IDLE)
  347. {
  348. timer.Start(time);
  349. state = STATE.WAIT;
  350. }
  351. if (timer.IsTimeout())
  352. {
  353. if (func != null && !func())
  354. {
  355. return Tuple.Create(true, Result.FAIL);
  356. }
  357. next();
  358. }
  359. return Tuple.Create(true, Result.RUN);
  360. }
  361. return Tuple.Create(false, Result.RUN);
  362. }
  363. #endregion
  364. private Tuple<bool,bool> execute(int id, Func<bool> func) //顺序执行
  365. {
  366. bool bActive = Acitve(id);
  367. bool bExecute = false;
  368. if (bActive)
  369. {
  370. bExecute = func();
  371. if (bExecute)
  372. {
  373. next();
  374. }
  375. }
  376. return Tuple.Create(bActive, bExecute);
  377. }
  378. private Tuple<bool, bool> Check(int id, Func<bool> func) //check
  379. {
  380. bool bActive = Acitve(id);
  381. bool bExecute = false;
  382. if (bActive)
  383. {
  384. bExecute = func();
  385. next();
  386. }
  387. return Tuple.Create(bActive, bExecute);
  388. }
  389. /// <summary>
  390. /// </summary>
  391. /// <param name="id"></param>
  392. /// <param name="func"></param>
  393. /// <param name="timeout"></param>
  394. /// <returns>
  395. /// item1 Active
  396. /// item2 execute
  397. /// item3 Timeout
  398. ///</returns>
  399. private Tuple<bool,bool, bool> wait(int id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  400. {
  401. bool bActive = Acitve(id);
  402. bool bExecute = false;
  403. bool bTimeout = false;
  404. if (bActive)
  405. {
  406. if (state == STATE.IDLE)
  407. {
  408. timer.Start(timeout);
  409. state = STATE.WAIT;
  410. }
  411. bExecute = func();
  412. if (bExecute)
  413. {
  414. next();
  415. }
  416. bTimeout = timer.IsTimeout();
  417. }
  418. return Tuple.Create(bActive, bExecute, bTimeout);
  419. }
  420. private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition && Check error
  421. {
  422. bool bActive = Acitve(id);
  423. bool? bExecute = false;
  424. bool bTimeout = false;
  425. if (bActive)
  426. {
  427. if (state == STATE.IDLE)
  428. {
  429. timer.Start(timeout);
  430. state = STATE.WAIT;
  431. }
  432. bExecute = func();
  433. if (bExecute.HasValue && bExecute.Value)
  434. {
  435. next();
  436. }
  437. bTimeout = timer.IsTimeout();
  438. }
  439. return Tuple.Create(bActive, bExecute, bTimeout);
  440. }
  441. /// <summary>
  442. /// </summary>
  443. /// <param name="value"></param>
  444. /// <returns>
  445. /// item1 true, return item2
  446. /// </returns>
  447. private Tuple<bool,Result> Check(Tuple<bool, bool> value)
  448. {
  449. if (value.Item1)
  450. {
  451. if (!value.Item2)
  452. {
  453. return Tuple.Create(true, Result.FAIL);
  454. }
  455. return Tuple.Create(true, Result.RUN);
  456. }
  457. return Tuple.Create(false, Result.RUN);
  458. }
  459. private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)
  460. {
  461. if (value.Item1) // 当前执行
  462. {
  463. if (CheckTimeout(value)) //timeout
  464. {
  465. return Tuple.Create(true, Result.TIMEOUT);
  466. }
  467. return Tuple.Create(true, Result.RUN);
  468. }
  469. return Tuple.Create(false, Result.RUN);
  470. }
  471. private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)
  472. {
  473. if (value.Item1) // 当前执行
  474. {
  475. if (value.Item2 == null)
  476. {
  477. return Tuple.Create(true, Result.FAIL);
  478. }
  479. else
  480. {
  481. if (value.Item2 == false && value.Item3 == true) //timeout
  482. {
  483. return Tuple.Create(true, Result.TIMEOUT);
  484. }
  485. return Tuple.Create(true, Result.RUN);
  486. }
  487. }
  488. return Tuple.Create(false, Result.RUN);
  489. }
  490. private bool CheckTimeout(Tuple<bool, bool, bool> value)
  491. {
  492. return value.Item1 == true && value.Item2 == false && value.Item3 == true;
  493. }
  494. private bool Acitve(int id) //
  495. {
  496. if (_steps.Contains(id))
  497. return false;
  498. this._id = id;
  499. return true;
  500. }
  501. private void next()
  502. {
  503. _steps.Push(this._id);
  504. state = STATE.IDLE;
  505. }
  506. private void next(int step) //loop
  507. {
  508. while(_steps.Pop() != step);
  509. state = STATE.IDLE;
  510. }
  511. public void Delay(int id, double delaySeconds)
  512. {
  513. Tuple<bool, Result> ret = Delay(id, () =>
  514. {
  515. return true;
  516. }, delaySeconds * 1000);
  517. if (ret.Item1)
  518. {
  519. if (ret.Item2 == Result.RUN)
  520. {
  521. throw (new RoutineBreakException());
  522. }
  523. }
  524. }
  525. }
  526. public class ModuleRoutine : SeqenecRoutine
  527. {
  528. public string Module { get; set; }
  529. public string Name { get; set; }
  530. public delegate RoutineState RoutineFunc<T>(T arg);
  531. protected void Notify(string message)
  532. {
  533. EV.PostInfoLog(Module, $"[{Name}] routine, {message}");
  534. }
  535. protected void Stop(string failReason)
  536. {
  537. EV.PostAlarmLog(Module, $"[{Name}] routine failed, {failReason}");
  538. }
  539. public void TimeDelay(int id, double time)
  540. {
  541. Tuple<bool, Result> ret = Delay(id, () =>
  542. {
  543. Notify($"Delay {time} seconds");
  544. return true;
  545. }, time * 1000);
  546. if (ret.Item1)
  547. {
  548. if (ret.Item2 == Result.RUN)
  549. {
  550. throw (new RoutineBreakException());
  551. }
  552. }
  553. }
  554. protected void ExecuteRoutine(int id, IRoutine routine)
  555. {
  556. Tuple<bool, Result> ret = ExecuteAndWait(id, routine);
  557. if (ret.Item1)
  558. {
  559. if (ret.Item2 == Result.FAIL)
  560. {
  561. throw (new RoutineFaildException());
  562. }
  563. else if (ret.Item2 == Result.RUN)
  564. {
  565. throw (new RoutineBreakException());
  566. }
  567. }
  568. }
  569. protected void PerformStep<T, T1>(T step, RoutineFunc<T1> func, T1 param1)
  570. {
  571. int idx = Convert.ToInt32(step);
  572. RoutineState state = func(param1);
  573. }
  574. }
  575. public class QueueRoutine
  576. {
  577. private Queue< IRoutine > _steps = new Queue< IRoutine >();
  578. private IRoutine _currentStep = null;
  579. public void Add(IRoutine step)
  580. {
  581. _steps.Enqueue(step);
  582. }
  583. public void Reset()
  584. {
  585. _steps.Clear();
  586. _currentStep = null;
  587. }
  588. public void Abort()
  589. {
  590. if (_currentStep != null)
  591. _currentStep.Abort();
  592. Reset();
  593. }
  594. public Result Start(params object[] objs)
  595. {
  596. if (_steps.Count == 0)
  597. return Result.DONE;
  598. _currentStep = _steps.Dequeue();
  599. return _currentStep.Start(objs);
  600. }
  601. public Result Monitor(params object[] objs)
  602. {
  603. Result ret = Result.FAIL;
  604. if (_currentStep != null)
  605. {
  606. ret = _currentStep.Monitor();
  607. }
  608. if (ret == Result.DONE)
  609. {
  610. _currentStep = _steps.Count > 0 ? _steps.Dequeue() : null;
  611. if (_currentStep != null)
  612. {
  613. return _currentStep.Start(objs);
  614. }
  615. }
  616. return ret;
  617. }
  618. }
  619. }