磁导航1.0内部交管和信号交互
This commit is contained in:
@@ -4,30 +4,24 @@ using StandardScene.Signal.Model;
|
||||
namespace StandardScene.Signal.Logic
|
||||
{
|
||||
/// <summary>
|
||||
/// 一条握手点配置的解析结果。参数格式与反编译 <c>SignalStop.SignalParams</c> 一致。
|
||||
/// 一条握手点配置的解析结果。新列(机构/工位/动作/附加参数)优先,旧 SignalParams 作回退。
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <see cref="SignalParams"/> 按分号切成 <see cref="Parts"/>,缺段时 <see cref="Part"/> 返回空串。
|
||||
/// 各类型约定:
|
||||
/// <list type="bullet">
|
||||
/// <item><c>JGControl</c>:机构名;RequestIn|Arrived;[区域-车组-限额-点列表]</item>
|
||||
/// <item><c>PointControl</c>:UP1|UP2|Down1|Down2;机构名</item>
|
||||
/// <item><c>TimedCharging</c>:最长秒数;上限电量;下限电量</item>
|
||||
/// <item><c>RateFlowControl</c>:区域;车组;限额;点1,点2</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
public sealed class SignalStopSpec
|
||||
{
|
||||
/// <summary>握手类型名,与 Handler 的 <see cref="Is"/> 比较时忽略大小写。</summary>
|
||||
public string SignalType { get; init; } = "";
|
||||
|
||||
/// <summary>原始参数串,限流独立类型会整段交给 <see cref="RateFlowHandler"/>。</summary>
|
||||
public string SignalParams { get; init; } = "";
|
||||
|
||||
/// <summary>按 ';' 切分,保留空段(与 Split None 一致,方便 Part(n) 按下标取)。</summary>
|
||||
public string[] Parts { get; init; } = Array.Empty<string>();
|
||||
|
||||
/// <summary>取第 <paramref name="index"/> 段;越界或 null 返回空串。</summary>
|
||||
public string JgName { get; init; } = "";
|
||||
|
||||
public string DockId { get; init; } = "";
|
||||
|
||||
public string Action { get; init; } = "";
|
||||
|
||||
public string ExtraParams { get; init; } = "";
|
||||
|
||||
public string Part(int index)
|
||||
{
|
||||
if (index < 0 || index >= Parts.Length)
|
||||
@@ -35,29 +29,102 @@ namespace StandardScene.Signal.Logic
|
||||
return Parts[index] ?? "";
|
||||
}
|
||||
|
||||
/// <summary>从类型名和参数串构造;类型会 Trim,参数保持原样以便日志对照现场 JSON。</summary>
|
||||
public static SignalStopSpec Parse(string signalType, string signalParams)
|
||||
{
|
||||
var type = (signalType ?? "").Trim();
|
||||
var raw = signalParams ?? "";
|
||||
return new SignalStopSpec
|
||||
var parsed = new SignalStopSpec
|
||||
{
|
||||
SignalType = type,
|
||||
SignalParams = raw,
|
||||
Parts = raw.Split(new[] { ';' }, StringSplitOptions.None)
|
||||
};
|
||||
return EnrichFromParts(parsed);
|
||||
}
|
||||
|
||||
/// <summary>从握手点 Model 构造;model 为 null 时返回 null。</summary>
|
||||
public static SignalStopSpec From(HandshakePointModel model)
|
||||
{
|
||||
if (model == null)
|
||||
return null;
|
||||
return Parse(model.SignalType, model.SignalParams);
|
||||
|
||||
var type = (model.SignalType ?? "").Trim();
|
||||
if (string.Equals(type, "TimedCharging", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(type, "RateFlowControl", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var raw = First(model.ExtraParams, model.SignalParams);
|
||||
return Parse(type, raw);
|
||||
}
|
||||
|
||||
var parsed = Parse(type, model.SignalParams ?? "");
|
||||
var jg = First(model.JgName, parsed.JgName);
|
||||
var action = First(model.Action, parsed.Action);
|
||||
var dock = First(model.DockId, parsed.DockId);
|
||||
var extra = First(model.ExtraParams, parsed.ExtraParams);
|
||||
return new SignalStopSpec
|
||||
{
|
||||
SignalType = parsed.SignalType,
|
||||
SignalParams = parsed.SignalParams,
|
||||
Parts = parsed.Parts,
|
||||
JgName = jg,
|
||||
DockId = dock,
|
||||
Action = action,
|
||||
ExtraParams = extra
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>类型名是否匹配(忽略大小写)。</summary>
|
||||
public bool Is(string type) =>
|
||||
string.Equals(SignalType, type, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private static SignalStopSpec EnrichFromParts(SignalStopSpec parsed)
|
||||
{
|
||||
var type = parsed.SignalType;
|
||||
if (string.Equals(type, "TimedCharging", StringComparison.OrdinalIgnoreCase) ||
|
||||
string.Equals(type, "RateFlowControl", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new SignalStopSpec
|
||||
{
|
||||
SignalType = parsed.SignalType,
|
||||
SignalParams = parsed.SignalParams,
|
||||
Parts = parsed.Parts,
|
||||
ExtraParams = parsed.SignalParams
|
||||
};
|
||||
}
|
||||
|
||||
var point = string.Equals(type, "PointControl", StringComparison.OrdinalIgnoreCase);
|
||||
var jg = point ? parsed.Part(1).Trim() : parsed.Part(0).Trim();
|
||||
var action = point ? parsed.Part(0).Trim() : parsed.Part(1).Trim();
|
||||
var dock = "";
|
||||
var extra = "";
|
||||
var p2 = parsed.Part(2).Trim();
|
||||
if (LooksLikeDock(p2))
|
||||
dock = p2;
|
||||
else if (LooksLikeRateFlow(p2))
|
||||
extra = p2;
|
||||
if (string.IsNullOrEmpty(extra))
|
||||
extra = parsed.Part(3).Trim();
|
||||
return new SignalStopSpec
|
||||
{
|
||||
SignalType = parsed.SignalType,
|
||||
SignalParams = parsed.SignalParams,
|
||||
Parts = parsed.Parts,
|
||||
JgName = jg,
|
||||
DockId = dock,
|
||||
Action = action,
|
||||
ExtraParams = extra
|
||||
};
|
||||
}
|
||||
|
||||
private static string First(string a, string b)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(a))
|
||||
return a.Trim();
|
||||
return (b ?? "").Trim();
|
||||
}
|
||||
|
||||
private static bool LooksLikeRateFlow(string s) =>
|
||||
!string.IsNullOrEmpty(s) && s.IndexOf('-') >= 0;
|
||||
|
||||
private static bool LooksLikeDock(string s) =>
|
||||
!string.IsNullOrEmpty(s) && s.IndexOf('-') < 0 && s.IndexOf(',') < 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user