Files
test_demo/MX-PD-盘古 - new/PanGu.DieBonderApp/MainShell/DeviceMaintance/Model/CylinderDefinitionLoader.cs

210 lines
7.3 KiB
C#
Raw Normal View History

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace MainShell.DeviceMaintance.Model
{
public static class CylinderDefinitionLoader
{
private const string CylinderConfigFileName = "CylinderDefinitions.csv";
public static IReadOnlyList<CylinderDefinition> LoadDefinitions()
{
var definitions = new List<CylinderDefinition>();
var path = ResolveConfigPath();
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
{
return definitions;
}
var lines = File.ReadAllLines(path, Encoding.UTF8);
foreach (var raw in lines)
{
if (string.IsNullOrWhiteSpace(raw))
{
continue;
}
var line = raw.Trim();
if (line.StartsWith("#") || line.StartsWith("Name", StringComparison.OrdinalIgnoreCase))
{
continue;
}
var cols = line.Split(',');
if (cols.Length < 7)
{
continue;
}
var extendOutputPoints = ParsePointReferences(cols[3]);
if (extendOutputPoints.Count == 0)
{
continue;
}
var retractOutputPoints = ParsePointReferences(cols[4]);
var hasConditionColumns = cols.Length >= 10;
var extendConditionIndex = hasConditionColumns ? 7 : -1;
var retractConditionIndex = hasConditionColumns ? 8 : -1;
var descriptionIndex = hasConditionColumns ? 9 : 7;
definitions.Add(new CylinderDefinition
{
Name = cols[0].Trim(),
Module = cols[1].Trim(),
ControlType = ParseControlType(cols[2]),
ExtendOutputPoints = extendOutputPoints,
RetractOutputPoints = retractOutputPoints,
ExtendedFeedbackPoints = ParsePointReferences(cols[5]),
RetractedFeedbackPoints = ParsePointReferences(cols[6]),
ExtendConditions = extendConditionIndex >= 0 ? ParseConditions(cols[extendConditionIndex]) : new List<CylinderActionConditionDefinition>(),
RetractConditions = retractConditionIndex >= 0 ? ParseConditions(cols[retractConditionIndex]) : new List<CylinderActionConditionDefinition>(),
Description = cols.Length > descriptionIndex ? string.Join(",", cols.Skip(descriptionIndex)).Trim() : string.Empty
});
}
return definitions;
}
private static CylinderControlType ParseControlType(string raw)
{
if (string.Equals(raw, "DualOutput", StringComparison.OrdinalIgnoreCase) ||
string.Equals(raw, "Dual", StringComparison.OrdinalIgnoreCase))
{
return CylinderControlType.DualOutput;
}
if (string.Equals(raw, "MultiOutput", StringComparison.OrdinalIgnoreCase) ||
string.Equals(raw, "Multi", StringComparison.OrdinalIgnoreCase))
{
return CylinderControlType.MultiOutput;
}
return CylinderControlType.SingleOutput;
}
private static List<string> ParsePointReferences(string raw)
{
return (raw ?? string.Empty)
.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => x.Trim())
.Where(x => !string.IsNullOrWhiteSpace(x))
.ToList();
}
private static List<CylinderActionConditionDefinition> ParseConditions(string raw)
{
return (raw ?? string.Empty)
.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
.Select(ParseCondition)
.Where(x => x != null)
.ToList();
}
private static CylinderActionConditionDefinition ParseCondition(string raw)
{
if (string.IsNullOrWhiteSpace(raw))
{
return null;
}
var parts = raw.Split(new[] { ':' }, 3);
if (parts.Length < 2)
{
return null;
}
var pointReference = parts[1].Trim();
if (string.IsNullOrWhiteSpace(pointReference))
{
return null;
}
CylinderConditionType conditionType;
switch ((parts[0] ?? string.Empty).Trim().ToUpperInvariant())
{
case "POINTON":
case "ON":
conditionType = CylinderConditionType.PointOn;
break;
case "POINTOFF":
case "OFF":
conditionType = CylinderConditionType.PointOff;
break;
default:
return null;
}
return new CylinderActionConditionDefinition
{
ConditionType = conditionType,
PointReference = pointReference,
Message = parts.Length > 2 ? parts[2].Trim() : string.Empty
};
}
private static string ResolveConfigPath()
{
var baseDir = AppDomain.CurrentDomain.BaseDirectory;
var localPath = Path.Combine(baseDir, "Configuration", CylinderConfigFileName);
var sourcePath = ResolveRootConfigPath(baseDir);
if (TrySyncConfigToLocal(sourcePath, localPath))
{
return localPath;
}
return File.Exists(localPath) ? localPath : sourcePath;
}
private static string ResolveRootConfigPath(string baseDir)
{
var current = new DirectoryInfo(baseDir);
while (current != null)
{
var rootConfigDir = Path.Combine(current.FullName, "Configuration");
if (Directory.Exists(rootConfigDir) && Directory.Exists(Path.Combine(current.FullName, "MainShell")))
{
var path = Path.Combine(rootConfigDir, CylinderConfigFileName);
if (File.Exists(path))
{
return path;
}
}
current = current.Parent;
}
return null;
}
private static bool TrySyncConfigToLocal(string sourcePath, string localPath)
{
if (string.IsNullOrWhiteSpace(sourcePath) || !File.Exists(sourcePath))
{
return false;
}
if (!string.Equals(Path.GetFullPath(sourcePath), Path.GetFullPath(localPath), StringComparison.OrdinalIgnoreCase))
{
var localDir = Path.GetDirectoryName(localPath);
if (!string.IsNullOrWhiteSpace(localDir))
{
Directory.CreateDirectory(localDir);
}
if (!File.Exists(localPath) || File.GetLastWriteTimeUtc(localPath) < File.GetLastWriteTimeUtc(sourcePath))
{
File.Copy(sourcePath, localPath, true);
}
}
return true;
}
}
}