TDKBLoadPortHhYx.cs 30 KB

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