添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,314 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Filewritable;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class FlowStageMappingRule
|
||||
{
|
||||
public string WorkflowName { get; set; }
|
||||
public string ParentActivityName { get; set; }
|
||||
public string ActivityName { get; set; }
|
||||
public FlowDisplayStage Stage { get; set; }
|
||||
public string DisplayFlowName { get; set; }
|
||||
}
|
||||
|
||||
public class FlowStageMappingConfig
|
||||
{
|
||||
public List<FlowStageMappingRule> Rules { get; } = new List<FlowStageMappingRule>();
|
||||
|
||||
public static string DefaultConfigPath => Path.Combine(Paths.BasePath, "Configuration", "FlowStageMapping.json");
|
||||
|
||||
public FlowDisplayStage Resolve(string workflowName, string parentActivityName, string activityName)
|
||||
{
|
||||
var rule = ResolveRule(workflowName, parentActivityName, activityName);
|
||||
|
||||
return rule?.Stage ?? FlowDisplayStage.Align;
|
||||
}
|
||||
|
||||
public string ResolveDisplayFlowName(string workflowName, string parentActivityName, string activityName)
|
||||
{
|
||||
var rule = ResolveRule(workflowName, parentActivityName, activityName);
|
||||
if (rule != null && !string.IsNullOrWhiteSpace(rule.DisplayFlowName))
|
||||
{
|
||||
return rule.DisplayFlowName;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(parentActivityName)) return parentActivityName;
|
||||
return workflowName;
|
||||
}
|
||||
|
||||
private FlowStageMappingRule ResolveRule(string workflowName, string parentActivityName, string activityName)
|
||||
{
|
||||
return Rules.FirstOrDefault(r =>
|
||||
Match(r.WorkflowName, workflowName) &&
|
||||
Match(r.ParentActivityName, parentActivityName) &&
|
||||
Match(r.ActivityName, activityName));
|
||||
}
|
||||
|
||||
private static bool Match(string expected, string actual)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(expected) || expected == "*") return true;
|
||||
if (expected.IndexOf('*') >= 0)
|
||||
{
|
||||
var source = actual ?? string.Empty;
|
||||
var parts = expected.Split(new[] { '*' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var index = 0;
|
||||
foreach (var part in parts)
|
||||
{
|
||||
var found = source.IndexOf(part, index, StringComparison.OrdinalIgnoreCase);
|
||||
if (found < 0) return false;
|
||||
index = found + part.Length;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return string.Equals(expected, actual ?? string.Empty, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static FlowStageMappingConfig LoadOrCreate(string filePath = null)
|
||||
{
|
||||
var path = string.IsNullOrWhiteSpace(filePath) ? DefaultConfigPath : filePath;
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrWhiteSpace(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
var def = CreateDefault();
|
||||
def.Save(path);
|
||||
return def;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var loaded = Load(path);
|
||||
if (loaded == null || loaded.Rules.Count == 0)
|
||||
{
|
||||
throw new InvalidDataException("FlowStageMapping config is empty.");
|
||||
}
|
||||
loaded.Normalize();
|
||||
return loaded;
|
||||
}
|
||||
catch
|
||||
{
|
||||
var def = CreateDefault();
|
||||
def.Save(path);
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(string filePath = null)
|
||||
{
|
||||
var path = string.IsNullOrWhiteSpace(filePath) ? DefaultConfigPath : filePath;
|
||||
var ext = Path.GetExtension(path)?.ToLowerInvariant();
|
||||
|
||||
Normalize();
|
||||
|
||||
var data = new FlowStageMappingFile { Rules = Rules.ToList() };
|
||||
|
||||
if (ext == ".xml")
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(FlowStageMappingFile));
|
||||
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None))
|
||||
{
|
||||
serializer.Serialize(fs, data);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(data, Formatting.Indented);
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
|
||||
public static FlowStageMappingConfig Load(string filePath)
|
||||
{
|
||||
var ext = Path.GetExtension(filePath)?.ToLowerInvariant();
|
||||
FlowStageMappingFile data;
|
||||
|
||||
if (ext == ".xml")
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(FlowStageMappingFile));
|
||||
using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
data = serializer.Deserialize(fs) as FlowStageMappingFile;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var json = File.ReadAllText(filePath);
|
||||
data = JsonConvert.DeserializeObject<FlowStageMappingFile>(json);
|
||||
}
|
||||
|
||||
var cfg = new FlowStageMappingConfig();
|
||||
if (data != null && data.Rules != null)
|
||||
{
|
||||
cfg.Rules.AddRange(data.Rules);
|
||||
}
|
||||
|
||||
cfg.Normalize();
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
private void Normalize()
|
||||
{
|
||||
foreach (var rule in Rules)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(rule.DisplayFlowName) &&
|
||||
!string.IsNullOrWhiteSpace(rule.WorkflowName) &&
|
||||
!string.Equals(rule.WorkflowName, ProcessFlowName.AutoProduction, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
rule.DisplayFlowName = rule.WorkflowName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FlowStageMappingConfig CreateDefault()
|
||||
{
|
||||
var cfg = new FlowStageMappingConfig();
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.SubstrateLoadFlow,
|
||||
ParentActivityName = "*",
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Load,
|
||||
DisplayFlowName = ProcessFlowName.SubstrateLoadFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.SubstratePositionFlow,
|
||||
ParentActivityName = "*",
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Align,
|
||||
DisplayFlowName = ProcessFlowName.SubstratePositionFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.ChipStraighteningFlow,
|
||||
ParentActivityName = "*",
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Align,
|
||||
DisplayFlowName = ProcessFlowName.ChipStraighteningFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.DiePositionFlow,
|
||||
ParentActivityName = "*",
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Align,
|
||||
DisplayFlowName = ProcessFlowName.DiePositionFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.DieTransferFlow,
|
||||
ParentActivityName = "*",
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Bond,
|
||||
DisplayFlowName = ProcessFlowName.DieTransferFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.DieRecheckFlow,
|
||||
ParentActivityName = "*",
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Inspect,
|
||||
DisplayFlowName = ProcessFlowName.DieRecheckFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.SubstrateUnloadFlow,
|
||||
ParentActivityName = "*",
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Unload,
|
||||
DisplayFlowName = ProcessFlowName.SubstrateUnloadFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.AutoProduction,
|
||||
ParentActivityName = ProcessFlowName.SubstrateLoadFlow,
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Load,
|
||||
DisplayFlowName = ProcessFlowName.SubstrateLoadFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.AutoProduction,
|
||||
ParentActivityName = ProcessFlowName.SubstratePositionFlow,
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Align,
|
||||
DisplayFlowName = ProcessFlowName.SubstratePositionFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.AutoProduction,
|
||||
ParentActivityName = ProcessFlowName.ChipStraighteningFlow,
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Align,
|
||||
DisplayFlowName = ProcessFlowName.ChipStraighteningFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.AutoProduction,
|
||||
ParentActivityName = ProcessFlowName.DiePositionFlow,
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Align,
|
||||
DisplayFlowName = ProcessFlowName.DiePositionFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.AutoProduction,
|
||||
ParentActivityName = ProcessFlowName.DieTransferFlow,
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Bond,
|
||||
DisplayFlowName = ProcessFlowName.DieTransferFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.AutoProduction,
|
||||
ParentActivityName = ProcessFlowName.DieRecheckFlow,
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Inspect,
|
||||
DisplayFlowName = ProcessFlowName.DieRecheckFlow
|
||||
});
|
||||
|
||||
cfg.Rules.Add(new FlowStageMappingRule
|
||||
{
|
||||
WorkflowName = ProcessFlowName.AutoProduction,
|
||||
ParentActivityName = ProcessFlowName.SubstrateUnloadFlow,
|
||||
ActivityName = "*",
|
||||
Stage = FlowDisplayStage.Unload,
|
||||
DisplayFlowName = ProcessFlowName.SubstrateUnloadFlow
|
||||
});
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
[XmlRoot("FlowStageMapping")]
|
||||
public class FlowStageMappingFile
|
||||
{
|
||||
[XmlArray("Rules")]
|
||||
[XmlArrayItem("Rule")]
|
||||
public List<FlowStageMappingRule> Rules { get; set; } = new List<FlowStageMappingRule>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
using MainShell.Common;
|
||||
using MainShell.Filewritable;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace MainShell.Process
|
||||
{
|
||||
public class WaferHandlingFlowNodeRule
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public List<string> ActivityKeywords { get; set; } = new List<string>();
|
||||
public List<string> WorkflowKeywords { get; set; } = new List<string>();
|
||||
public List<string> ParentKeywords { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
public class WaferHandlingFlowConfig
|
||||
{
|
||||
public List<WaferHandlingFlowNodeRule> Nodes { get; } = new List<WaferHandlingFlowNodeRule>();
|
||||
|
||||
public static string DefaultConfigPath => Path.Combine(Paths.BasePath, "Configuration", "WaferHandlingFlow.json");
|
||||
|
||||
public static WaferHandlingFlowConfig LoadOrCreate(string filePath = null)
|
||||
{
|
||||
var path = string.IsNullOrWhiteSpace(filePath) ? DefaultConfigPath : filePath;
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrWhiteSpace(dir))
|
||||
{
|
||||
Directory.CreateDirectory(dir);
|
||||
}
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
var def = CreateDefault();
|
||||
def.Save(path);
|
||||
return def;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var loaded = Load(path);
|
||||
if (loaded == null || loaded.Nodes.Count == 0)
|
||||
{
|
||||
throw new InvalidDataException("WaferHandlingFlow config is empty.");
|
||||
}
|
||||
loaded.Normalize();
|
||||
return loaded;
|
||||
}
|
||||
catch
|
||||
{
|
||||
var def = CreateDefault();
|
||||
def.Save(path);
|
||||
return def;
|
||||
}
|
||||
}
|
||||
|
||||
public static WaferHandlingFlowConfig Load(string filePath)
|
||||
{
|
||||
var json = File.ReadAllText(filePath);
|
||||
var data = JsonConvert.DeserializeObject<WaferHandlingFlowFile>(json);
|
||||
|
||||
var cfg = new WaferHandlingFlowConfig();
|
||||
if (data?.Nodes != null)
|
||||
{
|
||||
cfg.Nodes.AddRange(data.Nodes);
|
||||
}
|
||||
|
||||
cfg.Normalize();
|
||||
return cfg;
|
||||
}
|
||||
|
||||
public void Save(string filePath = null)
|
||||
{
|
||||
var path = string.IsNullOrWhiteSpace(filePath) ? DefaultConfigPath : filePath;
|
||||
Normalize();
|
||||
|
||||
var data = new WaferHandlingFlowFile
|
||||
{
|
||||
Nodes = Nodes.ToList()
|
||||
};
|
||||
|
||||
var json = JsonConvert.SerializeObject(data, Formatting.Indented);
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
|
||||
public string ResolveNodeKey(string workflowName, string parentActivityName, string activityName)
|
||||
{
|
||||
var activity = activityName ?? string.Empty;
|
||||
var workflow = workflowName ?? string.Empty;
|
||||
var parent = parentActivityName ?? string.Empty;
|
||||
|
||||
var rule = Nodes.FirstOrDefault(n => IsMatch(n, activity, workflow, parent));
|
||||
return rule?.Key;
|
||||
}
|
||||
|
||||
private static bool IsMatch(WaferHandlingFlowNodeRule node, string activity, string workflow, string parent)
|
||||
{
|
||||
if (node == null) return false;
|
||||
|
||||
return ContainsAny(activity, node.ActivityKeywords) ||
|
||||
ContainsAny(workflow, node.WorkflowKeywords) ||
|
||||
ContainsAny(parent, node.ParentKeywords);
|
||||
}
|
||||
|
||||
private static bool ContainsAny(string source, List<string> keywords)
|
||||
{
|
||||
if (keywords == null || keywords.Count == 0) return false;
|
||||
|
||||
foreach (var keyword in keywords)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(keyword)) continue;
|
||||
if ((source ?? string.Empty).IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void Normalize()
|
||||
{
|
||||
Nodes.RemoveAll(n => n == null || string.IsNullOrWhiteSpace(n.Key));
|
||||
|
||||
foreach (var node in Nodes)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(node.DisplayName))
|
||||
{
|
||||
node.DisplayName = node.Key;
|
||||
}
|
||||
|
||||
node.ActivityKeywords = node.ActivityKeywords ?? new List<string>();
|
||||
node.WorkflowKeywords = node.WorkflowKeywords ?? new List<string>();
|
||||
node.ParentKeywords = node.ParentKeywords ?? new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
public static WaferHandlingFlowConfig CreateDefault()
|
||||
{
|
||||
var cfg = new WaferHandlingFlowConfig();
|
||||
|
||||
cfg.Nodes.Add(new WaferHandlingFlowNodeRule
|
||||
{
|
||||
Key = "WaferLoad",
|
||||
DisplayName = "<22><>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD>",
|
||||
ActivityKeywords = new List<string> { "ChipLoad", ProcessFlowName.ChipLoadExecuteActivity }
|
||||
});
|
||||
|
||||
cfg.Nodes.Add(new WaferHandlingFlowNodeRule
|
||||
{
|
||||
Key = "WaferSupply",
|
||||
DisplayName = "<22><>Ƭ<C6AC><D7BC>",
|
||||
WorkflowKeywords = new List<string>
|
||||
{
|
||||
ProcessFlowName.ChipStraighteningFlow,
|
||||
ProcessFlowName.DiePositionFlow,
|
||||
ProcessFlowName.DieTransferFlow,
|
||||
ProcessFlowName.DieRecheckFlow
|
||||
},
|
||||
ParentKeywords = new List<string> { "DieAlign", "DieBond", "Inspect" }
|
||||
});
|
||||
|
||||
cfg.Nodes.Add(new WaferHandlingFlowNodeRule
|
||||
{
|
||||
Key = "WaferUnload",
|
||||
DisplayName = "<22><>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD>",
|
||||
ActivityKeywords = new List<string> { "ChipUnload", ProcessFlowName.ChipUnloadExecuteActivity }
|
||||
});
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
public class WaferHandlingFlowFile
|
||||
{
|
||||
public List<WaferHandlingFlowNodeRule> Nodes { get; set; } = new List<WaferHandlingFlowNodeRule>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user