RoutineRunner.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Diagnostics;
  5. using Aitex.Core.RT.Log;
  6. using MECF.Framework.Common.Equipment;
  7. using Venus_Core;
  8. namespace MECF.Framework.Common.Routine
  9. {
  10. public class RoutineRunner
  11. {
  12. public RState Status => _runnerState;
  13. private bool IsSubStepRunning(int id) => _runnerState == RState.Running && _subState == RState.Running && _curStep == id;
  14. private bool bAllowSubStepStart(int id) => _runnerState == RState.Running && _subState == RState.End && !_steps.Contains(id) && _isLoopMode == false;
  15. private bool bAllowLoopSubStepStart(int id) => _runnerState == RState.Running && _subState == RState.End && !_steps.Contains(id) && _isLoopMode;
  16. public int LoopCounter => _loopCounter;
  17. public long StepElapsedMS => _subStepTimer.ElapsedMilliseconds;
  18. private RState _subState = RState.Init;
  19. private Stack<int> _steps = new Stack<int>();
  20. private Stack<int> _loopSteps = new Stack<int>();
  21. private int _curStep = int.MaxValue;
  22. private RState _runnerState = RState.Init;
  23. private string _name;
  24. private string _loopName;
  25. private ModuleName _module;
  26. // 缺省最大超时 10 分钟, delay 5 秒
  27. private const int _defaultTimeout = 600000;
  28. private const int _defaultDelay = 5000;
  29. Stopwatch _subStepTimer = new Stopwatch();
  30. private bool _isLoopMode = false;
  31. private int _loopCounterSP = 0;
  32. private int _loopCounter = 0;
  33. public RoutineRunner()
  34. {
  35. _runnerState = RState.Init;
  36. }
  37. public void Reset()
  38. {
  39. _runnerState = RState.Init;
  40. _subState = RState.Init;
  41. _isLoopMode = false;
  42. _steps.Clear();
  43. _loopSteps.Clear();
  44. _subStepTimer.Reset();
  45. }
  46. public RState Start(ModuleName module, string name)
  47. {
  48. Reset();
  49. _module = module;
  50. _name = name;
  51. _runnerState = RState.Running;
  52. _subState = RState.End;
  53. Notify("开始");
  54. return _runnerState;
  55. }
  56. public void Stop(string reason)
  57. {
  58. Alarm(reason);
  59. _runnerState = _subState = RState.Failed;
  60. }
  61. public RoutineRunner Run(int id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  62. {
  63. if (bAllowSubStepStart(id))
  64. {
  65. startNewStep(id, action);
  66. }
  67. else if(IsSubStepRunning(id))
  68. {
  69. if (condition())
  70. {
  71. _subState = RState.End;
  72. }
  73. else if(_subStepTimer.ElapsedMilliseconds >= timeout)
  74. {
  75. Alarm($"Step:{id} 超时");
  76. _runnerState = _subState = RState.Timeout;
  77. _subStepTimer.Reset();
  78. }
  79. }
  80. return this;
  81. }
  82. public RoutineRunner Run(int id, Func<bool> action, int delayMS = _defaultDelay)
  83. {
  84. if (bAllowSubStepStart(id))
  85. {
  86. startNewStep(id, action);
  87. }
  88. else if (IsSubStepRunning(id))
  89. {
  90. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  91. {
  92. _subState = RState.End;
  93. }
  94. }
  95. return this;
  96. }
  97. public RoutineRunner End(int id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  98. {
  99. if (bAllowSubStepStart(id))
  100. {
  101. startNewStep(id, action);
  102. }
  103. else if (IsSubStepRunning(id))
  104. {
  105. if (condition())
  106. {
  107. Notify($"结束");
  108. _runnerState = RState.End;
  109. _subState = RState.End;
  110. }
  111. else
  112. {
  113. if (_subStepTimer.ElapsedMilliseconds > timeout)
  114. {
  115. Alarm($"Step:{id} 超时");
  116. _runnerState = RState.Failed;
  117. _subState = RState.Timeout;
  118. }
  119. }
  120. }
  121. return this;
  122. }
  123. public RoutineRunner End(int id, Func<bool> action, int delayMS = _defaultDelay)
  124. {
  125. if (bAllowSubStepStart(id))
  126. {
  127. startNewStep(id, action);
  128. }
  129. else if (IsSubStepRunning(id))
  130. {
  131. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  132. {
  133. Notify($"结束");
  134. _runnerState = RState.End;
  135. _subState = RState.End;
  136. }
  137. }
  138. return this;
  139. }
  140. public RoutineRunner Delay(int id, int delayMS = _defaultDelay)
  141. {
  142. return Run(id, () => { return true; }, delayMS);
  143. }
  144. public RoutineRunner Wait(int id, Func<bool> condition, int timeout = _defaultTimeout)
  145. {
  146. return Run(id, () => { return true; }, condition, timeout);
  147. }
  148. public RoutineRunner LoopStart(int id, string name, int cycleCount, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  149. {
  150. if(bAllowSubStepStart(id))
  151. {
  152. _loopName = name;
  153. _loopCounterSP = cycleCount;
  154. _loopCounter = 0;
  155. _isLoopMode = true;
  156. startNewLoopStep(id, action);
  157. }
  158. else if(bAllowLoopSubStepStart(id))
  159. {
  160. startNewLoopStep(id, action);
  161. }
  162. else if(IsSubStepRunning(id))
  163. {
  164. if (condition())
  165. {
  166. _subState = RState.End;
  167. }
  168. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  169. {
  170. Alarm($"Step:{id} 超时");
  171. _runnerState = _subState = RState.Timeout;
  172. _subStepTimer.Reset();
  173. }
  174. }
  175. return this;
  176. }
  177. public RoutineRunner LoopStart(int id, string name, int cycleCount, Func<bool> action, int delayMS = _defaultDelay)
  178. {
  179. if (bAllowSubStepStart(id))
  180. {
  181. _loopName = name;
  182. _loopCounterSP = cycleCount;
  183. _loopCounter = 0;
  184. _isLoopMode = true;
  185. startNewLoopStep(id, action);
  186. }
  187. else if (bAllowLoopSubStepStart(id))
  188. {
  189. startNewLoopStep(id, action);
  190. }
  191. else if (IsSubStepRunning(id))
  192. {
  193. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  194. {
  195. _subState = RState.End;
  196. }
  197. }
  198. return this;
  199. }
  200. public RoutineRunner LoopRun(int id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  201. {
  202. if (bAllowLoopSubStepStart(id))
  203. {
  204. startNewLoopStep(id, action);
  205. }
  206. else if (IsSubStepRunning(id))
  207. {
  208. if (condition())
  209. {
  210. _subState = RState.End;
  211. }
  212. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  213. {
  214. Alarm($"Step:{id} 超时");
  215. _runnerState = _subState = RState.Timeout;
  216. _subStepTimer.Reset();
  217. }
  218. }
  219. return this;
  220. }
  221. public RoutineRunner LoopRun(int id, Func<bool> action, int delayMS = _defaultDelay)
  222. {
  223. if (bAllowLoopSubStepStart(id))
  224. {
  225. startNewLoopStep(id, action);
  226. }
  227. else if (IsSubStepRunning(id))
  228. {
  229. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  230. {
  231. _subState = RState.End;
  232. }
  233. }
  234. return this;
  235. }
  236. public RoutineRunner LoopEnd(int id, Func<bool> action, Func<bool> condition, int timeout = _defaultTimeout)
  237. {
  238. if (bAllowLoopSubStepStart(id))
  239. {
  240. startNewLoopStep(id, action);
  241. }
  242. else if (IsSubStepRunning(id))
  243. {
  244. if (condition())
  245. {
  246. Notify($"{_loopCounter + 1}th [{_loopName}] Loop End");
  247. _subState = RState.End;
  248. _loopCounter++;
  249. if (_loopCounter >= _loopCounterSP)
  250. {
  251. foreach (var lid in _loopSteps)
  252. _steps.Push(lid);
  253. _loopSteps.Clear();
  254. _isLoopMode = false;
  255. }
  256. }
  257. else if (_subStepTimer.ElapsedMilliseconds >= timeout)
  258. {
  259. Alarm($"Step:{id} 超时");
  260. _runnerState = _subState = RState.Timeout;
  261. _subStepTimer.Reset();
  262. }
  263. }
  264. return this;
  265. }
  266. public RoutineRunner LoopEnd(int id, Func<bool> action, int delayMS = _defaultDelay)
  267. {
  268. if (bAllowLoopSubStepStart(id))
  269. {
  270. startNewLoopStep(id, action);
  271. }
  272. else if (IsSubStepRunning(id))
  273. {
  274. if (_subStepTimer.ElapsedMilliseconds > delayMS)
  275. {
  276. Notify($"{_loopCounter + 1}th [{_loopName}] Loop End");
  277. _subState = RState.End;
  278. _loopCounter++;
  279. if (_loopCounter >= _loopCounterSP)
  280. {
  281. foreach (var lid in _loopSteps)
  282. _steps.Push(lid);
  283. _loopSteps.Clear();
  284. _isLoopMode = false;
  285. }
  286. }
  287. }
  288. return this;
  289. }
  290. public RoutineRunner LoopDelay(int id, int delayMS)
  291. {
  292. return LoopRun(id, () => { return true; }, delayMS);
  293. }
  294. public RoutineRunner LoopWait(int id, Func<bool> condition, int timeout = _defaultTimeout)
  295. {
  296. return LoopRun(id, () => { return true; }, condition, timeout);
  297. }
  298. private void startNewStep(int id, Func<bool> action)
  299. {
  300. if (action())
  301. {
  302. Notify($"Step: {id} start ---");
  303. _steps.Push(id);
  304. _curStep = id;
  305. _subState = RState.Running;
  306. _subStepTimer.Restart();
  307. }
  308. else
  309. {
  310. Alarm($"Step: {id} failed ");
  311. _runnerState = RState.Failed;
  312. }
  313. }
  314. private void startNewLoopStep(int id, Func<bool> action)
  315. {
  316. if (action())
  317. {
  318. Notify($"{_loopCounter + 1}th [{_loopName}] Loop Step: {id} start ---");
  319. if (!_loopSteps.Contains(id))
  320. _loopSteps.Push(id);
  321. _curStep = id;
  322. _subState = RState.Running;
  323. _subStepTimer.Restart();
  324. }
  325. else
  326. {
  327. Alarm($"{_loopCounter + 1}th [{_loopName}] Loop Step: {id} failed");
  328. _runnerState = RState.Failed;
  329. }
  330. }
  331. protected void Notify(string message)
  332. {
  333. LOG.Write(eEvent.EV_ROUTINE_NOTIFY, _module, _name, message);
  334. }
  335. protected void Alarm(string message)
  336. {
  337. LOG.Write(eEvent.ERR_ROUTINE_FAILED, _module, _name, message);
  338. }
  339. }
  340. static public class HOFs
  341. {
  342. public static Func<R> Apply<T1, R>(this Func<T1, R> func, T1 t1)
  343. => () => func(t1);
  344. public static Func<R> Apply<T1, T2, R>(this Func<T1, T2, R> func, T1 t1, T2 t2)
  345. => () => func(t1, t2);
  346. public static Func<R> Apply<T1, T2, T3, R>(this Func<T1, T2, T3, R> func, T1 t1, T2 t2, T3 t3)
  347. => () => func(t1, t2, t3);
  348. public static Func<bool> WrapAction(this Action action)
  349. => () => { action(); return true; };
  350. public static Func<bool> WrapAction<T1>(this Action<T1> action, T1 t1)
  351. => () => { action(t1); return true; };
  352. public static Func<bool> WrapAction<T1, T2>(this Action<T1, T2> action, T1 t1, T2 t2)
  353. => () => { action(t1, t2); return true; };
  354. public static Func<bool> WrapAction<T1, T2, T3>(this Action<T1, T2, T3> action, T1 t1, T2 t2, T3 t3)
  355. => () => { action(t1, t2, t3); return true; };
  356. }
  357. }