| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- using System;
- using System.Collections.Generic;
- using System.Threading;
- using System.Windows;
- using Plugins.Vm.Models;
- using Plugins.Vm.Views;
- using TeamAAS.FlowEditor.Execution;
- using TeamAAS.FlowEditor.Models;
- using TeamAAS.FlowEditor.Plugins;
- namespace Plugins.Vm
- {
- /// <summary>
- /// VM 图像显示节点:把上游输出的图层/图像显示到指定画面框(视觉窗体);每个显示项可独立
- /// 链接 OK/NG 结果(可不链接)驱动该画面框状态圆点。镜像 VppDisplayPlugin。
- /// </summary>
- [Serializable]
- [Plugin("VM图像显示", PluginCategory.Vm模块, typeof(VmDisplayModel),
- "Monitor",
- Description = "把图层/图像显示到主页画面框;每项可独立链接 OK/NG 结果驱动状态圆点(可不链接)")]
- public class VmDisplayPlugin : BasePlugin<VmDisplayModel>
- {
- public override List<OutputField> DeclareOutputs()
- {
- var list = new List<OutputField>
- {
- new OutputField("显示画面数", typeof(int)),
- new OutputField("结果", typeof(bool)),
- };
- foreach (var kv in BuildItemKeys(Model))
- list.Add(new OutputField(kv.Key, typeof(object)));
- return list;
- }
- /// <summary>
- /// 依据显示项列表生成稳定的“输出键 → 显示项”映射:键优先取目标画面名,重名/空名时追加序号去重。
- /// DeclareOutputs 与 PluginRun 共用,保证键一致。
- /// </summary>
- private static List<KeyValuePair<string, VmDisplayItem>> BuildItemKeys(VmDisplayModel model)
- {
- var map = new List<KeyValuePair<string, VmDisplayItem>>();
- if (model?.DisplayItems == null) return map;
- var used = new HashSet<string>();
- for (int i = 0; i < model.DisplayItems.Count; i++)
- {
- var item = model.DisplayItems[i];
- if (item == null) continue;
- string key = string.IsNullOrWhiteSpace(item.FrameName) ? $"画面{item.FrameNo}" : item.FrameName;
- string unique = key;
- int dup = 2;
- while (!used.Add(unique)) unique = $"{key}({dup++})";
- map.Add(new KeyValuePair<string, VmDisplayItem>(unique, item));
- }
- return map;
- }
- public override NodeRunStatus PluginRun(CancellationToken token, out Dictionary<string, object> results)
- {
- results = new Dictionary<string, object>();
- try
- {
- var windows = UCDispVm.Instance.vmWindow;
- int displayed = 0;
- Log(3, $"开始显示,显示项 {Model.DisplayItems?.Count ?? 0} 个,可用画面框 {windows?.Count ?? 0} 个");
- foreach (var kv in BuildItemKeys(Model))
- {
- var item = kv.Value;
- results[kv.Key] = null;
- if (item.FrameNo < 1 || windows == null || windows.Count < item.FrameNo)
- {
- Log(2, $"显示项[{kv.Key}] 目标画面序号 {item.FrameNo} 无效或画面框不足,已跳过", TeamAAS.LogLevel.Warning);
- continue;
- }
- var win = windows[item.FrameNo - 1];
- if (win == null)
- {
- Log(2, $"显示项[{kv.Key}] 画面框为空,已跳过", TeamAAS.LogLevel.Warning);
- continue;
- }
- object value = GetResolve(item.Source);
- results[kv.Key] = value;
- var toShow = value;
- Application.Current?.Dispatcher.Invoke(() => win.RefreshImage(toShow));
- displayed++;
- Log(4, $"显示项[{kv.Key}] → 画面{item.FrameNo},类型 {(value?.GetType().Name ?? "null")}");
- if (!string.IsNullOrWhiteSpace(item.OkNgBinding?.Formula))
- {
- bool ok = GetValue<bool>(item.OkNgBinding);
- win.SetLable(ok ? VmResultType.OK : VmResultType.NG);
- Log(4, $"显示项[{kv.Key}] OK/NG = {(ok ? "OK" : "NG")}");
- }
- }
- results["显示画面数"] = displayed;
- results["结果"] = true;
- Log(2, $"显示完成,共刷新 {displayed} 个画面");
- return NodeRunStatus.Success;
- }
- catch (Exception ex)
- {
- results["Error"] = ex.Message;
- results["结果"] = false;
- Log(1, $"VM图像显示异常: {ex.Message}", TeamAAS.LogLevel.Error);
- return NodeRunStatus.Failed;
- }
- }
- }
- }
|