TDKBLoadPortXss.cs 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Device.Unit;
  5. using Aitex.Core.RT.Event;
  6. using Aitex.Core.RT.Log;
  7. using Aitex.Core.RT.Routine;
  8. using Aitex.Core.RT.SCCore;
  9. using Aitex.Core.Util;
  10. using Aitex.Sorter.Common;
  11. using MECF.Framework.Common.Communications;
  12. using MECF.Framework.Common.Equipment;
  13. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.CarrierIdReaders.CarrierIDReaderBase;
  14. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  15. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK;
  16. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.IO.Ports;
  20. using System.Linq;
  21. using System.Text;
  22. using System.Threading;
  23. using System.Threading.Tasks;
  24. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDKB
  25. {
  26. public class TDKBLoadPortXss : TDKBLoadPort
  27. {
  28. public TDKBLoadPortXss(string module, string name, string scRoot, IoTrigger[] dos = null, IoSensor[] dis = null, RobotBaseDevice robot = null, bool IsTCPconnection = false, IE84CallBack e84 = null) :
  29. base(module, name, scRoot, dos, dis,robot, false, e84)
  30. {
  31. }
  32. protected override bool fStartInit(object[] param)
  33. {
  34. if (MapRobot == null || MapRobot.RobotState != Robots.RobotStateEnum.Idle)
  35. {
  36. EV.PostAlarmLog(Name, $"Robot is not ready,can't home.");
  37. return false;
  38. }
  39. IsBusy = false;
  40. ResetRoutine();
  41. return true;
  42. }
  43. protected override bool fMonitorInit(object[] param)
  44. {
  45. RobotHome((int)LpStepEnum.Step1, TimelimitAction, OnError);
  46. if (ExecuteResult.Item1)
  47. {
  48. return false;
  49. }
  50. WaitRobotReady((int)LpStepEnum.Step2, TimelimitAction, OnError);
  51. if (ExecuteResult.Item1)
  52. {
  53. return false;
  54. }
  55. XssHome((int)LpStepEnum.Step3, TimelimitAction, OnError);
  56. if (ExecuteResult.Item1)
  57. {
  58. return false;
  59. }
  60. OnActionDone(null);
  61. return false;
  62. }
  63. protected override bool fStartLoad(object[] param)
  64. {
  65. if (MapRobot == null||MapRobot.RobotState == Robots.RobotStateEnum.Error
  66. || MapRobot.RobotState == Robots.RobotStateEnum.Init)
  67. {
  68. EV.PostAlarmLog(Name, $"Robot is not ready,can't load.");
  69. return false;
  70. }
  71. if (!_isPlaced)
  72. {
  73. EV.PostAlarmLog(Name, $"No carrier on {Name},can't load.");
  74. return false;
  75. }
  76. if (_isDocked)
  77. {
  78. EV.PostAlarmLog(Name, $"Carrier is docked on {Name},can't load.");
  79. return false;
  80. }
  81. ResetRoutine();
  82. _isNeedToWaitAnotherLPComplete = _anotherLP.CurrentState != LoadPortStateEnum.Error;
  83. return true;
  84. }
  85. private bool _isNeedToWaitAnotherLPComplete;
  86. private LoadPortBaseDevice _anotherLP
  87. {
  88. get
  89. {
  90. if(LPModuleName == ModuleName.LP1)
  91. {
  92. return DEVICE.GetDevice<LoadPortBaseDevice>("LP2");
  93. }
  94. if (LPModuleName == ModuleName.LP2)
  95. {
  96. return DEVICE.GetDevice<LoadPortBaseDevice>("LP1");
  97. }
  98. return null;
  99. }
  100. }
  101. protected override bool fMonitorLoad(object[] param)
  102. {
  103. IsBusy = false;
  104. WaitLoadPortReady((int)LpStepEnum.Step6, TimelimitAction,_anotherLP, OnError);
  105. if (ExecuteResult.Item1)
  106. {
  107. return false;
  108. }
  109. WaitRobotReady((int)LpStepEnum.Step1, TimelimitAction, OnError);
  110. if (ExecuteResult.Item1)
  111. {
  112. return false;
  113. }
  114. RobotHome((int)LpStepEnum.Step2, TimelimitAction, OnError);
  115. if (ExecuteResult.Item1)
  116. {
  117. return false;
  118. }
  119. WaitRobotReady((int)LpStepEnum.Step3, TimelimitAction, OnError);
  120. if (ExecuteResult.Item1)
  121. {
  122. return false;
  123. }
  124. XssLoad((int)LpStepEnum.Step4, TimelimitAction, OnError);
  125. if (ExecuteResult.Item1)
  126. {
  127. return false;
  128. }
  129. RobotMap((int)LpStepEnum.Step5, TimelimitAction, OnError);
  130. if (ExecuteResult.Item1)
  131. {
  132. return false;
  133. }
  134. OnActionDone(null);
  135. return false;
  136. }
  137. protected override bool fStartUnload(object[] param)
  138. {
  139. if (MapRobot == null || MapRobot.RobotState == Robots.RobotStateEnum.Error
  140. || MapRobot.RobotState == Robots.RobotStateEnum.Init)
  141. {
  142. EV.PostAlarmLog(Name, $"Robot is not ready,can't load.");
  143. return false;
  144. }
  145. if (!_isPlaced)
  146. {
  147. EV.PostAlarmLog(Name, $"No carrier on {Name},can't load.");
  148. return false;
  149. }
  150. if (!_isDocked)
  151. {
  152. EV.PostAlarmLog(Name, $"Carrier is undocked on {Name},can't load.");
  153. return false;
  154. }
  155. ResetRoutine();
  156. return true;
  157. }
  158. protected override bool fMonitorUnload(object[] param)
  159. {
  160. IsBusy = false;
  161. WaitLoadPortReady((int)LpStepEnum.Step1, TimelimitAction, _anotherLP, OnError);
  162. if (ExecuteResult.Item1)
  163. {
  164. return false;
  165. }
  166. WaitRobotReady((int)LpStepEnum.Step2, TimelimitAction, OnError);
  167. if (ExecuteResult.Item1)
  168. {
  169. return false;
  170. }
  171. RobotHome((int)LpStepEnum.Step3, TimelimitAction, OnError);
  172. if (ExecuteResult.Item1)
  173. {
  174. return false;
  175. }
  176. WaitRobotReady((int)LpStepEnum.Step4, TimelimitAction, OnError);
  177. if (ExecuteResult.Item1)
  178. {
  179. return false;
  180. }
  181. XssUnload((int)LpStepEnum.Step5, TimelimitAction, OnError);
  182. if (ExecuteResult.Item1)
  183. {
  184. return false;
  185. }
  186. _isMapped = false;
  187. OnActionDone(null);
  188. return false;
  189. }
  190. public void WaitLoadPortReady(int id, int time,LoadPortBaseDevice lp, Action<string> error)
  191. {
  192. var ret = ExecuteAndWait(id, () =>
  193. {
  194. EV.PostInfoLog("System", $"Wait {lp.LPModuleName} to be ready");
  195. return true;
  196. }, () =>
  197. {
  198. if (lp.IsReady())
  199. return Result.DONE;
  200. if (lp.CurrentState == LoadPortStateEnum.Error)
  201. return Result.DONE;
  202. return Result.RUN;
  203. }, time * 1000);
  204. if (ret.Item1)
  205. {
  206. if (ret.Item2 == Result.FAIL)
  207. error("Wait lp ready failed");
  208. if (ret.Item2 == Result.TIMEOUT) //timeout
  209. {
  210. error("Wait lp ready timeout");
  211. }
  212. }
  213. }
  214. public void WaitRobotReady(int id, int time, Action<string> error)
  215. {
  216. var ret = ExecuteAndWait(id, () =>
  217. {
  218. EV.PostInfoLog("System", $"Wait {MapRobot.RobotModuleName} to be ready");
  219. return true;
  220. }, () =>
  221. {
  222. if (MapRobot.IsReady())
  223. return Result.DONE;
  224. if (MapRobot.RobotState == Robots.RobotStateEnum.Error)
  225. return Result.FAIL;
  226. return Result.RUN;
  227. }, time * 1000);
  228. if (ret.Item1)
  229. {
  230. if (ret.Item2 == Result.FAIL)
  231. error("Wait robot ready failed");
  232. if (ret.Item2 == Result.TIMEOUT) //timeout
  233. {
  234. error("Wait robot ready timeout");
  235. }
  236. }
  237. }
  238. public void RobotHome(int id, int time, Action<string> error)
  239. {
  240. var ret = ExecuteAndWait(id, () =>
  241. {
  242. EV.PostInfoLog("System",$"{MapRobot.RobotModuleName} start homing");
  243. var reason = string.Empty;
  244. return MapRobot.HomeModule(null);
  245. }, () =>
  246. {
  247. if (MapRobot.IsReady())
  248. return Result.DONE;
  249. if (MapRobot.RobotState == Robots.RobotStateEnum.Error)
  250. return Result.FAIL;
  251. return Result.RUN;
  252. }, time * 1000);
  253. if (ret.Item1)
  254. {
  255. if (ret.Item2 == Result.FAIL)
  256. error("Map robot home failed");
  257. if (ret.Item2 == Result.TIMEOUT) //timeout
  258. {
  259. error("Map robot home timeout");
  260. }
  261. }
  262. }
  263. public void RobotMap(int id, int time,Action<string> error)
  264. {
  265. var ret = ExecuteAndWait(id, () =>
  266. {
  267. EV.PostInfoLog($"System",$"{MapRobot.RobotModuleName} start to map LP:{LPModuleName}");
  268. var reason = string.Empty;
  269. return MapRobot.WaferMapping(LPModuleName,out _);
  270. }, () =>
  271. {
  272. if (MapRobot.IsReady())
  273. return Result.DONE;
  274. if (MapRobot.RobotState == Robots.RobotStateEnum.Error)
  275. return Result.FAIL;
  276. return Result.RUN;
  277. }, time * 1000);
  278. if (ret.Item1)
  279. {
  280. if (ret.Item2 == Result.FAIL)
  281. error($"Robot map {LPModuleName} failed");
  282. if (ret.Item2 == Result.TIMEOUT) //timeout
  283. {
  284. error($"Robot map {LPModuleName} timeout");
  285. }
  286. }
  287. }
  288. public void XssLoad(int id, int time, Action<string> error)
  289. {
  290. var ret = ExecuteAndWait(id, () =>
  291. {
  292. EV.PostInfoLog($"System", $"Start to load LP:{LPModuleName}");
  293. var reason = string.Empty;
  294. return base.fStartLoad(null);
  295. }, () =>
  296. {
  297. if(!IsHandlerBusy)
  298. return Result.DONE;
  299. return Result.RUN;
  300. }, time * 1000);
  301. if (ret.Item1)
  302. {
  303. if (ret.Item2 == Result.FAIL)
  304. error($"{LPModuleName} load failed");
  305. if (ret.Item2 == Result.TIMEOUT) //timeout
  306. {
  307. error($"{LPModuleName} load timeout");
  308. }
  309. }
  310. }
  311. public void XssUnload(int id, int time, Action<string> error)
  312. {
  313. var ret = ExecuteAndWait(id, () =>
  314. {
  315. EV.PostInfoLog($"System", $"Start to unload LP:{LPModuleName}");
  316. var reason = string.Empty;
  317. return base.fStartUnload(null);
  318. }, () =>
  319. {
  320. if (!IsHandlerBusy)
  321. return Result.DONE;
  322. return Result.RUN;
  323. }, time * 1000);
  324. if (ret.Item1)
  325. {
  326. if (ret.Item2 == Result.FAIL)
  327. error($"{LPModuleName} unload failed");
  328. if (ret.Item2 == Result.TIMEOUT) //timeout
  329. {
  330. error($"{LPModuleName} unload timeout");
  331. }
  332. }
  333. }
  334. public void XssHome(int id, int time, Action<string> error)
  335. {
  336. var ret = ExecuteAndWait(id, () =>
  337. {
  338. EV.PostInfoLog($"System", $"Start to home LP:{LPModuleName}");
  339. var reason = string.Empty;
  340. return base.fStartInit(CurrentParamter);
  341. }, () =>
  342. {
  343. if (!IsHandlerBusy)
  344. return Result.DONE;
  345. return Result.RUN;
  346. }, time * 1000);
  347. if (ret.Item1)
  348. {
  349. if (ret.Item2 == Result.FAIL)
  350. error($"{LPModuleName} load failed");
  351. if (ret.Item2 == Result.TIMEOUT) //timeout
  352. {
  353. error($"{LPModuleName} load timeout");
  354. }
  355. }
  356. }
  357. public enum LpStepEnum
  358. {
  359. Step1,
  360. Step2,
  361. Step3,
  362. Step4,
  363. Step5,
  364. Step6,
  365. Step7,
  366. }
  367. protected DeviceTimer counter = new DeviceTimer();
  368. protected DeviceTimer delayTimer = new DeviceTimer();
  369. private enum STATE
  370. {
  371. IDLE,
  372. WAIT,
  373. }
  374. public int TokenId
  375. {
  376. get { return _id; }
  377. }
  378. private int _id; //step index
  379. private int _currentTokenId = -1;
  380. /// <summary>
  381. /// already done steps
  382. /// </summary>
  383. private Stack<int> _steps = new Stack<int>();
  384. private STATE state; //step state //idel,wait,
  385. //loop control
  386. private int loop = 0;
  387. private int loopCount = 0;
  388. private int loopID = 0;
  389. private DeviceTimer timer = new DeviceTimer();
  390. public int LoopCounter { get { return loop; } }
  391. public int LoopTotalTime { get { return loopCount; } }
  392. // public int Timeout { get { return (int)(timer.GetTotalTime() / 1000); } }
  393. //状态持续时间,单位为秒
  394. public int Elapsed { get { return (int)(timer.GetElapseTime() / 1000); } }
  395. protected RoutineResult RoutineToken = new RoutineResult() { Result = RoutineState.Running };
  396. protected Tuple<bool, Result> ExecuteResult;
  397. public void ResetRoutine()
  398. {
  399. _id = 0;
  400. _steps.Clear();
  401. loop = 0;
  402. loopCount = 0;
  403. state = STATE.IDLE;
  404. counter.Start(60 * 60 * 100); //默认1小时
  405. RoutineToken.Result = RoutineState.Running;
  406. _currentTokenId = -1;
  407. ExecuteResult = Tuple.Create(false, Result.DONE);
  408. }
  409. protected void PerformRoutineStep(int id, Func<RoutineState> execution, RoutineResult result)
  410. {
  411. if (!Acitve(id))
  412. return;
  413. result.Result = execution();
  414. }
  415. #region interface
  416. public void StopLoop()
  417. {
  418. loop = loopCount;
  419. }
  420. public Tuple<bool, Result> Loop<T>(T id, Func<bool> func, int count)
  421. {
  422. int idx = Convert.ToInt32(id);
  423. bool bActive = Acitve(idx);
  424. if (bActive)
  425. {
  426. if (!func())
  427. {
  428. return Tuple.Create(bActive, Result.FAIL); //执行错误
  429. }
  430. loopID = idx;
  431. loopCount = count;
  432. next();
  433. return Tuple.Create(true, Result.RUN);
  434. }
  435. return Tuple.Create(false, Result.RUN);
  436. }
  437. public Tuple<bool, Result> EndLoop<T>(T id, Func<bool> func)
  438. {
  439. int idx = Convert.ToInt32(id);
  440. bool bActive = Acitve(idx);
  441. if (bActive)
  442. {
  443. if (++loop >= loopCount) //Loop 结束
  444. {
  445. if (!func())
  446. {
  447. return Tuple.Create(bActive, Result.FAIL); //执行错误
  448. }
  449. loop = 0;
  450. loopCount = 0; // Loop 结束时,当前loop和loop总数都清零
  451. next();
  452. return Tuple.Create(true, Result.RUN);
  453. }
  454. //继续下一LOOP
  455. next(loopID);
  456. return Tuple.Create(true, Result.RUN);
  457. }
  458. return Tuple.Create(false, Result.RUN);
  459. }
  460. public Tuple<bool, Result> ExecuteAndWait<T>(T id, IRoutine routine)
  461. {
  462. int idx = Convert.ToInt32(id);
  463. bool bActive = Acitve(idx);
  464. if (bActive)
  465. {
  466. if (state == STATE.IDLE)
  467. {
  468. Result startRet = routine.Start();
  469. if (startRet == Result.FAIL)
  470. {
  471. return Tuple.Create(true, Result.FAIL); //执行错误
  472. }
  473. else if (startRet == Result.DONE)
  474. {
  475. next();
  476. return Tuple.Create(true, Result.DONE);
  477. }
  478. state = STATE.WAIT;
  479. }
  480. Result ret = routine.Monitor();
  481. if (ret == Result.DONE)
  482. {
  483. next();
  484. return Tuple.Create(true, Result.DONE);
  485. }
  486. else if (ret == Result.FAIL || ret == Result.TIMEOUT)
  487. {
  488. return Tuple.Create(true, Result.FAIL);
  489. }
  490. else
  491. {
  492. return Tuple.Create(true, Result.RUN);
  493. }
  494. }
  495. return Tuple.Create(false, Result.RUN);
  496. }
  497. public Tuple<bool, Result> ExecuteAndWait<T>(T id, List<IRoutine> routines)
  498. {
  499. int idx = Convert.ToInt32(id);
  500. bool bActive = Acitve(idx);
  501. if (bActive)
  502. {
  503. if (state == STATE.IDLE)
  504. {
  505. foreach (var item in routines)
  506. {
  507. if (item.Start() == Result.FAIL)
  508. return Tuple.Create(true, Result.FAIL);
  509. }
  510. state = STATE.WAIT;
  511. }
  512. //wait all sub failed or completedboo
  513. bool bFail = false;
  514. bool bDone = true;
  515. foreach (var item in routines)
  516. {
  517. Result ret = item.Monitor();
  518. bDone &= (ret == Result.FAIL || ret == Result.DONE);
  519. bFail |= ret == Result.FAIL;
  520. }
  521. if (bDone)
  522. {
  523. next();
  524. if (bFail)
  525. return Tuple.Create(true, Result.FAIL);
  526. return Tuple.Create(true, Result.DONE);
  527. }
  528. return Tuple.Create(true, Result.RUN);
  529. }
  530. return Tuple.Create(false, Result.RUN);
  531. }
  532. public Tuple<bool, Result> Check<T>(T id, Func<bool> func) //顺序执行
  533. {
  534. return Check(Check(Convert.ToInt32(id), func));
  535. }
  536. public Tuple<bool, Result> Execute<T>(T id, Func<bool> func) //顺序执行
  537. {
  538. return Check(execute(Convert.ToInt32(id), func));
  539. }
  540. public Tuple<bool, Result> Wait<T>(T id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  541. {
  542. return Check(wait(Convert.ToInt32(id), func, timeout));
  543. }
  544. public Tuple<bool, Result> Wait<T>(T id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition
  545. {
  546. return Check(wait(Convert.ToInt32(id), func, timeout));
  547. }
  548. public Tuple<bool, Result> ExecuteAndWait<T>(T id, Func<bool> execute, Func<Result?> check, double timeout = int.MaxValue)
  549. {
  550. int idx = Convert.ToInt32(id);
  551. bool bActive = Acitve(idx);
  552. Result? bExecute = Result.RUN;
  553. if (bActive)
  554. {
  555. //if (idx != _currentTokenId && ExecuteResult.Item1) return ExecuteResult;
  556. if (state == STATE.IDLE)
  557. {
  558. if (!execute())
  559. {
  560. ExecuteResult = Tuple.Create(bActive, Result.FAIL);
  561. return Tuple.Create(bActive, Result.FAIL); //执行错误
  562. }
  563. timer.Start(timeout);
  564. state = STATE.WAIT;
  565. _currentTokenId = idx;
  566. }
  567. bExecute = check();
  568. if (bExecute == null)
  569. {
  570. ExecuteResult = Tuple.Create(bActive, Result.FAIL);
  571. return Tuple.Create(bActive, Result.FAIL); //Termianate
  572. }
  573. else
  574. {
  575. if (bExecute == Result.DONE) //检查Success, next
  576. {
  577. next();
  578. ExecuteResult = Tuple.Create(true, Result.RUN);
  579. return Tuple.Create(true, Result.RUN);
  580. }
  581. if (bExecute == Result.Succeed) //检查Success, next
  582. {
  583. next();
  584. ExecuteResult = Tuple.Create(true, Result.RUN);
  585. return Tuple.Create(true, Result.RUN);
  586. }
  587. if (bExecute == Result.FAIL) //检查 Fail 直接返回Fail
  588. {
  589. ExecuteResult = Tuple.Create(true, Result.FAIL);
  590. return Tuple.Create(true, Result.FAIL);
  591. }
  592. }
  593. if (timer.IsTimeout())
  594. {
  595. ExecuteResult = Tuple.Create(true, Result.TIMEOUT);
  596. return Tuple.Create(true, Result.TIMEOUT);
  597. }
  598. ExecuteResult = Tuple.Create(true, Result.RUN);
  599. return Tuple.Create(true, Result.RUN);
  600. }
  601. ExecuteResult = Tuple.Create(false, Result.RUN);
  602. return Tuple.Create(false, Result.RUN);
  603. }
  604. public Tuple<bool, Result> Wait<T>(T id, IRoutine rt)
  605. {
  606. int idx = Convert.ToInt32(id);
  607. bool bActive = Acitve(idx);
  608. if (bActive)
  609. {
  610. if (state == STATE.IDLE)
  611. {
  612. rt.Start();
  613. state = STATE.WAIT;
  614. }
  615. Result ret = rt.Monitor();
  616. return Tuple.Create(true, ret);
  617. }
  618. return Tuple.Create(false, Result.RUN);
  619. }
  620. //Monitor
  621. public Tuple<bool, Result> Monitor<T>(T id, Func<bool> func, Func<bool> check, double time)
  622. {
  623. int idx = Convert.ToInt32(id);
  624. bool bActive = Acitve(idx);
  625. bool bCheck = false;
  626. if (bActive)
  627. {
  628. if (state == STATE.IDLE)
  629. {
  630. if ((func != null) && !func())
  631. {
  632. return Tuple.Create(true, Result.FAIL);
  633. }
  634. timer.Start(time);
  635. state = STATE.WAIT;
  636. }
  637. bCheck = check();
  638. if (!bCheck)
  639. {
  640. return Tuple.Create(true, Result.FAIL); //Termianate
  641. }
  642. if (timer.IsTimeout())
  643. {
  644. next();
  645. }
  646. return Tuple.Create(true, Result.RUN);
  647. }
  648. return Tuple.Create(false, Result.RUN);
  649. }
  650. //Delay
  651. public Tuple<bool, Result> Delay<T>(T id, Func<bool> func, double time)
  652. {
  653. int idx = Convert.ToInt32(id);
  654. bool bActive = Acitve(idx);
  655. if (bActive)
  656. {
  657. //if (_currentTokenId != idx && !ExecuteResult.Item1) return ExecuteResult;
  658. if (state == STATE.IDLE)
  659. {
  660. if ((func != null) && !func())
  661. {
  662. ExecuteResult = Tuple.Create(true, Result.FAIL);
  663. return Tuple.Create(true, Result.FAIL);
  664. }
  665. _currentTokenId = idx;
  666. timer.Start(time);
  667. state = STATE.WAIT;
  668. }
  669. if (timer.IsTimeout())
  670. {
  671. next();
  672. }
  673. ExecuteResult = Tuple.Create(true, Result.RUN);
  674. return Tuple.Create(true, Result.RUN);
  675. }
  676. ExecuteResult = Tuple.Create(false, Result.RUN);
  677. return Tuple.Create(false, Result.RUN);
  678. }
  679. //先delay 再运行
  680. public Tuple<bool, Result> DelayCheck<T>(T id, Func<bool> func, double time)
  681. {
  682. int idx = Convert.ToInt32(id);
  683. bool bActive = Acitve(idx);
  684. if (bActive)
  685. {
  686. if (state == STATE.IDLE)
  687. {
  688. timer.Start(time);
  689. state = STATE.WAIT;
  690. }
  691. if (timer.IsTimeout())
  692. {
  693. if (func != null && !func())
  694. {
  695. return Tuple.Create(true, Result.FAIL);
  696. }
  697. next();
  698. }
  699. return Tuple.Create(true, Result.RUN);
  700. }
  701. return Tuple.Create(false, Result.RUN);
  702. }
  703. #endregion
  704. private Tuple<bool, bool> execute(int id, Func<bool> func) //顺序执行
  705. {
  706. bool bActive = Acitve(id);
  707. bool bExecute = false;
  708. if (bActive)
  709. {
  710. //if (ExecuteResult.Item1) return Tuple.Create(true, true);
  711. bExecute = func();
  712. if (bExecute)
  713. {
  714. next();
  715. }
  716. }
  717. return Tuple.Create(bActive, bExecute);
  718. }
  719. private Tuple<bool, bool> Check(int id, Func<bool> func) //check
  720. {
  721. bool bActive = Acitve(id);
  722. bool bExecute = false;
  723. if (bActive)
  724. {
  725. if (ExecuteResult.Item1) return Tuple.Create(true, true);
  726. bExecute = func();
  727. next();
  728. }
  729. return Tuple.Create(bActive, bExecute);
  730. }
  731. /// <summary>
  732. /// </summary>
  733. /// <param name="id"></param>
  734. /// <param name="func"></param>
  735. /// <param name="timeout"></param>
  736. /// <returns>
  737. /// item1 Active
  738. /// item2 execute
  739. /// item3 Timeout
  740. ///</returns>
  741. private Tuple<bool, bool, bool> wait(int id, Func<bool> func, double timeout = int.MaxValue) //Wait condition
  742. {
  743. bool bActive = Acitve(id);
  744. bool bExecute = false;
  745. bool bTimeout = false;
  746. if (bActive)
  747. {
  748. if (state == STATE.IDLE)
  749. {
  750. timer.Start(timeout);
  751. state = STATE.WAIT;
  752. }
  753. bExecute = func();
  754. if (bExecute)
  755. {
  756. next();
  757. }
  758. bTimeout = timer.IsTimeout();
  759. }
  760. return Tuple.Create(bActive, bExecute, bTimeout);
  761. }
  762. private Tuple<bool, bool?, bool> wait(int id, Func<bool?> func, double timeout = int.MaxValue) //Wait condition && Check error
  763. {
  764. bool bActive = Acitve(id);
  765. bool? bExecute = false;
  766. bool bTimeout = false;
  767. if (bActive)
  768. {
  769. if (state == STATE.IDLE)
  770. {
  771. timer.Start(timeout);
  772. state = STATE.WAIT;
  773. }
  774. bExecute = func();
  775. if (bExecute.HasValue && bExecute.Value)
  776. {
  777. next();
  778. }
  779. bTimeout = timer.IsTimeout();
  780. }
  781. return Tuple.Create(bActive, bExecute, bTimeout);
  782. }
  783. /// <summary>
  784. /// </summary>
  785. /// <param name="value"></param>
  786. /// <returns>
  787. /// item1 true, return item2
  788. /// </returns>
  789. private Tuple<bool, Result> Check(Tuple<bool, bool> value)
  790. {
  791. if (value.Item1)
  792. {
  793. if (!value.Item2)
  794. {
  795. ExecuteResult = Tuple.Create(true, Result.FAIL);
  796. return Tuple.Create(true, Result.FAIL);
  797. }
  798. ExecuteResult = Tuple.Create(true, Result.RUN);
  799. return Tuple.Create(true, Result.RUN);
  800. }
  801. ExecuteResult = Tuple.Create(false, Result.RUN);
  802. return Tuple.Create(false, Result.RUN);
  803. }
  804. private Tuple<bool, Result> Check(Tuple<bool, bool, bool> value)
  805. {
  806. if (value.Item1) // 当前执行
  807. {
  808. if (CheckTimeout(value)) //timeout
  809. {
  810. return Tuple.Create(true, Result.TIMEOUT);
  811. }
  812. return Tuple.Create(true, Result.RUN);
  813. }
  814. return Tuple.Create(false, Result.RUN);
  815. }
  816. private Tuple<bool, Result> Check(Tuple<bool, bool?, bool> value)
  817. {
  818. if (value.Item1) // 当前执行
  819. {
  820. if (value.Item2 == null)
  821. {
  822. return Tuple.Create(true, Result.FAIL);
  823. }
  824. else
  825. {
  826. if (value.Item2 == false && value.Item3 == true) //timeout
  827. {
  828. return Tuple.Create(true, Result.TIMEOUT);
  829. }
  830. return Tuple.Create(true, Result.RUN);
  831. }
  832. }
  833. return Tuple.Create(false, Result.RUN);
  834. }
  835. private bool CheckTimeout(Tuple<bool, bool, bool> value)
  836. {
  837. return value.Item1 == true && value.Item2 == false && value.Item3 == true;
  838. }
  839. private bool Acitve(int id) //
  840. {
  841. if (_steps.Contains(id))
  842. return false;
  843. this._id = id;
  844. return true;
  845. }
  846. private void next()
  847. {
  848. _steps.Push(this._id);
  849. state = STATE.IDLE;
  850. }
  851. private void next(int step) //loop
  852. {
  853. while (_steps.Pop() != step) ;
  854. state = STATE.IDLE;
  855. }
  856. public void Delay(int id, double delaySeconds)
  857. {
  858. Tuple<bool, Result> ret = Delay(id, () =>
  859. {
  860. return true;
  861. }, delaySeconds * 1000);
  862. if (ret.Item1)
  863. {
  864. if (ret.Item2 == Result.RUN)
  865. {
  866. }
  867. }
  868. }
  869. public bool IsActived(int id)
  870. {
  871. return _steps.Contains(id);
  872. }
  873. }
  874. }