using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Future.Contract { /// /// 指令空间:有独立的参数和信道上下文 /// public abstract class SpaceInstructBase : StructInstructBase { #region 指令序列设计支持逻辑 /// /// 指令空间的序列标签Label种子 /// public int LabelSeed { get; set; } protected override void DoVerify(IOutputChannel infoChannel) { this.ReferenceMapping.Clear(); this.BuildReferenceMapping(this.ReferenceMapping); this.InsturctContext.Clear(); this.ParameterContext.Clear(); this.ChannelContext.Clear(); } protected override string CheckParent(FutureInstruct parentInst) { if (parentInst != null) return "指令空间不可以成为任何一个指令的子级指令!"; else return null; } #endregion #region 指令执行逻辑 /// /// 指令序列的执行状态 /// public ESpaceState State { get; set; } /// /// 启动指令序列的执行逻辑,自类可以重写这个逻辑 /// /// 用于输出验证信息或其它过程提示信息的输出通道 /// 消息输出管道、态势感知管道、报告生成管道等 /// 是否需要开启独立线程还执行?默认=false /// 如果失败则返回原因,正常启动返回“null” public virtual string Start(IOutputChannel infoOutChannel, IEnumerable expansionChannels = null, bool needThread = false) { if (this.State != ESpaceState.Finished) return $"当前指令序列正在执行或暂停,不可重复启动!"; //先执行一次指令校验 this.Verify(infoOutChannel); if (infoOutChannel.OutputMessageCount > 0) return $"当前指令序列运行校验失败,存在【{infoOutChannel.OutputMessageCount}】个问题,请检查指令序列的配置!"; //清空所有上下文 this.__ExpansionChannels.Clear(); this.ReferenceMapping.Clear(); this.InsturctContext.Clear(); this.ParameterContext.Clear(); this.ChannelContext.Clear(); this.__ExpansionChannels.AddRange(expansionChannels); //个性化启动准备 string startMsg = this.OnPreStart(); if (startMsg != null) return startMsg; this.State = ESpaceState.Normal; if (needThread) { //TODO:指令执行逻辑=>启动线程并使用新线程执行Execute方法或DoExecute方法 } else this.Execute(); return null; } /// /// 子类必须实现的启动准备逻辑 /// /// 如果启动准备失败则需要返回失败原因 protected abstract string OnPreStart(); /// /// 发送暂停通知,等待执行引擎在执行到检查周期时开始等待 /// /// 如果失败则返回原因 public virtual string Pause() { return null; } /// /// 发送继续通知,等待执行引擎在执行到检查周期时继续执行 /// /// 如果失败则返回原因 public virtual string Rouse() { return null; } /// /// 发出终止通知,等待执行引擎在执行到检查周期时自动停止 /// /// 如果失败则返回原因 public virtual string Break() { return null; } /// /// 强制终止,强制终止引擎的执行线程,可能会造成未知错误 /// /// 如果失败则返回原因 public virtual string Abort() { return null; } /// /// 执行结束时需要进行的操作 /// public abstract void OnFinished(); /// /// 当执行完成时发出的通知 /// public event EventHandler Finished; #endregion #region 扩展通道逻辑 private readonly List __ExpansionChannels = new List(); /// /// 扩展信道表,用于进行态势感知、报告生成等行为的扩展信道表 /// /// public IEnumerable OutChannels() { yield break; } #endregion #region 指令与参数上下文逻辑 /// /// 存储一个指令空间中所有指令的“值” /// private readonly Dictionary InsturctContext = new Dictionary(); /// /// 以指令为单位存储一个指令空间中所有指令的参数值 /// private readonly Dictionary> ParameterContext = new Dictionary>(); /// /// 设置一个参数的值,如果这个参数尚未存在于上下文中则创建上下文参数 /// /// 上下文参数名 /// 参数值 public void SetParameter(string key, string value) { string[] args = key.Split(new char[] { FutureInstruct.PR_SplitChar, FutureInstruct.PR_StartChar }, StringSplitOptions.RemoveEmptyEntries); switch (args.Length) { case (1): { if (this.InsturctContext.ContainsKey(args[0])) InsturctContext[args[0]] = value; else InsturctContext.Add(args[0], value); } break; case (2): { if (!this.ParameterContext.ContainsKey(args[0])) this.ParameterContext.Add(args[0], new Dictionary()); Dictionary param = this.ParameterContext[args[0]]; if (param.ContainsKey(args[1])) param[args[1]] = value; else param.Add(args[1], value); } break; default: return; } } /// /// 获取一个上下文参数的值,如果这个上下文参数不存在则返回默认值 /// /// 上下文参数名 /// 默认值 /// 参数的值 public string GetParameter(string key, string @default) { string[] args = key.Split(new char[] { FutureInstruct.PR_SplitChar, FutureInstruct.PR_StartChar }, StringSplitOptions.RemoveEmptyEntries); switch (args.Length) { case (1): { if (this.InsturctContext.ContainsKey(args[0])) return this.InsturctContext[args[0]]; else return @default; } case (2): { if (!this.ParameterContext.ContainsKey(args[0])) this.ParameterContext.Add(args[0], new Dictionary()); Dictionary param = this.ParameterContext[args[0]]; if (param.ContainsKey(args[1])) return param[args[1]]; else return @default; } default: return @default; } } /// /// 检查上下文中是否存在制定名称的参数 /// /// 上下文参数名称 /// 是/否 public bool IsExistParameter(string key) { string[] args = key.Split(new char[] { FutureInstruct.PR_SplitChar, FutureInstruct.PR_StartChar }, StringSplitOptions.RemoveEmptyEntries); switch (args.Length) { case (1): { if (this.InsturctContext.ContainsKey(args[0])) return true; } break; case (2): { if (!this.ParameterContext.ContainsKey((string)args[0])) return false; if (this.ParameterContext[args[0]].ContainsKey(args[1])) return true; break; } default: return false; } return false; } #endregion #region 信道上下文逻辑 /// /// 以信道名称为Key,存储当前指令空间中所有已经完成初始化化的通信信道 /// private readonly Dictionary ChannelContext = new Dictionary(); /// /// 向上下文注册信道,如果信道名称已经存在则会报错 /// /// 通信信道名称 /// 信道实例 public void SetChannel(string key, CommChannel channel) { key = key.TrimStart(FutureInstruct.PR_StartChar); if (!this.ChannelContext.ContainsKey(key)) this.ChannelContext.Add(key, channel); else this.ChannelContext[key] = channel; } /// /// 从上下文中获取通信信道实例 /// /// 通信信道名称 /// 获得的通信信道实例 public CommChannel GetChannel(string key) { key = key.TrimStart(FutureInstruct.PR_StartChar); if (!ChannelContext.ContainsKey(key)) return this.ChannelContext[key]; return null; } /// /// 检查上下文中是否存在制定名称的通信信道 /// /// 通信信道名称 /// 是/否 public bool IsExistChannel(string key) { key = key.TrimStart(FutureInstruct.PR_StartChar); return this.ChannelContext.ContainsKey(key); } #endregion #region 指令与参数引用校验逻辑 /// /// 指令引用表:指示那些指令被其它指令引用,用于加速指令的运行,减小指令上下文与参数上下文的内存占用 /// private readonly List ReferenceMapping = new List(); /// /// 检查一个指令或是指令的参数是否被其它指令引用;只允许在执行态被使用 /// /// 指令或是参数的标识符 /// 如果被引用则返回True,否则返回False public bool IsExistReference(string identify) { if (string.IsNullOrEmpty(identify)) return false; return this.ReferenceMapping.Contains(identify); } #endregion } }