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; }
}
}
}