[XP.Hardware.Detector] DetectorWorkMode 枚举扩展为 9 个预设模式;新增 DetectorPreset 模型类、PresetLoader(JSON 配置文件加载器)。
This commit is contained in:
@@ -89,13 +89,28 @@ namespace XP.Hardware.Detector.Config
|
||||
/// <summary>
|
||||
/// 获取指定工作模式的完整参数预设 | Get full parameter preset for the given work mode
|
||||
/// Custom 模式返回 null(由用户自由设定)| Returns null for Custom mode (user sets manually)
|
||||
/// 子类应重写以提供设备型号专属的参数组合 | Subclass should override for model-specific parameter combinations
|
||||
/// 优先从 JSON 配置文件加载,加载失败时回退到代码默认值
|
||||
/// Loads from JSON config file first, falls back to code defaults on failure
|
||||
/// </summary>
|
||||
/// <param name="mode">工作模式 | Work mode</param>
|
||||
/// <returns>参数预设,Custom 时返回 null | Parameter preset, null for Custom</returns>
|
||||
public virtual DetectorPreset GetPreset(DetectorWorkMode mode)
|
||||
{
|
||||
// 基类提供通用默认值(基于 1×1/2×2 两种 Binning) | Base class provides generic defaults
|
||||
if (mode == DetectorWorkMode.Custom) return null;
|
||||
|
||||
// 优先从 JSON 配置文件加载 | Try JSON config file first
|
||||
var fromJson = PresetLoader.TryLoadFromJson(Type, mode);
|
||||
if (fromJson != null) return fromJson;
|
||||
|
||||
// 回退到代码默认值 | Fallback to code defaults
|
||||
return GetDefaultPreset(mode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 代码内置的默认预设参数(JSON 加载失败时使用)| Built-in default preset parameters (used when JSON fails)
|
||||
/// </summary>
|
||||
protected virtual DetectorPreset GetDefaultPreset(DetectorWorkMode mode)
|
||||
{
|
||||
return mode switch
|
||||
{
|
||||
DetectorWorkMode.HighQuality => new DetectorPreset(mode, binningIndex: 0, frameRate: 1m, avgFrames: 8, pga: 4),
|
||||
@@ -106,7 +121,6 @@ namespace XP.Hardware.Detector.Config
|
||||
DetectorWorkMode.HighDynamicFullRes=> new DetectorPreset(mode, binningIndex: 0, frameRate: 3m, avgFrames: 4, pga: 6),
|
||||
DetectorWorkMode.HighDynamic => new DetectorPreset(mode, binningIndex: 1, frameRate: 15m, avgFrames: 2, pga: 6),
|
||||
DetectorWorkMode.LowDosage => new DetectorPreset(mode, binningIndex: 0, frameRate: 3m, avgFrames: 1, pga: 2),
|
||||
DetectorWorkMode.Custom => null,
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
@@ -121,9 +121,9 @@ namespace XP.Hardware.Detector.Config
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// iRay 工作模式参数预设 | iRay work mode parameter presets
|
||||
/// iRay 工作模式参数预设(代码默认值)| iRay work mode parameter presets (code defaults)
|
||||
/// </summary>
|
||||
public override DetectorPreset GetPreset(DetectorWorkMode mode)
|
||||
protected override DetectorPreset GetDefaultPreset(DetectorWorkMode mode)
|
||||
{
|
||||
return mode switch
|
||||
{
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.Json;
|
||||
using XP.Hardware.Detector.Abstractions.Enums;
|
||||
|
||||
namespace XP.Hardware.Detector.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// 预设加载器 | Preset loader
|
||||
/// 从 JSON 配置文件加载预设参数,覆盖代码默认值
|
||||
/// Loads preset parameters from JSON config file, overriding code defaults
|
||||
/// </summary>
|
||||
public static class PresetLoader
|
||||
{
|
||||
private static Dictionary<string, Dictionary<string, PresetJson>> _cache = new();
|
||||
private static readonly object _lock = new();
|
||||
|
||||
/// <summary>
|
||||
/// 尝试从 JSON 文件加载指定模式的预设 | Try to load preset for given mode from JSON file
|
||||
/// </summary>
|
||||
/// <param name="detectorType">探测器类型 | Detector type</param>
|
||||
/// <param name="mode">工作模式 | Work mode</param>
|
||||
/// <returns>预设参数,加载失败或无此模式时返回 null | Preset, or null if failed/not found</returns>
|
||||
public static DetectorPreset TryLoadFromJson(DetectorType detectorType, DetectorWorkMode mode)
|
||||
{
|
||||
if (mode == DetectorWorkMode.Custom) return null;
|
||||
|
||||
var modeName = mode.ToString();
|
||||
var presets = LoadPresetsFile(detectorType);
|
||||
if (presets == null || !presets.ContainsKey(modeName)) return null;
|
||||
|
||||
var json = presets[modeName];
|
||||
return new DetectorPreset(mode, json.BinningIndex, json.FrameRate, json.AvgFrames, json.Pga);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载探测器对应的预设文件(带缓存)| Load preset file for detector type (with cache)
|
||||
/// </summary>
|
||||
private static Dictionary<string, PresetJson> LoadPresetsFile(DetectorType detectorType)
|
||||
{
|
||||
var fileName = GetPresetFileName(detectorType);
|
||||
if (string.IsNullOrEmpty(fileName)) return null;
|
||||
|
||||
lock (_lock)
|
||||
{
|
||||
if (_cache.ContainsKey(fileName)) return _cache[fileName];
|
||||
|
||||
try
|
||||
{
|
||||
// 查找 JSON 文件路径:优先 exe 同级目录,其次 Config/Presets 子目录
|
||||
// Search path: prefer exe directory, then Config/Presets subdirectory
|
||||
var basePath = AppDomain.CurrentDomain.BaseDirectory;
|
||||
var filePath = Path.Combine(basePath, fileName);
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
filePath = Path.Combine(basePath, "Config", "Presets", fileName);
|
||||
}
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
_cache[fileName] = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
var jsonText = File.ReadAllText(filePath);
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNameCaseInsensitive = true,
|
||||
ReadCommentHandling = JsonCommentHandling.Skip
|
||||
};
|
||||
var dict = JsonSerializer.Deserialize<Dictionary<string, PresetJson>>(jsonText, options);
|
||||
_cache[fileName] = dict;
|
||||
return dict;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// JSON 解析失败时回退到代码默认值 | Fallback to code defaults on parse failure
|
||||
_cache[fileName] = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据探测器类型确定 JSON 文件名 | Determine JSON file name by detector type
|
||||
/// </summary>
|
||||
private static string GetPresetFileName(DetectorType detectorType)
|
||||
{
|
||||
return detectorType switch
|
||||
{
|
||||
DetectorType.Varex => "VarexPresets.json",
|
||||
DetectorType.IRay => "IRayPresets.json",
|
||||
_ => null
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清除缓存(测试用或配置文件更新后调用)| Clear cache (for testing or after config file update)
|
||||
/// </summary>
|
||||
public static void ClearCache()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
_cache.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// JSON 反序列化模型 | JSON deserialization model
|
||||
/// </summary>
|
||||
private class PresetJson
|
||||
{
|
||||
public int BinningIndex { get; set; }
|
||||
public decimal FrameRate { get; set; }
|
||||
public int AvgFrames { get; set; }
|
||||
public int Pga { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"HighQuality": { "BinningIndex": 0, "FrameRate": 1, "AvgFrames": 8, "Pga": 4 },
|
||||
"MediumQuality": { "BinningIndex": 0, "FrameRate": 10, "AvgFrames": 4, "Pga": 4 },
|
||||
"RealTime": { "BinningIndex": 1, "FrameRate": 30, "AvgFrames": 1, "Pga": 4 },
|
||||
"HighSpeed": { "BinningIndex": 2, "FrameRate": 45, "AvgFrames": 1, "Pga": 4 },
|
||||
"RealTimeFullRes": { "BinningIndex": 0, "FrameRate": 15, "AvgFrames": 1, "Pga": 4 },
|
||||
"HighDynamicFullRes": { "BinningIndex": 0, "FrameRate": 3, "AvgFrames": 4, "Pga": 7 },
|
||||
"HighDynamic": { "BinningIndex": 1, "FrameRate": 15, "AvgFrames": 2, "Pga": 7 },
|
||||
"LowDosage": { "BinningIndex": 0, "FrameRate": 3, "AvgFrames": 1, "Pga": 1 }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"HighQuality": { "BinningIndex": 0, "FrameRate": 1, "AvgFrames": 8, "Pga": 4 },
|
||||
"MediumQuality": { "BinningIndex": 0, "FrameRate": 10, "AvgFrames": 4, "Pga": 4 },
|
||||
"RealTime": { "BinningIndex": 1, "FrameRate": 30, "AvgFrames": 1, "Pga": 4 },
|
||||
"HighSpeed": { "BinningIndex": 2, "FrameRate": 60, "AvgFrames": 1, "Pga": 4 },
|
||||
"RealTimeFullRes": { "BinningIndex": 0, "FrameRate": 15, "AvgFrames": 1, "Pga": 4 },
|
||||
"HighDynamicFullRes": { "BinningIndex": 0, "FrameRate": 3, "AvgFrames": 4, "Pga": 6 },
|
||||
"HighDynamic": { "BinningIndex": 1, "FrameRate": 15, "AvgFrames": 2, "Pga": 6 },
|
||||
"LowDosage": { "BinningIndex": 0, "FrameRate": 3, "AvgFrames": 1, "Pga": 2 }
|
||||
}
|
||||
@@ -70,9 +70,9 @@ namespace XP.Hardware.Detector.Config
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Varex 4343N 工作模式参数预设 | Varex 4343N work mode parameter presets
|
||||
/// Varex 4343N 工作模式参数预设(代码默认值)| Varex 4343N work mode parameter presets (code defaults)
|
||||
/// </summary>
|
||||
public override DetectorPreset GetPreset(DetectorWorkMode mode)
|
||||
protected override DetectorPreset GetDefaultPreset(DetectorWorkMode mode)
|
||||
{
|
||||
return mode switch
|
||||
{
|
||||
|
||||
@@ -27,6 +27,15 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- 预设配置文件复制到输出目录(可选覆盖代码默认值)| Preset config files copied to output (optional override for code defaults) -->
|
||||
<Content Include="Config\Presets\VarexPresets.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="Config\Presets\IRayPresets.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Resources\Resources.Designer.cs">
|
||||
<DesignTime>True</DesignTime>
|
||||
|
||||
Reference in New Issue
Block a user