NodeBase.cs 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Reflection;
  6. using IwbZero.IwbBase;
  7. using IwbZero.ToolCommon.LogHelpers;
  8. using IwbZero.ToolCommon.StringModel;
  9. using WeEngine.CommonDto;
  10. using WeEngine.Enum;
  11. namespace WeEngine.Packages
  12. {
  13. public abstract class NodeBase : IIwbId, IComparer<NodeBase>, ICloneable
  14. {
  15. #region 字段
  16. ///// <summary>
  17. ///// 实际权重得分
  18. ///// </summary>
  19. //private decimal _actualWeightScore;
  20. /// <summary>
  21. /// 节点状态
  22. /// </summary>
  23. private NodeState _nodeState;
  24. #endregion 字段
  25. #region 属性
  26. /// <summary>
  27. /// 父节点
  28. /// </summary>
  29. public NodeBase Parent { get; set; }
  30. /// <summary>
  31. /// 子节点
  32. /// </summary>
  33. public List<NodeBase> Children { get; set; }
  34. /// <summary>
  35. /// 唯一Id
  36. /// </summary>
  37. public string Id { get; set; }
  38. /// <summary>
  39. /// 方案包内部编号
  40. /// </summary>
  41. public string InternalNo { get; set; }
  42. /// <summary>
  43. /// 名称
  44. /// </summary>
  45. public string Name { get; set; }
  46. /// <summary>
  47. /// 节点类型
  48. /// </summary>
  49. public NodeType NodeType { get; set; }
  50. /// <summary>
  51. /// 扩展数据
  52. /// </summary>
  53. public dynamic ExtendData { get; set; }
  54. /// <summary>
  55. /// 节点状态
  56. /// </summary>
  57. public NodeState NodeState
  58. {
  59. get => _nodeState;
  60. set
  61. {
  62. if ( _nodeState != value)
  63. {
  64. var oldState = _nodeState;
  65. _nodeState = value;
  66. if (CurPackageInfo != null && !CurPackageInfo.EventSwitch)
  67. {
  68. return;
  69. }
  70. if (_nodeState != NodeState.New)
  71. {
  72. EvNodeStateChanged?.Invoke(this, oldState);
  73. }
  74. }
  75. }
  76. }
  77. /// <summary>
  78. /// 矫正评分
  79. /// </summary>
  80. public decimal CorrectionScore { get; set; }
  81. /// <summary>
  82. /// 权重(在父节点中的占比)
  83. /// </summary>
  84. public virtual decimal Weights { get; set; }
  85. /// <summary>
  86. /// 运行前事务(Id|Mapping)
  87. /// </summary>
  88. public string PreComponent { get; set; }
  89. /// <summary>
  90. /// 运行时事务(Id|Mapping)
  91. /// </summary>
  92. public string RunningComponent { get; set; }
  93. /// <summary>
  94. /// 运行结束时事务(Id|Mapping)
  95. /// </summary>
  96. public string RunnedComponent { get; set; }
  97. /// <summary>
  98. /// 运行后事务(Id|Mapping)
  99. /// </summary>
  100. public string PostComponent { get; set; }
  101. public List<GuideNode> GuideInfos { get; set; }
  102. public string GuideNos { get; set; }
  103. /// <summary>
  104. /// 实际节点评分
  105. /// </summary>
  106. public decimal ActualScore => GetActualScore();
  107. /// <summary>
  108. /// 节点满分
  109. /// </summary>
  110. public decimal NodeFullScore => GetNodeFullScore();
  111. /// <summary>
  112. /// 实际节点得分权重
  113. /// </summary>
  114. public decimal ActualWeights => GetActualWeights();
  115. /// <summary>
  116. /// 子权重和
  117. /// </summary>
  118. public decimal ChildFullWeights => GetChildFullWeights();
  119. /// <summary>
  120. /// 当前方案包
  121. /// </summary>
  122. public PackageNode CurPackageInfo => GetCurrentPackage();
  123. /// <summary>
  124. /// 节点深度
  125. /// </summary>
  126. public int NodeDepth => GetNodeDepth();
  127. /// <summary>
  128. /// 节点路径
  129. /// </summary>
  130. public string NodePath => GetNodePath();
  131. /// <summary>
  132. /// 是否有父节点
  133. /// </summary>
  134. public bool HasParent => IsHasParent();
  135. /// <summary>
  136. /// 是否有子节点
  137. /// </summary>
  138. public bool HasChild => IsHasChild();
  139. /// <summary>
  140. /// XML对象
  141. /// </summary>
  142. public IwbXmlNode XmlNode { get; set; }
  143. ///// <summary>
  144. ///// 是否等待其他节点
  145. ///// </summary>
  146. //public bool IsWait { get; set; }
  147. /// <summary>
  148. /// 局部变量
  149. /// </summary>
  150. public Hashtable Variables { get; set; }
  151. /// <summary>
  152. /// 验证合法性
  153. /// </summary>
  154. public virtual bool IsValid => Id != "" && Name != "";
  155. /// <summary>
  156. /// 是否等待
  157. /// </summary>
  158. public bool IsWait => WaitPath?.Any() ?? false;
  159. public List<string> WaitPath { get; set; }
  160. public bool ChildIsRunning => CheckChildIsRunning();
  161. public int AllChildrenCount { get; set; }
  162. #endregion 属性
  163. #region 构造函数
  164. protected NodeBase()
  165. {
  166. AllChildrenCount = 0;
  167. WaitPath = new List<string>();
  168. Children = new List<NodeBase>();
  169. GuideInfos= new List<GuideNode>();
  170. Variables = new Hashtable();
  171. NodeState = NodeState.New;
  172. EvNodeStateChanged += EventStateChange;
  173. // ReSharper disable once VirtualMemberCallInConstructor
  174. BindEvents();
  175. }
  176. protected NodeBase(string id) : this()
  177. {
  178. Id = id;
  179. }
  180. protected NodeBase(string id, string name) : this(id)
  181. {
  182. Name = name;
  183. }
  184. protected NodeBase(IwbXmlNode xmlNode) : this()
  185. {
  186. XmlNode = xmlNode;
  187. CreateNodeByXmlNode(xmlNode);
  188. }
  189. protected NodeBase(RunningBase run)
  190. {
  191. }
  192. #endregion 构造函数
  193. #region Event
  194. /// <summary>
  195. /// 绑定事件
  196. /// </summary>
  197. public virtual void BindEvents()
  198. {
  199. if (EvPreCondition == null)
  200. {
  201. EvPreCondition += EventRunPre;
  202. }
  203. if (EvRunningCondition == null)
  204. {
  205. EvRunningCondition += EventRunning;
  206. }
  207. if (EvRunnedCondition == null)
  208. {
  209. EvRunnedCondition += EventRunned;
  210. }
  211. if (EvPostCondition == null)
  212. {
  213. EvPostCondition += EventRunPost;
  214. }
  215. }
  216. #region 运行前事件
  217. /// <summary>
  218. /// 运行前条件验证
  219. /// </summary>
  220. public bool PreConditionValidated { get; set; }
  221. /// <summary>
  222. /// 无需验证(随机选的情景块不需要验证)
  223. /// </summary>
  224. public bool NotValidated { get; set; }
  225. /// <summary>
  226. /// 运行前事件
  227. /// </summary>
  228. public event EvPreCondition EvPreCondition;
  229. /// <summary>
  230. /// 执行运行前事件
  231. /// </summary>
  232. /// <param name="node"></param>
  233. protected virtual void ExecutePreCondition(NodeBase node)
  234. {
  235. PreConditionValidated = true;
  236. EvPreCondition?.Invoke(node);
  237. }
  238. protected virtual void EventRunPre(NodeBase node)
  239. {
  240. node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.PreEvent);
  241. }
  242. #endregion 运行前
  243. #region 运行时事件
  244. /// <summary>
  245. /// 运行时事件
  246. /// </summary>
  247. public event EvRunningCondition EvRunningCondition;
  248. /// <summary>
  249. /// 执行运行时事件
  250. /// </summary>
  251. /// <param name="node"></param>
  252. protected virtual void ExecuteRunningCondition(NodeBase node)
  253. {
  254. EvRunningCondition?.Invoke(node);
  255. }
  256. protected virtual void EventRunning(NodeBase node)
  257. {
  258. node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.RunningEvent);
  259. }
  260. #endregion 运行时事件
  261. #region 运行结束时事件
  262. /// <summary>
  263. /// 运行结束时事件
  264. /// </summary>
  265. public event EvRunnedCondition EvRunnedCondition;
  266. public bool RunnedConditionValidated { get; set; }
  267. /// <summary>
  268. /// 执行运行结束时事件
  269. /// </summary>
  270. /// <param name="node"></param>
  271. protected virtual void ExecuteRunnedCondition(NodeBase node)
  272. {
  273. RunnedConditionValidated = true;
  274. EvRunnedCondition?.Invoke(node);
  275. }
  276. protected virtual void EventRunned(NodeBase node)
  277. {
  278. node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.RunnedEvent);
  279. }
  280. #endregion 运行结束时事件
  281. #region 运行后事件
  282. /// <summary>
  283. /// 运行后条件验证
  284. /// </summary>
  285. public bool PostConditionValidated { get; set; }
  286. /// <summary>
  287. /// 运行后事件
  288. /// </summary>
  289. public event EvPostCondition EvPostCondition;
  290. /// <summary>
  291. /// 执行运行后事件
  292. /// </summary>
  293. /// <param name="node"></param>
  294. protected virtual void ExecutePostCondition(NodeBase node)
  295. {
  296. PostConditionValidated = true;
  297. EvPostCondition?.Invoke(node);
  298. }
  299. protected virtual void EventRunPost(NodeBase node)
  300. {
  301. node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.PostEvent);
  302. //if (HasChild)
  303. //{
  304. // foreach (var nodeBase in Children)
  305. // {
  306. // if (nodeBase.NodeState != NodeState.New)
  307. // {
  308. // nodeBase.NodeState = NodeState.Complete;
  309. // }
  310. // }
  311. //}
  312. }
  313. #endregion 运行后
  314. #region 节点变化
  315. public event EvNodeStateChanged EvNodeStateChanged;
  316. /// <summary>
  317. /// 节点状态变化触发事件
  318. /// </summary>
  319. /// <param name="node"></param>
  320. /// <param name="oldValue"></param>
  321. protected virtual void EventStateChange(NodeBase node, NodeState oldValue)
  322. {
  323. if (node.NodeState == NodeState.New)
  324. {
  325. return;
  326. }
  327. if (node.NodeState == NodeState.ReStart)
  328. {
  329. //重启后自动变更为运行状态
  330. node.NodeState = NodeState.Running;
  331. return;
  332. }
  333. switch (oldValue)
  334. {
  335. case NodeState.New:
  336. ExecutePreCondition(node);
  337. if (!node.NotValidated && !PreConditionValidated)
  338. {
  339. node.NodeState = NodeState.New;
  340. if (node.NodeType == NodeType.FlowNode || node.NodeType == NodeType.SceneFlowBlock)
  341. {
  342. node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.SelectNextNode);
  343. }
  344. return;
  345. }
  346. if (IsWait)
  347. {
  348. node.NodeState = NodeState.Wait;
  349. return;
  350. }
  351. NotValidated = false;
  352. if (node.NodeState == NodeState.Running)
  353. {
  354. typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【已启动】");
  355. ExecuteRunningCondition(node);
  356. }
  357. break;
  358. case NodeState.Wait:
  359. {
  360. if (node.NodeState == NodeState.Running)
  361. {
  362. typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【已启动】");
  363. ExecuteRunningCondition(node);
  364. }
  365. break;
  366. }
  367. case NodeState.Running:
  368. if (node.NodeState == NodeState.RunEnd)
  369. {
  370. ExecuteRunnedCondition(node);
  371. if (!RunnedConditionValidated)
  372. {
  373. node.NodeState = oldValue;
  374. return;
  375. }
  376. typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【已结束】");
  377. }
  378. else if (node.NodeState == NodeState.Complete)
  379. {
  380. typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【【已完成】】");
  381. ExecutePostCondition(node);
  382. }
  383. break;
  384. case NodeState.RunEnd:
  385. if (node.NodeState == NodeState.Complete)
  386. {
  387. ExecutePostCondition(node);
  388. typeof(NodeBase).LogDebug($"节点- [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] - 【【 已完成 】】");
  389. }
  390. break;
  391. case NodeState.ReStart:
  392. break;
  393. }
  394. }
  395. #endregion 节点变化
  396. #endregion Event
  397. #region Score
  398. /// <summary>
  399. /// 获取当前节点评分
  400. /// </summary>
  401. /// <returns></returns>
  402. protected virtual decimal GetActualScore()
  403. {
  404. var score= CurPackageInfo?.EvalManager?.Instance?.GetActualScore(this)??0;
  405. return score;
  406. }
  407. /// <summary>
  408. /// 获取当前节点评分
  409. /// </summary>
  410. /// <returns></returns>
  411. protected virtual decimal GetActualWeights()
  412. {
  413. var score = CurPackageInfo?.EvalManager?.Instance?.GetActualWeights(this)??0;
  414. return score;
  415. }
  416. /// <summary>
  417. /// 获取当前节点满分
  418. /// </summary>
  419. /// <returns></returns>
  420. protected virtual decimal GetNodeFullScore()
  421. {
  422. var score = CurPackageInfo?.EvalManager?.Instance?.GetNodeFullScore(this)??0;
  423. return score;
  424. }
  425. /// <summary>
  426. /// 获取子节点权重之和
  427. /// </summary>
  428. /// <returns></returns>
  429. protected virtual decimal GetChildFullWeights()
  430. {
  431. var score = CurPackageInfo?.EvalManager?.Instance?.GetChildFullWeights(this)??0;
  432. return score;
  433. }
  434. #endregion Score
  435. #region XML
  436. /// <summary>
  437. /// 转成XML
  438. /// </summary>
  439. /// <returns></returns>
  440. public virtual string ToXmlString()
  441. {
  442. string str = "";
  443. str += $"<Id>{Id}</Id>\r\n";
  444. str += $"<InternalNo>{InternalNo}</InternalNo>\r\n";
  445. str += $"<Name>{Name}</Name>\r\n";
  446. //str += $"<NodeType>{NodeType}</NodeType>\r\n";
  447. str += $"<NodeState>{NodeState}</NodeState>\r\n";
  448. str += Weights == 0 ? "" : $"<Weights>{Weights}</Weights>\r\n";
  449. str += ActualScore == 0 ? "" : $"<CurrentScore>{ActualScore}</CurrentScore>\r\n";
  450. str += CorrectionScore == 0 ? "" : $"<CorrectionScore>{CorrectionScore}</CorrectionScore>\r\n";
  451. if (Variables != null && Variables.Count > 0)
  452. {
  453. string vStr = "";
  454. foreach (DictionaryEntry entry in Variables)
  455. {
  456. var v = (IwbRtVariable) entry.Value;
  457. vStr += (vStr == "" ? "" : ",") + $"[{v.VarName}:{v.DataType.TypeString}:{v.GetStringValue()}]";
  458. }
  459. if (vStr.IsNotEmpty())
  460. {
  461. str += $"<Variables>{vStr}</Variables>";
  462. }
  463. }
  464. str += GuideNos.IsEmpty() ? "" : $"<GuideNos>{GuideNos}</GuideNos>\r\n";
  465. var str1 = "";
  466. str1 += PreComponent.IsEmpty() ? "" : $"<PreComponent>{PreComponent}</PreComponent>\r\n";
  467. str1 += RunningComponent.IsEmpty() ? "" : $"<RunningComponent>{RunningComponent}</RunningComponent>\r\n";
  468. str1 += RunnedComponent.IsEmpty() ? "" : $"<RunnedComponent>{RunnedComponent}</RunnedComponent>\r\n";
  469. str1 += PostComponent.IsEmpty() ? "" : $"<PostComponent>{PostComponent}</PostComponent>\r\n";
  470. if (str1.IsNotEmpty())
  471. {
  472. str += "<Components>\r\n";
  473. str += str1;
  474. str += "</Components>\r\n";
  475. }
  476. return str;
  477. }
  478. /// <summary>
  479. /// 从XML对象中创建Node对象的值
  480. /// </summary>
  481. public NodeBase CreateNodeByXmlNode(IwbXmlNode xmlNode)
  482. {
  483. XmlNode = xmlNode;
  484. if (xmlNode != null)
  485. {
  486. Id = xmlNode.GetChildValue("Id");
  487. InternalNo = xmlNode.GetChildValue("InternalNo");
  488. Name = xmlNode.GetChildValue("Name");
  489. NodeState = xmlNode.GetChildValue("NodeState")?.GetEnumByName<NodeState>() ?? NodeState.New;
  490. Weights = xmlNode.GetChildValue("Weights").ValD();
  491. Weights = Weights <= 0 ? 100 : Weights;
  492. CorrectionScore = xmlNode.GetChildValue("CorrectionScore").ValD();
  493. GuideNos = xmlNode.GetChildValue("GuideNos");
  494. GuideInfos = CreateGuideByNos(GuideNos);
  495. var variables = xmlNode.GetChildValue("Variables").StrToArray();
  496. if (variables.Length > 0)
  497. {
  498. foreach (var v in variables)
  499. {
  500. var arr = v.StrToArray(":");
  501. string id = "";
  502. if (arr.Length > 0)
  503. {
  504. id = arr[0].UAndT();
  505. }
  506. if (id.IsNotEmpty())
  507. {
  508. Variables[id] = IwbRtVariable.Str2Variable(v);
  509. }
  510. }
  511. }
  512. var componentNode = xmlNode.GetChildNode("Components");
  513. if (componentNode != null)
  514. {
  515. PreComponent = componentNode.GetChildValue("PreComponent");
  516. RunningComponent = componentNode.GetChildValue("RunningComponent");
  517. RunnedComponent = componentNode.GetChildValue("RunnedComponent");
  518. PostComponent = componentNode.GetChildValue("PostComponent");
  519. }
  520. CreateSelfNode(xmlNode);
  521. }
  522. return this;
  523. }
  524. private List<GuideNode> CreateGuideByNos(string guideNos)
  525. {
  526. var list = new List<GuideNode>();
  527. var xmlNode = PackageHelper.GetGuidesXmlFromFile(CurPackageInfo?.Id, guideNos);
  528. if (xmlNode != null && xmlNode.Nodes.Count>0)
  529. {
  530. foreach (IwbXmlNode child in xmlNode.Nodes)
  531. {
  532. list.Add(new GuideNode().CreateNodeByXmlNode(child));
  533. }
  534. }
  535. return list;
  536. }
  537. //private GuideInfo CreateGuideByXml(XmlNode xmlNode)
  538. //{
  539. // var guide= new GuideInfo();
  540. // if (xmlNode != null)
  541. // {
  542. // guide.Id = xmlNode.Attributes?["path"] != null ? xmlNode.Attributes["path"].Value : "";
  543. // if (xmlNode.HasChildNodes)
  544. // {
  545. // foreach (XmlNode node in xmlNode.ChildNodes)
  546. // {
  547. // switch (node.Name.Trim())
  548. // {
  549. // case "Name":
  550. // guide.Name = node.FirstChild?.Value;
  551. // break;
  552. // case "Description":
  553. // guide.Description = node.FirstChild?.Value;
  554. // break;
  555. // case "IsPush":
  556. // guide.IsPush = node.FirstChild.Value.ValB();
  557. // break;
  558. // }
  559. // }
  560. // }
  561. // }
  562. // return guide;
  563. //}
  564. /// <summary>
  565. /// 创建自己属性值的时候必须继承,获取属性值的节点对象
  566. /// </summary>
  567. /// <param name="xmlNode"></param>
  568. protected virtual void CreateSelfNode(IwbXmlNode xmlNode)
  569. {
  570. }
  571. protected string ConvertXml(string str,bool isEscape=false)
  572. {
  573. if (isEscape)
  574. {
  575. str = str.Replace("&","&amp;");
  576. str = str.Replace("<","&lt;");
  577. str = str.Replace(">","&gt;");
  578. str = str.Replace("\"","&quot;");
  579. str = str.Replace("'","&apos;");
  580. }
  581. else
  582. {
  583. str = str.Replace("&amp;", "&");
  584. str = str.Replace("&lt;", "<");
  585. str = str.Replace("&gt;", ">");
  586. str = str.Replace("&quot;", "\"");
  587. str = str.Replace("&apos;", "'");
  588. }
  589. return str;
  590. }
  591. #endregion XML
  592. #region Virtual Method
  593. protected NodeState GetNodeState(RunningBase running)
  594. {
  595. return running.IsEnd? NodeState.RunEnd: running.IsStart? NodeState.Running: NodeState.New;
  596. }
  597. /// <summary>
  598. /// 获取变量
  599. /// </summary>
  600. /// <returns></returns>
  601. public virtual Hashtable GetVariables()
  602. {
  603. var variables = (Hashtable)Variables.Clone();
  604. if (HasParent)
  605. {
  606. variables = Parent.GetVariables().MergeHashtable(variables);
  607. }
  608. return variables;
  609. }
  610. /// <summary>
  611. /// 获取变量
  612. /// </summary>
  613. /// <returns></returns>
  614. public virtual Hashtable GetSelfVariables()
  615. {
  616. var variables = GetVariables();
  617. var newVariables = new Hashtable();
  618. foreach (DictionaryEntry entry in variables)
  619. {
  620. if (!DefaultVariable.VariableNames.Contains(entry.Key))
  621. {
  622. newVariables.Add(entry.Key, entry.Value);
  623. }
  624. }
  625. return newVariables;
  626. }
  627. public virtual void SetPreVariables()
  628. {
  629. SetVariable(DefaultVariable.FullNodeScore, NodeFullScore);
  630. SetVariable(DefaultVariable.Path, NodePath);
  631. SetVariable(DefaultVariable.RunValidate, "true");
  632. }
  633. public virtual void SetRunnedVariables()
  634. {
  635. //SetVariable(DefaultVariable.PrevNodeScore, ActualScore);
  636. }
  637. /// <summary>
  638. /// 添加变量
  639. /// </summary>
  640. /// <returns></returns>
  641. public void SetVariable(string key,string value)
  642. {
  643. SetVariable(key, new IwbRtVariable(key).SetValue(value));
  644. }
  645. /// <summary>
  646. /// 添加变量
  647. /// </summary>
  648. /// <returns></returns>
  649. public void SetVariable(string key,int? value)
  650. {
  651. SetVariable(key, new IwbRtVariable(key, "int").SetValue(value));
  652. }
  653. /// <summary>
  654. /// 添加变量
  655. /// </summary>
  656. /// <returns></returns>
  657. public void SetVariable(string key,decimal? value)
  658. {
  659. SetVariable(key, new IwbRtVariable(key, "decimal").SetValue(value));
  660. }
  661. /// <summary>
  662. /// 添加变量
  663. /// </summary>
  664. /// <returns></returns>
  665. public void SetVariable(string key,IwbRtVariable variable)
  666. {
  667. if (Variables.ContainsKey(key))
  668. {
  669. Variables[key] = variable;
  670. }
  671. else
  672. {
  673. Variables.Add(key,variable);
  674. }
  675. }
  676. ///// <summary>
  677. ///// 添加变量
  678. ///// </summary>
  679. ///// <returns></returns>
  680. //public void SetVariable( Dictionary<string,object> dic)
  681. //{
  682. // foreach (var d in dic)
  683. // {
  684. // SetVariable(d.Key,d.Value);
  685. // }
  686. //}
  687. /// <summary>
  688. /// 获取百分制得分
  689. /// </summary>
  690. /// <returns></returns>
  691. public decimal ConvertScoreTo100()
  692. {
  693. return ConvertScoreByPer(100);
  694. }
  695. /// <summary>
  696. /// 获取指定分制的得分
  697. /// </summary>
  698. /// <returns></returns>
  699. public decimal ConvertScoreByPer(int maxScore)
  700. {
  701. if (maxScore <= 0)
  702. {
  703. throw new Exception("分制不能小于0!");
  704. }
  705. return NodeFullScore == 0 ? 0 : Math.Round(maxScore * ActualScore / NodeFullScore);
  706. }
  707. /// <summary>
  708. /// 获取当前Package
  709. /// </summary>
  710. /// <returns></returns>
  711. protected PackageNode GetCurrentPackage()
  712. {
  713. PackageNode curPackage = null;
  714. if (HasParent)
  715. {
  716. curPackage = Parent.GetCurrentPackage();
  717. }
  718. if (NodeType == NodeType.ScenePackage)
  719. {
  720. curPackage = (PackageNode) this;
  721. }
  722. return curPackage;
  723. }
  724. /// <summary>
  725. /// 根据Id查询节点
  726. /// </summary>
  727. /// <param name="path"></param>
  728. /// <returns></returns>
  729. public virtual NodeBase GetNodeByPath(string path)
  730. {
  731. return CurPackageInfo?.GetChildNodeByPath(path);
  732. }
  733. /// <summary>
  734. /// 查询字节的下的节点
  735. /// </summary>
  736. /// <param name="path"></param>
  737. /// <returns></returns>
  738. protected NodeBase GetChildNodeByPath(string path)
  739. {
  740. if (path.IsEmpty())
  741. {
  742. return null;
  743. }
  744. if (NodePath.UAndT() == path.UAndT())
  745. {
  746. return this;
  747. }
  748. if (HasChild)
  749. {
  750. var child = Children.FirstOrDefault(a => a.NodePath.UAndT() == path.UAndT());
  751. if (child != null)
  752. {
  753. return child;
  754. }
  755. if (NodeType== NodeType.FlowNode)
  756. {
  757. var node1 = (FlowNode) this;
  758. foreach (var node in node1.SceneInfos)
  759. {
  760. child = node.GetChildNodeByPath(path);
  761. if (child != null)
  762. {
  763. return child;
  764. }
  765. }
  766. }
  767. foreach (var node in Children)
  768. {
  769. child = node.GetChildNodeByPath(path);
  770. if (child != null)
  771. {
  772. return child;
  773. }
  774. }
  775. }
  776. return null;
  777. }
  778. /// <summary>
  779. /// 获取节点深度
  780. /// </summary>
  781. /// <returns></returns>
  782. protected virtual int GetNodeDepth()
  783. {
  784. var depth = 1;
  785. if (HasParent)
  786. {
  787. depth = Parent.NodeDepth + 1;
  788. }
  789. return depth;
  790. }
  791. protected virtual string GetNodePath()
  792. {
  793. return HasParent ? $"{Parent.NodePath}_{InternalNo}" : InternalNo;
  794. }
  795. protected virtual bool IsHasParent()
  796. {
  797. return Parent != null;
  798. }
  799. protected virtual bool IsHasChild()
  800. {
  801. return Children?.Count > 0;
  802. }
  803. protected virtual bool CheckChildIsRunning()
  804. {
  805. if (!HasChild)
  806. {
  807. return NodeState==NodeState.Running;
  808. }
  809. return Children.Any(a => a.ChildIsRunning || a.NodeState==NodeState.Running );
  810. }
  811. protected virtual void SetAllChildrenCount()
  812. {
  813. if (HasParent)
  814. {
  815. Parent.SetAllChildrenCount();
  816. }
  817. AllChildrenCount++;
  818. }
  819. #endregion Virtual Method
  820. #region IComparer<CimNode> 成员
  821. int IComparer<NodeBase>.Compare(NodeBase x, NodeBase y)
  822. {
  823. return String.CompareOrdinal(x?.Id, y?.Id);
  824. }
  825. #endregion IComparer<CimNode> 成员
  826. #region ICloneable 成员
  827. public object Clone()
  828. {
  829. var obj = (NodeBase)Assembly.GetExecutingAssembly().CreateInstance(GetType().FullName ?? throw new InvalidOperationException());
  830. NodeBase node = obj?.CreateNodeByXmlNode(XmlNode);
  831. return node ?? throw new InvalidOperationException();
  832. }
  833. #endregion ICloneable 成员
  834. public override string ToString()
  835. {
  836. return $"[{NodeState}][{GetType().Name}]【{Name}-{Id}】";
  837. }
  838. }
  839. /// <summary>
  840. /// 运行前委托
  841. /// </summary>
  842. /// <param name="node"></param>
  843. [Serializable]
  844. public delegate void EvPreCondition(NodeBase node);
  845. /// <summary>
  846. /// 运行时委托
  847. /// </summary>
  848. /// <param name="node"></param>
  849. [Serializable]
  850. public delegate void EvRunningCondition(NodeBase node);
  851. /// <summary>
  852. /// 运行结束时委托
  853. /// </summary>
  854. /// <param name="node"></param>
  855. [Serializable]
  856. public delegate void EvRunnedCondition(NodeBase node);
  857. /// <summary>
  858. /// 节点状态发生改变时触发的事件
  859. /// </summary>
  860. /// <param name="node">当前的节点</param>
  861. /// <param name="oldValue">改变前的值</param>
  862. [Serializable]
  863. public delegate void EvNodeStateChanged(NodeBase node, NodeState oldValue);
  864. /// <summary>
  865. /// 节点评分改变触发的事件
  866. /// </summary>
  867. /// <param name="node">当前的节点</param>
  868. /// <param name="oldValue">改变前的值</param>
  869. [Serializable]
  870. public delegate void EvNodeScoreChanged(NodeBase node, decimal oldValue);
  871. /// <summary>
  872. /// 运行后委托
  873. /// </summary>
  874. /// <param name="node"></param>
  875. [Serializable]
  876. public delegate void EvPostCondition(NodeBase node);
  877. }