新增信号交互进程插件
This commit is contained in:
@@ -9,17 +9,43 @@ using StandardScene.Signal.Plc;
|
||||
|
||||
namespace StandardScene.Signal.Logic
|
||||
{
|
||||
/// <summary>1s 扫全场车,对齐反编译 DefaultPlugin.ExcuteThreadMethod + StarSignManage。</summary>
|
||||
/// <summary>
|
||||
/// 1s 扫全场车,对齐反编译 <c>DefaultPlugin.ExcuteThreadMethod</c> + <c>StarSignManage</c>。
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 每辆车每拍只看当前站点:
|
||||
/// <list type="number">
|
||||
/// <item>停稳:先按握手点类型分发 Handler,再执行放行点(放行点不读 PLC,可能把还在等允许进入的车开走,站点不要两边都配)。</item>
|
||||
/// <item>行驶中:仅 JGControl + RequestIn 调用 <c>RequestInJudge</c>,PLC 未允许进入则停车。</item>
|
||||
/// </list>
|
||||
/// 握手点解析优先站点 fields(<see cref="SignalCarAdapter.TryReadSignalStop"/>),没有再查 JSON。
|
||||
/// </remarks>
|
||||
public sealed class CarScanWorker : IDisposable
|
||||
{
|
||||
/// <summary>取当前全部机构运行态;由 Mission 提供,内部会拷贝列表。</summary>
|
||||
private readonly Func<IReadOnlyList<PlcStationRuntime>> _runtimes;
|
||||
|
||||
/// <summary>扫车间隔,下限 100ms,默认跟进程 TickMs=1000。</summary>
|
||||
private readonly int _tickMs;
|
||||
|
||||
/// <summary>保护握手点 / 放行点字典,热替换配置时与扫车拍互斥。</summary>
|
||||
private readonly object _configLock = new object();
|
||||
|
||||
/// <summary>站点 → 握手点。同一站点多条配置只留第一条。</summary>
|
||||
private Dictionary<int, HandshakePointModel> _handshake = new Dictionary<int, HandshakePointModel>();
|
||||
|
||||
/// <summary>站点 → 放行点。同一站点多条配置只留第一条。</summary>
|
||||
private Dictionary<int, ReleasePointModel> _release = new Dictionary<int, ReleasePointModel>();
|
||||
|
||||
/// <summary>限流区域上次记日志的车号,避免同一区域每秒刷屏。</summary>
|
||||
private readonly Dictionary<string, int> _rateFlowLog = new Dictionary<string, int>();
|
||||
|
||||
/// <summary>车辆没有 GetChargeTime 时,用首次看到「充电中」的时刻估算秒数。</summary>
|
||||
private readonly Dictionary<int, DateTime> _chargeStarted = new Dictionary<int, DateTime>();
|
||||
|
||||
/// <summary>未知 SignalType 的日志节流(同站点 10s 一次)。</summary>
|
||||
private readonly Dictionary<int, DateTime> _unknownTypeLog = new Dictionary<int, DateTime>();
|
||||
|
||||
private CancellationTokenSource _cts;
|
||||
private Thread _thread;
|
||||
private int _tickCount;
|
||||
@@ -30,8 +56,13 @@ namespace StandardScene.Signal.Logic
|
||||
_tickMs = Math.Max(100, tickMs);
|
||||
}
|
||||
|
||||
/// <summary>已完成的扫车拍数,写入进程 status 供监视。</summary>
|
||||
public int TickCount => _tickCount;
|
||||
|
||||
/// <summary>
|
||||
/// 热替换握手点 / 放行点。过滤掉站点号无效或信号类型为空的握手点。
|
||||
/// 不中断线程,下一拍生效。
|
||||
/// </summary>
|
||||
public void ReplaceConfig(IEnumerable<HandshakePointModel> handshake, IEnumerable<ReleasePointModel> release)
|
||||
{
|
||||
lock (_configLock)
|
||||
@@ -47,6 +78,7 @@ namespace StandardScene.Signal.Logic
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>启动后台扫车线程。重复 Start 若线程仍活则忽略。</summary>
|
||||
public void Start()
|
||||
{
|
||||
if (_thread != null && _thread.IsAlive) return;
|
||||
@@ -60,6 +92,7 @@ namespace StandardScene.Signal.Logic
|
||||
Diagnosis.Log("扫车握手线程已启动", "Signal", true);
|
||||
}
|
||||
|
||||
/// <summary>取消令牌并最多等 2s 退出。不抛异常,供进程停止时调用。</summary>
|
||||
public void Stop()
|
||||
{
|
||||
try { _cts?.Cancel(); }
|
||||
@@ -92,6 +125,10 @@ namespace StandardScene.Signal.Logic
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 一拍:拷贝配置字典 → 按机构名查找闭包 → 遍历全部车。
|
||||
/// 查找机构时忽略大小写,与 JSON 里 JgName 对齐。
|
||||
/// </summary>
|
||||
internal void ScanOnce()
|
||||
{
|
||||
Dictionary<int, HandshakePointModel> handshake;
|
||||
@@ -130,6 +167,10 @@ namespace StandardScene.Signal.Logic
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 站点 fields 有 SignalType 则用地图点配置(老 SignalStop);
|
||||
/// 否则用 handshake-points.json。fields 存在但类型为空视为本站不握手。
|
||||
/// </summary>
|
||||
private SignalStopSpec ResolveSpec(int sit, IReadOnlyDictionary<int, HandshakePointModel> handshake)
|
||||
{
|
||||
if (sit <= 0) return null;
|
||||
@@ -147,6 +188,10 @@ namespace StandardScene.Signal.Logic
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 停稳分发。TimedCharging 优先:充电点不应再走机构逻辑。
|
||||
/// 未识别的 SignalType 按站点节流打日志,避免刷屏。
|
||||
/// </summary>
|
||||
private void DispatchStopped(Car car, SignalStopSpec spec, Func<string, PlcStationRuntime> find)
|
||||
{
|
||||
if (spec.Is("TimedCharging"))
|
||||
|
||||
Reference in New Issue
Block a user