using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; using IwbZero.IwbBase; using IwbZero.ToolCommon.LogHelpers; using IwbZero.ToolCommon.StringModel; using WeEngine.CommonDto; using WeEngine.Enum; namespace WeEngine.Packages { public abstract class NodeBase : IIwbId, IComparer, ICloneable { #region 字段 ///// ///// 实际权重得分 ///// //private decimal _actualWeightScore; /// /// 节点状态 /// private NodeState _nodeState; #endregion 字段 #region 属性 /// /// 父节点 /// public NodeBase Parent { get; set; } /// /// 子节点 /// public List Children { get; set; } /// /// 唯一Id /// public string Id { get; set; } /// /// 方案包内部编号 /// public string InternalNo { get; set; } /// /// 名称 /// public string Name { get; set; } /// /// 节点类型 /// public NodeType NodeType { get; set; } /// /// 扩展数据 /// public dynamic ExtendData { get; set; } /// /// 节点状态 /// public NodeState NodeState { get => _nodeState; set { if ( _nodeState != value) { var oldState = _nodeState; _nodeState = value; if (CurPackageInfo != null && !CurPackageInfo.EventSwitch) { return; } if (_nodeState != NodeState.New) { EvNodeStateChanged?.Invoke(this, oldState); } } } } /// /// 矫正评分 /// public decimal CorrectionScore { get; set; } /// /// 权重(在父节点中的占比) /// public virtual decimal Weights { get; set; } /// /// 运行前事务(Id|Mapping) /// public string PreComponent { get; set; } /// /// 运行时事务(Id|Mapping) /// public string RunningComponent { get; set; } /// /// 运行结束时事务(Id|Mapping) /// public string RunnedComponent { get; set; } /// /// 运行后事务(Id|Mapping) /// public string PostComponent { get; set; } public List GuideInfos { get; set; } public string GuideNos { get; set; } /// /// 实际节点评分 /// public decimal ActualScore => GetActualScore(); /// /// 节点满分 /// public decimal NodeFullScore => GetNodeFullScore(); /// /// 实际节点得分权重 /// public decimal ActualWeights => GetActualWeights(); /// /// 子权重和 /// public decimal ChildFullWeights => GetChildFullWeights(); /// /// 当前方案包 /// public PackageNode CurPackageInfo => GetCurrentPackage(); /// /// 节点深度 /// public int NodeDepth => GetNodeDepth(); /// /// 节点路径 /// public string NodePath => GetNodePath(); /// /// 是否有父节点 /// public bool HasParent => IsHasParent(); /// /// 是否有子节点 /// public bool HasChild => IsHasChild(); /// /// XML对象 /// public IwbXmlNode XmlNode { get; set; } ///// ///// 是否等待其他节点 ///// //public bool IsWait { get; set; } /// /// 局部变量 /// public Hashtable Variables { get; set; } /// /// 验证合法性 /// public virtual bool IsValid => Id != "" && Name != ""; /// /// 是否等待 /// public bool IsWait => WaitPath?.Any() ?? false; public List WaitPath { get; set; } public bool ChildIsRunning => CheckChildIsRunning(); public int AllChildrenCount { get; set; } #endregion 属性 #region 构造函数 protected NodeBase() { AllChildrenCount = 0; WaitPath = new List(); Children = new List(); GuideInfos= new List(); Variables = new Hashtable(); NodeState = NodeState.New; EvNodeStateChanged += EventStateChange; // ReSharper disable once VirtualMemberCallInConstructor BindEvents(); } protected NodeBase(string id) : this() { Id = id; } protected NodeBase(string id, string name) : this(id) { Name = name; } protected NodeBase(IwbXmlNode xmlNode) : this() { XmlNode = xmlNode; CreateNodeByXmlNode(xmlNode); } protected NodeBase(RunningBase run) { } #endregion 构造函数 #region Event /// /// 绑定事件 /// public virtual void BindEvents() { if (EvPreCondition == null) { EvPreCondition += EventRunPre; } if (EvRunningCondition == null) { EvRunningCondition += EventRunning; } if (EvRunnedCondition == null) { EvRunnedCondition += EventRunned; } if (EvPostCondition == null) { EvPostCondition += EventRunPost; } } #region 运行前事件 /// /// 运行前条件验证 /// public bool PreConditionValidated { get; set; } /// /// 无需验证(随机选的情景块不需要验证) /// public bool NotValidated { get; set; } /// /// 运行前事件 /// public event EvPreCondition EvPreCondition; /// /// 执行运行前事件 /// /// protected virtual void ExecutePreCondition(NodeBase node) { PreConditionValidated = true; EvPreCondition?.Invoke(node); } protected virtual void EventRunPre(NodeBase node) { node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.PreEvent); } #endregion 运行前 #region 运行时事件 /// /// 运行时事件 /// public event EvRunningCondition EvRunningCondition; /// /// 执行运行时事件 /// /// protected virtual void ExecuteRunningCondition(NodeBase node) { EvRunningCondition?.Invoke(node); } protected virtual void EventRunning(NodeBase node) { node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.RunningEvent); } #endregion 运行时事件 #region 运行结束时事件 /// /// 运行结束时事件 /// public event EvRunnedCondition EvRunnedCondition; public bool RunnedConditionValidated { get; set; } /// /// 执行运行结束时事件 /// /// protected virtual void ExecuteRunnedCondition(NodeBase node) { RunnedConditionValidated = true; EvRunnedCondition?.Invoke(node); } protected virtual void EventRunned(NodeBase node) { node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.RunnedEvent); } #endregion 运行结束时事件 #region 运行后事件 /// /// 运行后条件验证 /// public bool PostConditionValidated { get; set; } /// /// 运行后事件 /// public event EvPostCondition EvPostCondition; /// /// 执行运行后事件 /// /// protected virtual void ExecutePostCondition(NodeBase node) { PostConditionValidated = true; EvPostCondition?.Invoke(node); } protected virtual void EventRunPost(NodeBase node) { node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.PostEvent); //if (HasChild) //{ // foreach (var nodeBase in Children) // { // if (nodeBase.NodeState != NodeState.New) // { // nodeBase.NodeState = NodeState.Complete; // } // } //} } #endregion 运行后 #region 节点变化 public event EvNodeStateChanged EvNodeStateChanged; /// /// 节点状态变化触发事件 /// /// /// protected virtual void EventStateChange(NodeBase node, NodeState oldValue) { if (node.NodeState == NodeState.New) { return; } if (node.NodeState == NodeState.ReStart) { //重启后自动变更为运行状态 node.NodeState = NodeState.Running; return; } switch (oldValue) { case NodeState.New: ExecutePreCondition(node); if (!node.NotValidated && !PreConditionValidated) { node.NodeState = NodeState.New; if (node.NodeType == NodeType.FlowNode || node.NodeType == NodeType.SceneFlowBlock) { node.CurPackageInfo?.RunnerManager?.Instance?.Run(this, OperationType.SelectNextNode); } return; } if (IsWait) { node.NodeState = NodeState.Wait; return; } NotValidated = false; if (node.NodeState == NodeState.Running) { typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【已启动】"); ExecuteRunningCondition(node); } break; case NodeState.Wait: { if (node.NodeState == NodeState.Running) { typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【已启动】"); ExecuteRunningCondition(node); } break; } case NodeState.Running: if (node.NodeState == NodeState.RunEnd) { ExecuteRunnedCondition(node); if (!RunnedConditionValidated) { node.NodeState = oldValue; return; } typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【已结束】"); } else if (node.NodeState == NodeState.Complete) { typeof(NodeBase).LogDebug($"节点 - [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] -【【已完成】】"); ExecutePostCondition(node); } break; case NodeState.RunEnd: if (node.NodeState == NodeState.Complete) { ExecutePostCondition(node); typeof(NodeBase).LogDebug($"节点- [{node.NodeType}] - [{node.CurPackageInfo.RunningId}] - [{node.NodePath}] - 【【 已完成 】】"); } break; case NodeState.ReStart: break; } } #endregion 节点变化 #endregion Event #region Score /// /// 获取当前节点评分 /// /// protected virtual decimal GetActualScore() { var score= CurPackageInfo?.EvalManager?.Instance?.GetActualScore(this)??0; return score; } /// /// 获取当前节点评分 /// /// protected virtual decimal GetActualWeights() { var score = CurPackageInfo?.EvalManager?.Instance?.GetActualWeights(this)??0; return score; } /// /// 获取当前节点满分 /// /// protected virtual decimal GetNodeFullScore() { var score = CurPackageInfo?.EvalManager?.Instance?.GetNodeFullScore(this)??0; return score; } /// /// 获取子节点权重之和 /// /// protected virtual decimal GetChildFullWeights() { var score = CurPackageInfo?.EvalManager?.Instance?.GetChildFullWeights(this)??0; return score; } #endregion Score #region XML /// /// 转成XML /// /// public virtual string ToXmlString() { string str = ""; str += $"{Id}\r\n"; str += $"{InternalNo}\r\n"; str += $"{Name}\r\n"; //str += $"{NodeType}\r\n"; str += $"{NodeState}\r\n"; str += Weights == 0 ? "" : $"{Weights}\r\n"; str += ActualScore == 0 ? "" : $"{ActualScore}\r\n"; str += CorrectionScore == 0 ? "" : $"{CorrectionScore}\r\n"; if (Variables != null && Variables.Count > 0) { string vStr = ""; foreach (DictionaryEntry entry in Variables) { var v = (IwbRtVariable) entry.Value; vStr += (vStr == "" ? "" : ",") + $"[{v.VarName}:{v.DataType.TypeString}:{v.GetStringValue()}]"; } if (vStr.IsNotEmpty()) { str += $"{vStr}"; } } str += GuideNos.IsEmpty() ? "" : $"{GuideNos}\r\n"; var str1 = ""; str1 += PreComponent.IsEmpty() ? "" : $"{PreComponent}\r\n"; str1 += RunningComponent.IsEmpty() ? "" : $"{RunningComponent}\r\n"; str1 += RunnedComponent.IsEmpty() ? "" : $"{RunnedComponent}\r\n"; str1 += PostComponent.IsEmpty() ? "" : $"{PostComponent}\r\n"; if (str1.IsNotEmpty()) { str += "\r\n"; str += str1; str += "\r\n"; } return str; } /// /// 从XML对象中创建Node对象的值 /// public NodeBase CreateNodeByXmlNode(IwbXmlNode xmlNode) { XmlNode = xmlNode; if (xmlNode != null) { Id = xmlNode.GetChildValue("Id"); InternalNo = xmlNode.GetChildValue("InternalNo"); Name = xmlNode.GetChildValue("Name"); NodeState = xmlNode.GetChildValue("NodeState")?.GetEnumByName() ?? NodeState.New; Weights = xmlNode.GetChildValue("Weights").ValD(); Weights = Weights <= 0 ? 100 : Weights; CorrectionScore = xmlNode.GetChildValue("CorrectionScore").ValD(); GuideNos = xmlNode.GetChildValue("GuideNos"); GuideInfos = CreateGuideByNos(GuideNos); var variables = xmlNode.GetChildValue("Variables").StrToArray(); if (variables.Length > 0) { foreach (var v in variables) { var arr = v.StrToArray(":"); string id = ""; if (arr.Length > 0) { id = arr[0].UAndT(); } if (id.IsNotEmpty()) { Variables[id] = IwbRtVariable.Str2Variable(v); } } } var componentNode = xmlNode.GetChildNode("Components"); if (componentNode != null) { PreComponent = componentNode.GetChildValue("PreComponent"); RunningComponent = componentNode.GetChildValue("RunningComponent"); RunnedComponent = componentNode.GetChildValue("RunnedComponent"); PostComponent = componentNode.GetChildValue("PostComponent"); } CreateSelfNode(xmlNode); } return this; } private List CreateGuideByNos(string guideNos) { var list = new List(); var xmlNode = PackageHelper.GetGuidesXmlFromFile(CurPackageInfo?.Id, guideNos); if (xmlNode != null && xmlNode.Nodes.Count>0) { foreach (IwbXmlNode child in xmlNode.Nodes) { list.Add(new GuideNode().CreateNodeByXmlNode(child)); } } return list; } //private GuideInfo CreateGuideByXml(XmlNode xmlNode) //{ // var guide= new GuideInfo(); // if (xmlNode != null) // { // guide.Id = xmlNode.Attributes?["path"] != null ? xmlNode.Attributes["path"].Value : ""; // if (xmlNode.HasChildNodes) // { // foreach (XmlNode node in xmlNode.ChildNodes) // { // switch (node.Name.Trim()) // { // case "Name": // guide.Name = node.FirstChild?.Value; // break; // case "Description": // guide.Description = node.FirstChild?.Value; // break; // case "IsPush": // guide.IsPush = node.FirstChild.Value.ValB(); // break; // } // } // } // } // return guide; //} /// /// 创建自己属性值的时候必须继承,获取属性值的节点对象 /// /// protected virtual void CreateSelfNode(IwbXmlNode xmlNode) { } protected string ConvertXml(string str,bool isEscape=false) { if (isEscape) { str = str.Replace("&","&"); str = str.Replace("<","<"); str = str.Replace(">",">"); str = str.Replace("\"","""); str = str.Replace("'","'"); } else { str = str.Replace("&", "&"); str = str.Replace("<", "<"); str = str.Replace(">", ">"); str = str.Replace(""", "\""); str = str.Replace("'", "'"); } return str; } #endregion XML #region Virtual Method protected NodeState GetNodeState(RunningBase running) { return running.IsEnd? NodeState.RunEnd: running.IsStart? NodeState.Running: NodeState.New; } /// /// 获取变量 /// /// public virtual Hashtable GetVariables() { var variables = (Hashtable)Variables.Clone(); if (HasParent) { variables = Parent.GetVariables().MergeHashtable(variables); } return variables; } /// /// 获取变量 /// /// public virtual Hashtable GetSelfVariables() { var variables = GetVariables(); var newVariables = new Hashtable(); foreach (DictionaryEntry entry in variables) { if (!DefaultVariable.VariableNames.Contains(entry.Key)) { newVariables.Add(entry.Key, entry.Value); } } return newVariables; } public virtual void SetPreVariables() { SetVariable(DefaultVariable.FullNodeScore, NodeFullScore); SetVariable(DefaultVariable.Path, NodePath); SetVariable(DefaultVariable.RunValidate, "true"); } public virtual void SetRunnedVariables() { //SetVariable(DefaultVariable.PrevNodeScore, ActualScore); } /// /// 添加变量 /// /// public void SetVariable(string key,string value) { SetVariable(key, new IwbRtVariable(key).SetValue(value)); } /// /// 添加变量 /// /// public void SetVariable(string key,int? value) { SetVariable(key, new IwbRtVariable(key, "int").SetValue(value)); } /// /// 添加变量 /// /// public void SetVariable(string key,decimal? value) { SetVariable(key, new IwbRtVariable(key, "decimal").SetValue(value)); } /// /// 添加变量 /// /// public void SetVariable(string key,IwbRtVariable variable) { if (Variables.ContainsKey(key)) { Variables[key] = variable; } else { Variables.Add(key,variable); } } ///// ///// 添加变量 ///// ///// //public void SetVariable( Dictionary dic) //{ // foreach (var d in dic) // { // SetVariable(d.Key,d.Value); // } //} /// /// 获取百分制得分 /// /// public decimal ConvertScoreTo100() { return ConvertScoreByPer(100); } /// /// 获取指定分制的得分 /// /// public decimal ConvertScoreByPer(int maxScore) { if (maxScore <= 0) { throw new Exception("分制不能小于0!"); } return NodeFullScore == 0 ? 0 : Math.Round(maxScore * ActualScore / NodeFullScore); } /// /// 获取当前Package /// /// protected PackageNode GetCurrentPackage() { PackageNode curPackage = null; if (HasParent) { curPackage = Parent.GetCurrentPackage(); } if (NodeType == NodeType.ScenePackage) { curPackage = (PackageNode) this; } return curPackage; } /// /// 根据Id查询节点 /// /// /// public virtual NodeBase GetNodeByPath(string path) { return CurPackageInfo?.GetChildNodeByPath(path); } /// /// 查询字节的下的节点 /// /// /// protected NodeBase GetChildNodeByPath(string path) { if (path.IsEmpty()) { return null; } if (NodePath.UAndT() == path.UAndT()) { return this; } if (HasChild) { var child = Children.FirstOrDefault(a => a.NodePath.UAndT() == path.UAndT()); if (child != null) { return child; } if (NodeType== NodeType.FlowNode) { var node1 = (FlowNode) this; foreach (var node in node1.SceneInfos) { child = node.GetChildNodeByPath(path); if (child != null) { return child; } } } foreach (var node in Children) { child = node.GetChildNodeByPath(path); if (child != null) { return child; } } } return null; } /// /// 获取节点深度 /// /// protected virtual int GetNodeDepth() { var depth = 1; if (HasParent) { depth = Parent.NodeDepth + 1; } return depth; } protected virtual string GetNodePath() { return HasParent ? $"{Parent.NodePath}_{InternalNo}" : InternalNo; } protected virtual bool IsHasParent() { return Parent != null; } protected virtual bool IsHasChild() { return Children?.Count > 0; } protected virtual bool CheckChildIsRunning() { if (!HasChild) { return NodeState==NodeState.Running; } return Children.Any(a => a.ChildIsRunning || a.NodeState==NodeState.Running ); } protected virtual void SetAllChildrenCount() { if (HasParent) { Parent.SetAllChildrenCount(); } AllChildrenCount++; } #endregion Virtual Method #region IComparer 成员 int IComparer.Compare(NodeBase x, NodeBase y) { return String.CompareOrdinal(x?.Id, y?.Id); } #endregion IComparer 成员 #region ICloneable 成员 public object Clone() { var obj = (NodeBase)Assembly.GetExecutingAssembly().CreateInstance(GetType().FullName ?? throw new InvalidOperationException()); NodeBase node = obj?.CreateNodeByXmlNode(XmlNode); return node ?? throw new InvalidOperationException(); } #endregion ICloneable 成员 public override string ToString() { return $"[{NodeState}][{GetType().Name}]【{Name}-{Id}】"; } } /// /// 运行前委托 /// /// [Serializable] public delegate void EvPreCondition(NodeBase node); /// /// 运行时委托 /// /// [Serializable] public delegate void EvRunningCondition(NodeBase node); /// /// 运行结束时委托 /// /// [Serializable] public delegate void EvRunnedCondition(NodeBase node); /// /// 节点状态发生改变时触发的事件 /// /// 当前的节点 /// 改变前的值 [Serializable] public delegate void EvNodeStateChanged(NodeBase node, NodeState oldValue); /// /// 节点评分改变触发的事件 /// /// 当前的节点 /// 改变前的值 [Serializable] public delegate void EvNodeScoreChanged(NodeBase node, decimal oldValue); /// /// 运行后委托 /// /// [Serializable] public delegate void EvPostCondition(NodeBase node); }