1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! `LoopSweep` — call-driven dispatch for [`LineKind::Loop`] groups.
//!
//! On a one-way closed loop, "dispatch" reduces to a label: the
//! `systems::dispatch` phase already kickstarts an `Idle` Loop car onto
//! its forward-next stop and excludes Loop cars from the Hungarian idle
//! pool, and the door FSM hands the car straight from `DoorClosing`
//! back to `MovingToStop(next)` without ever passing through
//! `Stopped`. The loading phase boards every eligible rider regardless
//! of the linear up/down lamps, so a Loop car serves every waiter at
//! every served stop on every lap.
//!
//! That continuous-patrol behaviour is the LoopSweep contract from
//! `docs/plans/loop-lines-v1.md`. This struct exists so that:
//!
//! - Loop groups have a typed default that round-trips through
//! snapshots and config files via [`BuiltinStrategy::LoopSweep`]
//! instead of silently inheriting [`BuiltinStrategy::Scan`] — which
//! would replay any restored sim with the wrong identity.
//! - The construction-time validation can name the only strategy a
//! Loop group is allowed to carry, rejecting Linear-only strategies
//! loud rather than silently misbehaving.
//!
//! All [`DispatchStrategy`] hooks fall back to defaults: Loop cars
//! never reach the Hungarian, so [`rank`](DispatchStrategy::rank) is
//! unreachable in practice, and there is no per-car or per-pass scratch
//! that needs to round-trip — the whole struct is unit-shaped.
//!
//! Future Loop-aware behaviour (skip-empty-stops, headway-driven hold
//! recovery) will land in successors (`LoopSchedule`).
//!
//! [`LineKind::Loop`]: crate::components::LineKind::Loop
use ;
/// Dispatch strategy for [`LineKind::Loop`] groups.
///
/// See the module-level documentation for the full contract. The struct
/// holds no per-pass state — Loop cars patrol forward on their own and
/// never enter the Hungarian assignment — so it is a unit struct. The
/// `Serialize`/`Deserialize` derives keep it round-trip-compatible with
/// the snapshot identity layer for symmetry with the other built-ins.
///
/// [`LineKind::Loop`]: crate::components::LineKind::Loop
;