JelBoffottEfem.cs 31 KB

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