Files
StandardSence/StandardScene.Core/InterLock/MagControlReleaseHook.cs
T

76 lines
2.7 KiB
C#

using System;
namespace StandardScene
{
/// <summary>
/// 磁条管控区放行判定结果。由信号插件「磁条交管进程」填写,Mag2Car 在 StartStop=12 停稳后消费。
/// </summary>
public sealed class MagControlReleaseDecision
{
/// <summary>当前触发点在交管表里有启用规则。false 时 Mag2Car 回退地图 <c>Fass2_ControlArea</c> 字段。</summary>
public bool RuleFound { get; set; }
public bool CanRelease { get; set; }
public string AreaId { get; set; } = string.Empty;
public int Capacity { get; set; } = 1;
public int OthersInArea { get; set; }
/// <summary>放行后写入本车报文的 StartStop,通常 11(管控启动)或 1(过站)。</summary>
public byte ReleaseStartStop { get; set; } = 11;
public string Reason { get; set; } = string.Empty;
}
/// <summary>
/// Mag2Car 与信号插件之间的管控放行钩子。不让 Magnetic / Signal 互相引用。
/// </summary>
/// <remarks>
/// 磁条交管进程启动时 <see cref="Register"/>,停止时 <see cref="Unregister"/>。
/// Mag2Car 在管控停止点调用 <see cref="TryCheck"/>:有规则用表判定,没有则用地图字段。
/// </remarks>
public static class MagControlReleaseHook
{
private static readonly object Sync = new object();
private static object _owner;
private static Func<int, int, MagControlReleaseDecision> _check;
/// <summary>注册判定函数。<paramref name="owner"/> 用于停止时只清自己的注册。</summary>
public static void Register(object owner, Func<int, int, MagControlReleaseDecision> check)
{
if (owner == null) throw new ArgumentNullException(nameof(owner));
lock (Sync)
{
_owner = owner;
_check = check;
}
}
public static void Unregister(object owner)
{
if (owner == null) return;
lock (Sync)
{
if (!ReferenceEquals(_owner, owner))
return;
_owner = null;
_check = null;
}
}
/// <summary>
/// 询问当前注册的交管进程。未注册返回 null;已注册但该触发点无规则时
/// 返回 <see cref="MagControlReleaseDecision.RuleFound"/> = false。
/// </summary>
public static MagControlReleaseDecision TryCheck(int carId, int triggerSiteId)
{
Func<int, int, MagControlReleaseDecision> check;
lock (Sync)
check = _check;
return check?.Invoke(carId, triggerSiteId);
}
}
}