添加 MX-PD-盘古 项目文件
将 MX-PD-盘古 - new 目录下的所有文件添加到主仓库
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MXJM.FileWritable
|
||||
{
|
||||
public abstract class FileWriteBase : IFileWritable
|
||||
{
|
||||
public string Description { get;protected set; }
|
||||
public object UserData { get; set ; }
|
||||
|
||||
public virtual void Save()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public virtual Task SaveAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
using MainShell.Log;
|
||||
using MaxwellFramework.Core.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MXJM.FileWritable
|
||||
{
|
||||
public class FileWriteQueue : IDisposable
|
||||
{
|
||||
private readonly Channel<IFileWritable> _fileChannel;
|
||||
private readonly int _capacity;
|
||||
private bool _isClosed = false;
|
||||
|
||||
public FileWriteQueue(int capacity = 50)
|
||||
{
|
||||
_capacity = capacity;
|
||||
var options = new BoundedChannelOptions(capacity)
|
||||
{
|
||||
FullMode = BoundedChannelFullMode.Wait
|
||||
};
|
||||
_fileChannel = Channel.CreateBounded<IFileWritable>(options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 当前队列长度
|
||||
/// </summary>
|
||||
public int Count => _fileChannel.Reader.Count;
|
||||
|
||||
/// <summary>
|
||||
/// 队列容量
|
||||
/// </summary>
|
||||
public int Capacity => _capacity;
|
||||
|
||||
/// <summary>
|
||||
/// 入队(同步,立即返回是否成功)
|
||||
/// </summary>
|
||||
public bool Enqueue(IFileWritable fileWritable)
|
||||
{
|
||||
if (_isClosed) return false;
|
||||
return _fileChannel.Writer.TryWrite(fileWritable);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 入队(异步,支持等待)
|
||||
/// </summary>
|
||||
public async Task<bool> EnqueueAsync(IFileWritable fileWritable, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (_isClosed) return false;
|
||||
try
|
||||
{
|
||||
await _fileChannel.Writer.WriteAsync(fileWritable, cancellationToken);
|
||||
return true;
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex, "EnqueueAsync", fileWritable.Description);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理队列
|
||||
/// </summary>
|
||||
public async Task ProcessQueueAsync(CancellationToken cancellationToken = default, bool throwOnError = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (await _fileChannel.Reader.WaitToReadAsync(cancellationToken))
|
||||
{
|
||||
while (_fileChannel.Reader.TryRead(out IFileWritable fileWritable))
|
||||
{
|
||||
try
|
||||
{
|
||||
await Task.Run(() => fileWritable.Save(), cancellationToken);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex, "ProcessQueueAsync", fileWritable.Description);
|
||||
if (throwOnError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
if (throwOnError)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭队列,不再接受新任务
|
||||
/// </summary>
|
||||
public void Close()
|
||||
{
|
||||
if (!_isClosed)
|
||||
{
|
||||
_isClosed = true;
|
||||
_fileChannel.Writer.TryComplete();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 释放资源
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private void LogException(Exception ex, string method,string description)
|
||||
{
|
||||
LogManager.LogSysError($"{description}:[FileWriteQueue][{method}] 异常: {ex}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MXJM.FileWritable
|
||||
{
|
||||
public interface IFileWritable
|
||||
{
|
||||
string Description { get; }
|
||||
/// <summary>
|
||||
/// 用户数据
|
||||
/// </summary>
|
||||
object UserData { get; set; }
|
||||
/// <summary>
|
||||
/// 执行文件保存操作
|
||||
/// </summary>
|
||||
Task SaveAsync(CancellationToken cancellationToken = default);
|
||||
/// <summary>
|
||||
/// 同步保存文件
|
||||
/// </summary>
|
||||
void Save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Filewritable
|
||||
{
|
||||
public class IgnorePropertiesResolver : DefaultContractResolver
|
||||
{
|
||||
private readonly HashSet<string> _ignoreProps;
|
||||
public IgnorePropertiesResolver(IEnumerable<string> propNames) =>
|
||||
_ignoreProps = new HashSet<string>(propNames);
|
||||
|
||||
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
|
||||
{
|
||||
var p = base.CreateProperty(member, memberSerialization);
|
||||
if (_ignoreProps.Contains(p.PropertyName))
|
||||
p.Ignored = true;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
using MainShell.Filewritable;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MXJM.FileWritable
|
||||
{
|
||||
/// <summary>
|
||||
/// 通用的 JSON 可保存/加载基类,供任意需要持久化为 JSON 的类继承。
|
||||
/// 派生类可覆盖 Dir / FileName 指定保存位置与文件名。
|
||||
/// </summary>
|
||||
public abstract class JsonFileWritableBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 存储目录,派生类可覆盖。默认为应用程序基目录。
|
||||
/// 标记为 JsonIgnore 避免被序列化到文件中。
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public virtual string Dir => Paths.RecipeBasePath;
|
||||
[JsonIgnore]
|
||||
public virtual IgnorePropertiesResolver IgnorePropertiesResolver =>new IgnorePropertiesResolver(new string[] { "PropertyChangedDispatcher" });
|
||||
/// <summary>
|
||||
/// 文件名,派生类可覆盖。
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public virtual string FileName => $"{GetType().Name}.json";
|
||||
|
||||
/// <summary>
|
||||
/// 将当前实例以 JSON 形式保存到 Dir/FileName。
|
||||
/// </summary>
|
||||
public void Write()
|
||||
{
|
||||
var dir = Dir ?? string.Empty;
|
||||
if (!Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
var path = Path.Combine(dir, FileName ?? "data.json");
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
||||
ContractResolver = IgnorePropertiesResolver
|
||||
};
|
||||
var json = JsonConvert.SerializeObject(this, settings);
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
public void Write(string path)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
|
||||
ContractResolver= IgnorePropertiesResolver
|
||||
};
|
||||
var json = JsonConvert.SerializeObject(this, settings);
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
/// <summary>
|
||||
/// 异步保存的简单封装。
|
||||
/// </summary>
|
||||
public Task WriteAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
Write();
|
||||
}, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从指定路径读取 JSON 并填充到当前实例(使用 PopulateObject,集合使用 Replace)。
|
||||
/// 如果需要返回一个全新的对象,请使用静态 LoadFromFile<T> 方法。
|
||||
/// </summary>
|
||||
/// <param name="path">包含文件名的完整路径</param>
|
||||
public virtual void Read(string path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
||||
{
|
||||
Write();
|
||||
return;
|
||||
}
|
||||
|
||||
var json = File.ReadAllText(path);
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ObjectCreationHandling = ObjectCreationHandling.Replace,
|
||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
||||
};
|
||||
JsonConvert.PopulateObject(json, this, settings);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从默认位置(Dir + FileName)读取。
|
||||
/// </summary>
|
||||
public virtual void Read()
|
||||
{
|
||||
var path = Path.Combine(Dir ?? string.Empty, FileName ?? string.Empty);
|
||||
Read(path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 静态:从指定文件反序列化为新对象(若需要完整新实例,请使用此方法)。
|
||||
/// </summary>
|
||||
public static T LoadFromFile<T>(string path) where T : class
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path) || !File.Exists(path))
|
||||
return null;
|
||||
var json = File.ReadAllText(path);
|
||||
return JsonConvert.DeserializeObject<T>(json);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 静态:将任意对象保存到指定文件(路径自动创建)。
|
||||
/// </summary>
|
||||
public static void SaveToFile<T>(T obj, string path)
|
||||
{
|
||||
if (obj == null) throw new ArgumentNullException(nameof(obj));
|
||||
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullException(nameof(path));
|
||||
|
||||
var dir = Path.GetDirectoryName(path);
|
||||
if (!string.IsNullOrWhiteSpace(dir) && !Directory.Exists(dir))
|
||||
Directory.CreateDirectory(dir);
|
||||
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
|
||||
};
|
||||
var json = JsonConvert.SerializeObject(obj, settings);
|
||||
File.WriteAllText(path, json);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MainShell.Filewritable
|
||||
{
|
||||
public static class Paths
|
||||
{
|
||||
public static string BasePath => AppDomain.CurrentDomain.BaseDirectory;
|
||||
|
||||
#region //算法标定文件路径
|
||||
public static string CalibPath => Path.Combine(BasePath, "CalibData");
|
||||
#endregion
|
||||
|
||||
#region//配方文件路径
|
||||
public static string RecipeBasePath => Path.Combine(BasePath, "Recipe");
|
||||
public static string CarrierRecipe => Path.Combine(RecipeBasePath, "Carrier");
|
||||
public static string SubstrateRecipe=> Path.Combine(RecipeBasePath, "Substrate");
|
||||
public static string WaferRecipe => Path.Combine(RecipeBasePath, "Wafer");
|
||||
public static string ProcessRecipe => Path.Combine(RecipeBasePath, "Process");
|
||||
#endregion
|
||||
|
||||
#region//模版路径
|
||||
/// <summary>
|
||||
/// 模版统一存放路径
|
||||
/// </summary>
|
||||
public static string TemplateBasePath => Path.Combine(BasePath, "VisionTemplate");
|
||||
|
||||
#region //原点标定模板路径
|
||||
public const string OriginCalibDefaultTemplatePath = "Template/Default";
|
||||
public const string OriginCalibGantryX1Y1TemplatePath = "Template/OriginCalib/GantryX1Y1";
|
||||
public const string OriginCalibGantryX2TemplatePath = "Template/OriginCalib/GantryX2";
|
||||
public const string OriginCalibStageY2TemplatePath = "Template/OriginCalib/StageY2";
|
||||
public const string OriginCalibWSX3TemplatePath = "Template/OriginCalib/WSX3";
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region //维护记录路径
|
||||
public const string MaintanceRecordDir = @"D:\RecordData\Maintance\";
|
||||
#endregion
|
||||
|
||||
#region //过程结果路径
|
||||
public static string ProcessResultDir => Path.Combine(BasePath, "ProcessResult");
|
||||
#endregion
|
||||
|
||||
#region //标定设置路径
|
||||
public static string CalibSettingPath => Path.Combine(BasePath, "Parameters");
|
||||
#endregion
|
||||
|
||||
public static Dictionary<string, string> WaferFileNames => new Dictionary<string, string>
|
||||
{
|
||||
{ "Row", Path.Combine(BasePath,"Path", "row.txt") },
|
||||
{ "Column", Path.Combine(BasePath,"Path", "Column.txt") },
|
||||
{ "Angle", Path.Combine(BasePath,"Path", "angle.txt") },
|
||||
{ "RowOverlap", Path.Combine(BasePath,"Path", "rowOverlap.txt") },
|
||||
{ "ColumnOverlap", Path.Combine(BasePath,"Path", "ColumnOverlap.txt") },
|
||||
{ "AngleOverlap", Path.Combine(BasePath,"Path", "angleOverlap.txt") }
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using MainShell.Filewritable;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MXJM.FileWritable
|
||||
{
|
||||
public class WaferMapFile : FileWriteBase
|
||||
{
|
||||
public WaferMapFile()
|
||||
{
|
||||
Description = "芯片定位识别点数据保存";
|
||||
}
|
||||
public override void Save()
|
||||
{
|
||||
var (row, col, angle, overlapRow, overlapCol, overlapAngle) = UserData as Tuple<double[], double[], double[], double[], double[], double[]>;
|
||||
if (row == null || col == null || angle == null || overlapRow == null || overlapCol == null || overlapAngle == null)
|
||||
{
|
||||
throw new InvalidDataException("UserData must be a Tuple of six double arrays.");
|
||||
}
|
||||
SaveList(Paths.WaferFileNames["Row"], row.ToList());
|
||||
SaveList(Paths.WaferFileNames["Column"], col.ToList());
|
||||
SaveList(Paths.WaferFileNames["Angle"], angle.ToList());
|
||||
SaveList(Paths.WaferFileNames["RowOverlap"], overlapRow.ToList());
|
||||
SaveList(Paths.WaferFileNames["ColumnOverlap"], overlapCol.ToList());
|
||||
SaveList(Paths.WaferFileNames["AngleOverlap"], overlapAngle.ToList());
|
||||
}
|
||||
void SaveList(string fileName, List<double> list)
|
||||
{
|
||||
string directory = Path.GetDirectoryName(fileName);
|
||||
if (!string.IsNullOrWhiteSpace(directory) && !Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
string content = list == null || list.Count == 0
|
||||
? string.Empty
|
||||
: string.Join(Environment.NewLine, list);
|
||||
using (StreamWriter sw = new StreamWriter(fileName, false, Encoding.UTF8))
|
||||
{
|
||||
sw.Write(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user