using PropertyGridLib.Controls;
using System;
using System.Collections.Generic;
using System.Threading;
using TeamAAS.FlowEditor.Execution;
using TeamAAS.FlowEditor.Models;
namespace TeamAAS.FlowEditor.Plugins
{
///
/// 插件抽象基类 - 参照 VisionKit 的 BaseAbstractPlugin<TModel>
/// 泛型 TModel 自动实例化,子类只需实现 InitPlugin 和 PluginRun
///
[Serializable]
public abstract class BasePlugin : IFlowNodePlugin where TModel : BasePluginModel, new()
{
public TModel Model { get; protected set; }
public BasePluginModel GetModel { get => Model; set => Model = (TModel)value; }
///
/// 所属流程绑定的结果注册表(运行态=Main,编辑/调试态=Debug)。
/// 由 FlowNode 在初始化/换图时注入;未注入时回退到 Debug 注册表。
///
[field: NonSerialized]
public ResultRegistry Registry { get; set; }
/// 实际使用的注册表(保证非 null)
protected ResultRegistry RegistryOrDebug => Registry ?? ResultRegistry.Debug;
[NonSerialized]
private TeamAAS.Global.IPluginContext _context;
///
/// 插件运行上下文:获取平台服务(相机/机器人/通讯/供料/运动)的正规渠道。
/// 未注入时回落到全局 ServiceRegistry.Default,永不为 null;
/// 插件经 Context.GetService 取服务,无需直接摸 XxxManager.Instance。
/// 宿主将来可提供自定义实现(如远程代理)注入覆盖。
///
public TeamAAS.Global.IPluginContext Context
{
get => _context ?? TeamAAS.Global.ServiceRegistry.Default;
set => _context = value;
}
/// 按类型获取平台服务(工厂方法):相机/机器人/通讯/供料/运动管理器等;未注册返回 null。
protected T Service() => Context.GetService();
public int CostTime { get; protected set; }
public NodeRunStatus IsSuccess { get; set; } = NodeRunStatus.NotStarted;
public bool IsEnable { get; set; } = true;
public Dictionary LastResults { get; private set; }
/// 分支节点:返回下一个要执行的节点名列表(null=非分支节点)
public List BranchTargets { get; protected set; }
protected BasePlugin()
{
Model = new TModel();
}
///
/// 释放插件持有的资源。
/// 子类有相机句柄/连接流/大对象等需释放的资源时,重写并调用 base.Dispose()。
///
public virtual void Dispose()
{
try
{
LastResults?.Clear();
LastResults = null;
BranchTargets?.Clear();
BranchTargets = null;
Model = null;
}
catch { }
}
public virtual bool InitPlugin()
{
return true;
}
///
/// 声明插件输出字段。静态插件重写此方法声明固定输出;动态插件可从 Model 动态生成。
///
public virtual List DeclareOutputs() => new List();
public abstract NodeRunStatus PluginRun(CancellationToken token, out Dictionary results);
public bool InitRun()
{
Dictionary results = new Dictionary();
try
{
bool ret = InitPlugin();
foreach (var field in DeclareOutputs())
{
results[field.Key] = field.ValueType != null && field.ValueType.IsValueType
? Activator.CreateInstance(field.ValueType)
: null;
}
results["状态"] = NodeRunStatus.NotStarted;
results["结果"] = false;
results["耗时"] = 0;
results["模型"] = this;
if (!ret)
results["Error"] = GetModel.FlowName + "插件初始化失败";
RegistryOrDebug.SetResult(GetModel.FlowId, GetModel.NodeId, GetModel.NodeName, results);
LastResults = results;
return ret;
}
catch (System.Exception ex)
{
results["Error"] = GetModel.FlowName + ex.Message;
RegistryOrDebug.SetResult(GetModel.FlowId, GetModel.NodeId, GetModel.NodeName, results);
LastResults = results;
System.Diagnostics.Debug.WriteLine($"[InitRun] {GetModel.NodeName}: {ex}");
return false;
}
}
public NodeRunStatus Run(CancellationToken token)
{
IsSuccess = NodeRunStatus.Running;
NodeRunStatus status;
try
{
Dictionary results;
status = PluginRun(token, out results);
LastResults = results;
IsSuccess = status;
}
catch (System.Exception)
{
IsSuccess = NodeRunStatus.Failed;
status = NodeRunStatus.Failed;
}
return status;
}
///
/// 通过公式获取节点执行结果值
///
///
///
///
public T GetValue(FormulaBound formula)
{
if (formula == null)
return default(T);
object _result = new object();
_result = RegistryOrDebug.ResolveFormula(GetModel.FlowId, formula.Formula);
if (_result == null || _result?.ToString() == "")
return formula.Value;
else if (typeof(T).IsInterface)
{
if (_result is T tResult)
return tResult;
else
return default(T);
}
else
return (T)System.Convert.ChangeType(_result, typeof(T));
}
public object GetResolve(FormulaBound