using System; using System.Collections.Generic; namespace Plugins.Script.Core { /// /// 脚本基类:脚本节点里用户写的类会自动继承它(生成的包装脚本 public class MyScript : Plugins.Script.ScriptContext)。 /// 由宿主 在运行前注入桥接委托,从而让脚本拥有"普通插件"的能力: /// 读上游流程变量()、产出结果(return / )、 /// 写插件日志()、取平台服务()。 /// /// 设计取舍:脚本不直接继承 BasePlugin——脚本是运行时动态编译的临时程序集,无法稳定写入 .aas /// 流程文件(BinaryFormatter 按类型全名反序列化)也无法被 PluginLoader 从磁盘发现;故用"稳定宿主节点 /// + 脚本继承 ScriptContext"两层结构,既拿到全部插件能力,又规避动态类型持久化难题(对标 VisionKit ScriptMethods)。 /// public abstract class ScriptContext { /// 宿主注入:按公式解析上游流程变量值(如 "&{图像采集.图像}")。设计期测试运行时为 null。 internal Func ResolveFormulaFunc { get; set; } /// 宿主注入:写插件日志(level, message, category)。 internal Action LogFunc { get; set; } /// 宿主注入:平台服务定位器(相机/机器人/通讯/供料/运动等)。 internal TeamAAS.Global.IPluginContext PluginContext { get; set; } /// 宿主注入:命名输出收集袋( 写入,运行结束后由宿主并入节点结果)。 internal IDictionary OutputBag { get; set; } /// 按公式读取上游流程变量(原始 object;解析不到或设计期无数据时返回 null)。 public object GetInput(string formula) { if (ResolveFormulaFunc == null || string.IsNullOrEmpty(formula)) return null; try { return ResolveFormulaFunc(formula); } catch { return null; } } /// 按公式读取上游流程变量并转换为目标类型(失败返回默认值)。 public T GetInput(string formula) { var v = GetInput(formula); if (v == null) return default(T); if (v is T) return (T)v; try { return (T)Convert.ChangeType(v, typeof(T)); } catch { return default(T); } } /// 产出一个命名输出(须在节点"输出字段名"里声明,供下游节点按 "&{本节点.名称}" 引用)。 public void SetOutput(string name, object value) { if (string.IsNullOrEmpty(name) || OutputBag == null) return; OutputBag[name] = value; } /// 写一条插件日志(默认中等详细度 L2、Info 类别)。 public void Log(string message) { Log(2, message, TeamAAS.LogLevel.Info); } /// 写一条插件日志(level 1低/2中/3高/4终;category Info/Warning/Error)。 public void Log(int level, string message, TeamAAS.LogLevel category) { if (LogFunc != null) LogFunc(level, message, category); } /// 按类型获取平台服务(相机/机器人/通讯/供料/运动管理器等;未注册或设计期返回默认值)。 public T Service() { return PluginContext != null ? PluginContext.GetService() : default(T); } /// 平台服务定位器(需要枚举/高级用法时直接使用)。 public TeamAAS.Global.IPluginContext Context { get { return PluginContext; } } } }