using HalconDotNet;
|
using LB_SmartVision.Forms.Pages.SettingPage;
|
using LB_SmartVision.Tool;
|
using LB_VisionFlowNode;
|
using LB_VisionProcesses;
|
using LB_VisionProcesses.Cameras;
|
using LB_VisionProcesses.Communicators;
|
using LB_VisionProcesses.Processes.ScriptTool;
|
using Newtonsoft.Json;
|
using Newtonsoft.Json.Serialization;
|
using OpenCvSharp;
|
using System.Collections.Concurrent;
|
using System.Data;
|
using System.Diagnostics;
|
using System.Reflection;
|
using System.Text;
|
|
namespace LB_SmartVision.ProcessRun
|
{
|
public class ProcessRunBll
|
{
|
|
private ProcessContext ProcessContext = null;
|
|
public static string Node2ToolClassName(string NodeName)
|
{
|
foreach (var item in IProcess.dicProcesses)
|
{
|
if (NodeName.StartsWith(item.Key))
|
{
|
return item.Value.ToString();
|
}
|
}
|
|
return string.Empty;
|
}
|
|
/// <summary>
|
/// 流程名称
|
/// </summary>
|
public string Name = string.Empty;
|
|
/// <summary>
|
/// 运行标记
|
/// </summary>
|
public bool bRuning
|
{
|
set
|
{
|
if (ProcessContext == null)
|
return;
|
ProcessContext.bRuning = value;
|
}
|
get
|
{
|
if (ProcessContext == null)
|
return false;
|
return ProcessContext.bRuning;
|
}
|
}
|
|
/// <summary>
|
/// 运行完成
|
/// </summary>
|
public bool bCompleted
|
{
|
set
|
{
|
if (ProcessContext == null)
|
return;
|
ProcessContext.bCompleted = value;
|
}
|
get
|
{
|
if (ProcessContext == null)
|
return false;
|
return ProcessContext.bCompleted;
|
}
|
}
|
|
/// <summary>
|
/// 运行结果
|
/// </summary>
|
public bool Result
|
{
|
set
|
{
|
if (ProcessContext == null)
|
return;
|
ProcessContext.Result = value;
|
}
|
get
|
{
|
if (ProcessContext == null)
|
return false;
|
return ProcessContext.Result;
|
}
|
}
|
|
/// <summary>
|
/// 运行消息
|
/// </summary>
|
public string Msg
|
{
|
set
|
{
|
if (ProcessContext == null)
|
return;
|
ProcessContext.Msg = value;
|
}
|
get
|
{
|
if (ProcessContext == null)
|
return "运行失败";
|
return ProcessContext.Msg;
|
}
|
}
|
|
/// <summary>
|
/// 运行时间(ms)
|
/// </summary>
|
public double RunTime = 0;
|
|
public bool GetImage(Forms.Pages.SettingPage.Layout layout, out HObject InputImage, out HObject RecordImage)
|
{
|
return ProcessContext.GetImage(layout, out InputImage, out RecordImage);
|
}
|
|
public bool GetImage(out HObject InputImage, out HObject RecordImage)
|
{
|
InputImage = null;
|
RecordImage = null;
|
foreach (var layout in GlobalVar.dicLayout)
|
{
|
if (layout.Value.ProcessName == Name)
|
return ProcessContext.GetImage(layout.Value, out InputImage, out RecordImage);
|
}
|
return false;
|
}
|
|
public bool GetCsv(CsvSetting csv, out List<string> DataTitle, out Dictionary<string, object> ResultData)
|
{
|
return ProcessContext.GetCsv(csv, out DataTitle, out ResultData);
|
}
|
|
public bool GetOutput(string map, out object obj)
|
{
|
return ProcessContext.GetValue(map, out obj);
|
}
|
|
public bool GetStringOutput(string map, out string str)
|
{
|
bool res = GetOutput(map, out object obj);
|
str = ProcessParams.ConvertToString(obj);
|
return res;
|
}
|
|
public bool GetBooleanOutput(string map, out bool ret)
|
{
|
try
|
{
|
if (!GetOutput(map, out object obj))
|
{
|
ret = false;
|
return ret;
|
}
|
ret = Convert.ToBoolean(obj);
|
return true;
|
}
|
catch
|
{
|
ret = false;
|
return ret;
|
}
|
|
}
|
|
public ConcurrentDictionary<string, IProcess> GetSteps()
|
{
|
if (ProcessContext.dicContext == null)
|
return new ConcurrentDictionary<string, IProcess>();
|
|
return ProcessContext.dicContext;
|
}
|
|
/// <summary>
|
/// 运行流程
|
/// </summary>
|
public FlowPanel nodesControl = null;
|
|
/// <summary>
|
/// 通讯集合(Key:通讯名,Value:通讯句柄)
|
/// </summary>
|
public ObservableConcurrentDictionary<string, BaseCommunicator> dicCommunicators { get; set; }
|
|
/// <summary>
|
/// 相机集合(Key:相机SN,Value:相机句柄)
|
/// </summary>
|
public ObservableConcurrentDictionary<string, BaseCamera> dicCameras { get; set; }
|
|
|
public Action<string, LogInfoType> LogInfo;
|
|
public string allProcessPath
|
{
|
get
|
{
|
return GlobalVar.allProcessPath + Name + "\\default.nds";
|
}
|
}
|
|
public string allProcessInputsSettingPath
|
{
|
get
|
{
|
return GlobalVar.allProcessPath + Name + "\\A_ProcessInputs.json";
|
}
|
}
|
|
public string allProcessOutputsSettingPath
|
{
|
get
|
{
|
return GlobalVar.allProcessPath + Name + "\\A_ProcessOutputs.json";
|
}
|
}
|
|
public ConcurrentDictionary<string, List<Tuple<string, string>>> dicInputsMapping = new ConcurrentDictionary<string, List<Tuple<string, string>>>();
|
|
public ConcurrentDictionary<string, List<string>> dicOutputsMapping = new ConcurrentDictionary<string, List<string>>();
|
|
public ProcessRunBll() { }
|
|
public ProcessRunBll(string Name
|
, ObservableConcurrentDictionary<string, BaseCamera> dicCameras
|
, ObservableConcurrentDictionary<string, BaseCommunicator> dicCommunicators)
|
{
|
this.Name = Name;
|
this.dicCameras = dicCameras;
|
this.dicCommunicators = dicCommunicators;
|
|
}
|
|
public bool Load(out string msg)
|
{
|
try
|
{
|
if (!LoadInputs())
|
{
|
msg = "加载输入失败";
|
return false;
|
}
|
if (!LoadOutputs())
|
{
|
msg = "加载输出失败";
|
return false;
|
}
|
|
if (!allProcessPath.Contains(".nds"))
|
{
|
msg = "文件路径不完整";
|
return false;
|
}
|
|
ProcessContext = new ProcessContext(dicCameras, dicCommunicators, dicInputsMapping, dicOutputsMapping);
|
nodesControl = new FlowPanel(ProcessContext);
|
|
if (!File.Exists(allProcessPath))
|
{
|
Save(out msg);
|
msg = "文件不存在,创建默认布局";
|
}
|
else
|
{
|
byte[] bytes = File.ReadAllBytes(allProcessPath);
|
try
|
{
|
nodesControl.Load(allProcessPath);
|
}
|
catch
|
{
|
msg = $"文件损坏,长度为{bytes.Length}";
|
return false;
|
}
|
}
|
|
foreach (var node in nodesControl.GetAllNodes().Values)
|
{
|
string ProcessName = node.Text;
|
string ClassDescription = node.Description;
|
string ClassName = Node2ToolClassName(ClassDescription);
|
string ProcessPath = GlobalVar.allProcessPath + Name + "\\" + ProcessName + ".json";
|
if (!AddStep(Name, ProcessName, ClassName, ProcessPath))
|
LogInfo?.Invoke(string.Format("流程[{0}]添加\"{1}\"失败", Name, ProcessName), LogInfoType.ERROR);
|
}
|
msg = "加载布局成功";
|
|
CompileMappings();
|
|
return true;
|
}
|
catch { msg = "加载布局失败"; return false; }
|
}
|
|
public bool Save(out string msg)
|
{
|
try
|
{
|
if (!SaveInputs())
|
{
|
msg = "保存输入失败";
|
return false;
|
}
|
if (!SaveOutputs())
|
{
|
msg = "保存输出失败";
|
return false;
|
}
|
|
var dicSteps = GetSteps();
|
|
if (nodesControl.Save(allProcessPath))
|
{
|
msg = "保存布局成功";
|
return true;
|
}
|
else
|
{
|
msg = "保存布局失败";
|
return false;
|
}
|
|
}
|
catch { msg = "保存布局失败"; return false; }
|
}
|
|
public bool LoadInputs()
|
{
|
try
|
{
|
if (!allProcessInputsSettingPath.Contains(".json"))
|
{
|
Debug.WriteLine("文件路径不完整");
|
return false;
|
}
|
|
if (!File.Exists(allProcessInputsSettingPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allProcessInputsSettingPath);
|
SaveInputs();
|
return true;
|
}
|
|
// 如果文件存在,则先移除隐藏属性
|
if (File.Exists(allProcessInputsSettingPath))
|
File.SetAttributes(allProcessInputsSettingPath, File.GetAttributes(allProcessInputsSettingPath) & ~FileAttributes.Hidden);
|
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allProcessInputsSettingPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
dicInputsMapping = JsonConvert.DeserializeObject<ConcurrentDictionary<string, List<Tuple<string, string>>>>(strJson);
|
|
if (File.Exists(allProcessInputsSettingPath))
|
{
|
// 获取文件信息
|
FileInfo fileInfo = new FileInfo(allProcessInputsSettingPath);
|
|
// 设置文件为隐藏
|
fileInfo.Attributes |= FileAttributes.Hidden;
|
}
|
|
if (dicInputsMapping == null)
|
return false;
|
|
SaveInputs();
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool SaveInputs()
|
{
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Newtonsoft.Json.Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(dicInputsMapping, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
if (!Directory.Exists(Path.GetDirectoryName(allProcessInputsSettingPath)))
|
{
|
try
|
{
|
Directory.CreateDirectory(Path.GetDirectoryName(allProcessInputsSettingPath));
|
}
|
catch (Exception)
|
{ }
|
}
|
|
// 如果文件存在,则先移除隐藏属性
|
if (File.Exists(allProcessInputsSettingPath))
|
File.SetAttributes(allProcessInputsSettingPath, File.GetAttributes(allProcessInputsSettingPath) & ~FileAttributes.Hidden);
|
|
File.WriteAllText(allProcessInputsSettingPath, strJson, Encoding.UTF8);
|
|
if (File.Exists(allProcessInputsSettingPath))
|
{
|
// 获取文件信息
|
FileInfo fileInfo = new FileInfo(allProcessInputsSettingPath);
|
|
// 设置文件为隐藏
|
fileInfo.Attributes |= FileAttributes.Hidden;
|
}
|
|
CompileMappings();
|
|
return true;
|
}
|
|
public bool LoadOutputs()
|
{
|
try
|
{
|
if (!allProcessOutputsSettingPath.Contains(".json"))
|
{
|
Debug.WriteLine("文件路径不完整");
|
return false;
|
}
|
|
if (!File.Exists(allProcessOutputsSettingPath))
|
{
|
Debug.WriteLine("文件不存在创建空文件");
|
// 获取不带文件名的目录路径
|
string directoryPath = Path.GetDirectoryName(allProcessOutputsSettingPath);
|
SaveInputs();
|
return true;
|
}
|
|
// 如果文件存在,则先移除隐藏属性
|
if (File.Exists(allProcessOutputsSettingPath))
|
File.SetAttributes(allProcessOutputsSettingPath, File.GetAttributes(allProcessOutputsSettingPath) & ~FileAttributes.Hidden);
|
|
string strJson = string.Empty;
|
using (StreamReader streamReader = new StreamReader(allProcessOutputsSettingPath, Encoding.UTF8))
|
{
|
strJson = streamReader.ReadToEnd();
|
streamReader.Close();
|
}
|
|
dicOutputsMapping = JsonConvert.DeserializeObject<ConcurrentDictionary<string, List<string>>>(strJson);
|
|
if (File.Exists(allProcessOutputsSettingPath))
|
{
|
// 获取文件信息
|
FileInfo fileInfo = new FileInfo(allProcessOutputsSettingPath);
|
|
// 设置文件为隐藏
|
fileInfo.Attributes |= FileAttributes.Hidden;
|
}
|
|
if (dicOutputsMapping == null)
|
return false;
|
|
SaveOutputs();
|
return true;
|
}
|
catch { return false; }
|
}
|
|
public bool SaveOutputs()
|
{
|
string strJson = string.Empty;
|
var settings = new JsonSerializerSettings
|
{
|
Formatting = Newtonsoft.Json.Formatting.Indented,
|
// 自定义缩进(4空格)
|
ContractResolver = new DefaultContractResolver
|
{
|
NamingStrategy = new CamelCaseNamingStrategy()
|
}
|
};
|
|
strJson = JsonConvert.SerializeObject(dicOutputsMapping, settings);
|
//判断文件夹是否存在,防呆输入为文件名称
|
if (!Directory.Exists(Path.GetDirectoryName(allProcessOutputsSettingPath)))
|
{
|
try
|
{
|
Directory.CreateDirectory(Path.GetDirectoryName(allProcessOutputsSettingPath));
|
}
|
catch (Exception)
|
{ }
|
}
|
|
// 如果文件存在,则先移除隐藏属性
|
if (File.Exists(allProcessOutputsSettingPath))
|
File.SetAttributes(allProcessOutputsSettingPath, File.GetAttributes(allProcessOutputsSettingPath) & ~FileAttributes.Hidden);
|
|
File.WriteAllText(allProcessOutputsSettingPath, strJson, Encoding.UTF8);
|
|
if (File.Exists(allProcessOutputsSettingPath))
|
{
|
// 获取文件信息
|
FileInfo fileInfo = new FileInfo(allProcessOutputsSettingPath);
|
|
// 设置文件为隐藏
|
fileInfo.Attributes |= FileAttributes.Hidden;
|
}
|
|
CompileMappings();
|
|
return true;
|
}
|
|
/// <summary>
|
/// 添加单个步骤到流程队列中
|
/// </summary>
|
/// <param name="Camera"></param>
|
/// <param name="ProcessName"></param>
|
/// <param name="ClassName"></param>
|
/// <param name="ProcessPath"></param>
|
/// <param name="listProcesses"></param>
|
public bool AddStep(string Name, string ProcessName, string ClassName, string ProcessPath)
|
{
|
try
|
{
|
if (nodesControl == null || !(nodesControl.Context is ProcessContext))
|
return false;
|
|
if (((ProcessContext)nodesControl.Context).dicContext.ContainsKey(ProcessName))
|
{
|
LogInfo?.Invoke(string.Format("流程[{0}]已存在步骤[{1}]添加失败", Name, ProcessName), LogInfoType.WARN);
|
return false;
|
}
|
|
//利用反射进行创建
|
if (ClassName.Contains("Cameras"))
|
{
|
Type type = IProcess.GetExecutingAssembly().GetType(ClassName.Split(',')[0]);
|
if (type == null)
|
{
|
Debug.WriteLine("Class not found.");
|
return false;
|
}
|
CameraConfig CameraConfig = Activator.CreateInstance(type, new object[] { dicCameras.Items }) as CameraConfig;
|
if (CameraConfig == null)
|
{
|
Debug.WriteLine("Cameras not found.");
|
return false;
|
}
|
CameraConfig.Load(ProcessPath);
|
CameraConfig.strProcessName = ProcessName;
|
AddInputsAndOutputs(CameraConfig.strProcessName, CameraConfig);
|
}
|
else if (ClassName.Contains("Communicators"))
|
{
|
Type type = IProcess.GetExecutingAssembly().GetType(ClassName.Split(',')[0]);
|
if (type == null)
|
{
|
Debug.WriteLine("Class not found.");
|
return false;
|
}
|
|
CommunicatorConfig CommunicatorConfig = Activator.CreateInstance(type, new object[] { dicCommunicators.Items }) as CommunicatorConfig;
|
if (CommunicatorConfig == null)
|
{
|
Debug.WriteLine("Communicators not found.");
|
return false;
|
}
|
CommunicatorConfig.Load(ProcessPath);
|
CommunicatorConfig.strProcessName = ProcessName;
|
AddInputsAndOutputs(CommunicatorConfig.strProcessName, CommunicatorConfig);
|
}
|
else if (!string.IsNullOrEmpty(ClassName))
|
{
|
//利用反射进行创建
|
Type type = IProcess.GetExecutingAssembly().GetType(ClassName.Split(',')[0]);
|
if (type == null)
|
{
|
Debug.WriteLine("Class not found.");
|
return false;
|
}
|
IProcess process = Activator.CreateInstance(type) as IProcess;
|
if (process == null)
|
{
|
Debug.WriteLine("IProcess not found.");
|
return false;
|
}
|
|
process.Load(ProcessPath);
|
process.strProcessName = ProcessName;
|
|
//if (process is VisionProTool && Tool.ContainsChinese(ProcessName))
|
// MessageBox.Show($"VisionPro工具不支持命名为中文:{ProcessName}", "异常");
|
|
if (process is ScriptTool script)
|
{
|
if (script.Params.Outputs.Count <= 0)
|
script.Params.Outputs.Add("Branch0", true);
|
|
if (script.Params.Outputs.Count <= 1)
|
script.Params.Outputs.Add("Branch1", false);
|
}
|
|
AddInputsAndOutputs(process.strProcessName, process);
|
}
|
|
LogInfo?.Invoke(string.Format("流程[{0}]添加步骤[{1}]", Name, ProcessName), LogInfoType.INFO);
|
return true;
|
}
|
catch (Exception ex) { Debug.WriteLine("AddProcessToList失败,原因是" + ex.Message.ToString()); return false; }
|
}
|
|
public void AddInputsAndOutputs(string name, IProcess obj)
|
{
|
try
|
{
|
if (obj == null)
|
return;
|
|
if (nodesControl.Context == null || !(nodesControl.Context is ProcessContext))
|
return;
|
|
((ProcessContext)nodesControl.Context).dicContext.TryAdd(name, obj);
|
|
if (obj is IProcess process)
|
{
|
if (!dicInputsMapping.ContainsKey(name))
|
{
|
dicInputsMapping.TryAdd(name, new List<Tuple<string, string>>());
|
dicInputsMapping[name].Add(new Tuple<string, string>(name + ".Inputs.Image", ""));
|
//dicInputsMapping[name].Add(new Tuple<string, string>(name + ".Inputs.Fixture", ""));
|
|
foreach (var item in process.Params.Inputs)
|
dicInputsMapping[name].Add(new Tuple<string, string>(name + ".Inputs." + item.Name, ""));
|
}
|
|
if (!dicOutputsMapping.ContainsKey(name))
|
{
|
dicOutputsMapping.TryAdd(name, new List<string>());
|
dicOutputsMapping[name].Add(name + ".Outputs.Image");
|
dicOutputsMapping[name].Add(name + ".Outputs.Record");
|
dicOutputsMapping[name].Add(name + ".Outputs.Result");
|
//dicOutputsMapping[name].Add(name + ".Outputs.Fixture");
|
|
foreach (var item in process.Params.Outputs)
|
dicOutputsMapping[name].Add(name + ".Outputs." + item.Name);
|
}
|
|
CompileMappings();
|
}
|
}
|
catch { }
|
}
|
|
public void CompileMappings()
|
{
|
try
|
{
|
if (ProcessContext != null)
|
{
|
ProcessContext.CompileMappings();
|
}
|
}
|
catch { }
|
}
|
|
|
public void UpdataInputsAndOutputs(string name, IProcess obj)
|
{
|
if (obj == null)
|
return;
|
|
if (obj is IProcess process)
|
{
|
if (dicInputsMapping.ContainsKey(name))
|
{
|
foreach (var item in process.Params.Inputs)
|
{
|
if (dicInputsMapping[name].Where(x => x.Item1 == name + ".Inputs." + item.Name).Count() == 0)
|
dicInputsMapping[name].Add(new Tuple<string, string>(name + ".Inputs." + item.Name, ""));
|
}
|
}
|
|
if (dicOutputsMapping.ContainsKey(name))
|
{
|
foreach (var item in process.Params.Outputs)
|
{
|
if (dicOutputsMapping[name].Where(x => x == name + ".Outputs." + item.Name).Count() == 0)
|
dicOutputsMapping[name].Add(name + ".Outputs." + item.Name);
|
}
|
}
|
|
CompileMappings();
|
}
|
}
|
|
public bool Remove(string ProcessName)
|
{
|
try
|
{
|
if (ProcessContext == null)
|
return false;
|
|
ConcurrentDictionary<string, IProcess> dicSteps = GetSteps();
|
if (!dicSteps.ContainsKey(ProcessName))
|
return false;
|
|
Object obj = dicSteps[ProcessName];
|
|
if (obj == null)
|
return false;
|
|
string strProcessName = ((IProcess)obj).strProcessName;
|
if (!string.IsNullOrEmpty(strProcessName))
|
{
|
dicInputsMapping.TryRemove(strProcessName, out List<Tuple<string, string>> tempInputs);
|
dicOutputsMapping.TryRemove(strProcessName, out List<string> tempOutputs);
|
if (dicSteps.TryRemove(strProcessName, out IProcess tempObj))
|
LogInfo?.Invoke(string.Format("流程[{0}]移除步骤[{1}]", Name, strProcessName), LogInfoType.INFO);
|
else
|
LogInfo?.Invoke(string.Format("流程[{0}]移除步骤[{1}]失败", Name, strProcessName), LogInfoType.WARN);
|
SaveInputs();
|
SaveOutputs();
|
|
CompileMappings();
|
return true;
|
}
|
return false;
|
}
|
catch { return false; }
|
}
|
|
void Rename(IProcess obj, string newName)
|
{
|
if (obj == null)
|
return;
|
|
((IProcess)obj).strProcessName = newName;
|
LogInfo?.Invoke(string.Format("流程[{0}]重命名步骤[{1}]", Name, newName), LogInfoType.INFO);
|
}
|
|
/// <summary>
|
/// 重命名步骤(!不是重命名流程!)
|
/// </summary>
|
/// <param name="oldName"></param>
|
/// <param name="newName"></param>
|
public void Rename(string oldName, string newName)
|
{
|
if (ProcessContext == null)
|
return;
|
|
var dicSteps = GetSteps();
|
if (!dicSteps.ContainsKey(oldName))
|
return;
|
|
dicSteps.TryRemove(oldName, out IProcess process);
|
dicSteps.TryAdd(newName, process);
|
|
Rename(process, newName);
|
|
ConcurrentDictionary<string, List<Tuple<string, string>>> dicInputsMapping = new ConcurrentDictionary<string, List<Tuple<string, string>>>();
|
foreach (var InputsMapping in this.dicInputsMapping)
|
{
|
if (InputsMapping.Key == oldName)
|
{
|
List<Tuple<string, string>> tempTuples = new List<Tuple<string, string>>();
|
foreach (var tuple in InputsMapping.Value)
|
{
|
string[] arrInputs = tuple.Item1.Split(".");
|
string InputProcessName = arrInputs[0];
|
string strInput = arrInputs[1];
|
string InputValueName = arrInputs[2];
|
|
string Input = "";
|
if (InputProcessName == oldName)
|
Input = newName + "." + strInput + "." + InputValueName;
|
else
|
Input = tuple.Item1;
|
|
tempTuples.Add(Tuple.Create(Input, tuple.Item2));
|
}
|
dicInputsMapping.TryAdd(newName, tempTuples);
|
}
|
else
|
{
|
List<Tuple<string, string>> tempTuples = new List<Tuple<string, string>>();
|
foreach (var tuple in InputsMapping.Value)
|
{
|
string[] arrInputs = tuple.Item1.Split(".");
|
if (arrInputs.Length < 3)
|
{
|
tempTuples.Add(tuple);
|
continue;
|
}
|
|
string InputProcessName = arrInputs[0];
|
string strInput = arrInputs[1];
|
string InputValueName = arrInputs[2];
|
|
string[] arrOutputs = tuple.Item2.Split(".");
|
if (arrOutputs.Length < 3)
|
{
|
tempTuples.Add(tuple);
|
continue;
|
}
|
|
string IndexProcessName = arrOutputs[0];
|
string IndexIsInputOrOutput = arrOutputs[1];
|
string IndexValueName = arrOutputs[2];
|
|
if (IndexProcessName == oldName)
|
{
|
tempTuples.Add(new Tuple<string, string>(tuple.Item1
|
, string.Format("{0}.{1}.{2}", newName, IndexIsInputOrOutput, IndexValueName)));
|
}
|
else
|
tempTuples.Add(tuple);
|
}
|
|
dicInputsMapping.TryAdd(InputsMapping.Key, tempTuples);
|
}
|
}
|
this.dicInputsMapping = ProcessContext.dicInputsMapping = dicInputsMapping;
|
|
ConcurrentDictionary<string, List<string>> dicOutputsMapping = new ConcurrentDictionary<string, List<string>>();
|
foreach (var OutputsMapping in this.dicOutputsMapping)
|
{
|
if (OutputsMapping.Key == oldName)
|
{
|
List<string> listOutputs = new List<string>();
|
foreach (string Output in OutputsMapping.Value)
|
{
|
string[] arrOutputs = Output.Split(".");
|
if (arrOutputs.Length < 3)
|
{
|
listOutputs.Add(Output);
|
continue;
|
}
|
|
string IndexProcessName = arrOutputs[0];
|
string IndexIsInputOrOutput = arrOutputs[1];
|
string IndexValueName = arrOutputs[2];
|
|
if (IndexProcessName == oldName)
|
{
|
listOutputs.Add(string.Format("{0}.{1}.{2}", newName, IndexIsInputOrOutput, IndexValueName));
|
}
|
else
|
listOutputs.Add(Output);
|
}
|
dicOutputsMapping.TryAdd(newName, listOutputs);
|
}
|
else
|
dicOutputsMapping.TryAdd(OutputsMapping.Key, OutputsMapping.Value);
|
}
|
this.dicOutputsMapping = ProcessContext.dicOutputsMapping = dicOutputsMapping;
|
|
SaveInputs();
|
SaveOutputs();
|
|
CompileMappings();
|
}
|
|
double total_OK;
|
double total_NG;
|
|
public double total
|
{
|
get { return total_OK + total_NG; }
|
}
|
|
public double Rate_OK
|
{
|
get
|
{
|
if (total == 0)
|
return 100;
|
return (total_OK / total) * 100;
|
}
|
}
|
|
public void ClearTotal()
|
{
|
total_OK = 0;
|
total_NG = 0;
|
}
|
|
/// <summary>
|
/// 调用Run必须是在Inovk中否则会报线程错误,该类的Run调用需要封装在UI内
|
/// </summary>
|
/// <param name="control"></param>
|
/// <returns></returns>
|
public bool Run()
|
{
|
bRuning = true;
|
bCompleted = false;
|
DateTime StartTime = DateTime.Now;
|
try
|
{
|
Result = true;
|
if (!nodesControl.Run(out string msg) && !string.IsNullOrEmpty(msg))
|
{
|
Msg += $"【{msg}】";
|
Result &= false;
|
}
|
}
|
catch (Exception ex)
|
{
|
Result = false;
|
Msg = string.Format("运行发送了意外{0}", ex.Message.Trim());
|
}
|
RunTime = (DateTime.Now - StartTime).TotalMilliseconds;
|
bRuning = false;
|
bCompleted = true;
|
if (Result)
|
{
|
total_OK++;
|
Msg = "运行成功";
|
}
|
else
|
{
|
total_NG++;
|
}
|
if (IProcess.dicGlobalVars.ContainsKey($"{Name}.Result"))
|
{
|
IProcess.dicGlobalVars[$"{Name}.Result"] = Result;
|
}
|
else
|
{
|
IProcess.dicGlobalVars.TryAdd($"{Name}.Result", Result);
|
}
|
if (IProcess.dicGlobalVars.ContainsKey($"{Name}.Msg"))
|
{
|
IProcess.dicGlobalVars[$"{Name}.Msg"] = Msg;
|
}
|
else
|
{
|
IProcess.dicGlobalVars.TryAdd($"{Name}.Msg", Msg);
|
}
|
// 手动触发垃圾回收
|
GC.Collect();
|
return Result;
|
}
|
|
public void LogoInfo(string info, LogInfoType logInfoType)
|
{
|
LogInfo?.Invoke(info, logInfoType);
|
}
|
}
|
}
|