| | | 1 | | //======================================================================= |
| | | 2 | | // NavigationGuideLease.cs |
| | | 3 | | //======================================================================= |
| | | 4 | | // MIT License, Copyright (c) 2024-present David Oravsky (mrdav30) |
| | | 5 | | // See LICENSE file in the project root for full license information. |
| | | 6 | | //======================================================================= |
| | | 7 | | |
| | | 8 | | using System; |
| | | 9 | | using FixedMathSharp; |
| | | 10 | | |
| | | 11 | | namespace Trailblazer.Pathing; |
| | | 12 | | |
| | | 13 | | /// <summary>Owns one graph-backed A* payload reference and its guide-local step cursor.</summary> |
| | | 14 | | public readonly struct NavigationGuideLease : IDisposable |
| | | 15 | | { |
| | | 16 | | private readonly NavigationAStarGuideLease? _inner; |
| | | 17 | | private readonly long _generation; |
| | | 18 | | |
| | | 19 | | internal NavigationGuideLease(NavigationAStarGuideLease inner) |
| | | 20 | | { |
| | | 21 | | _inner = inner; |
| | | 22 | | _generation = inner.Generation; |
| | | 23 | | } |
| | | 24 | | |
| | | 25 | | /// <summary>Gets the lease's current dependency-validated status.</summary> |
| | | 26 | | public NavigationGuideStatus Status => NavigationGuideStatusMapper.ToPublic( |
| | | 27 | | _inner?.GetStatus(_generation) ?? NavigationAStarQueryStatus.Stale); |
| | | 28 | | |
| | | 29 | | /// <summary>Gets the zero-based guide-local step cursor.</summary> |
| | | 30 | | public int CurrentStepIndex => _inner?.GetCurrentWaypointOrdinal(_generation) ?? -1; |
| | | 31 | | |
| | | 32 | | /// <summary>Gets the immutable number of movement and action steps in the leased route.</summary> |
| | | 33 | | public int StepCount => _inner?.GetWaypointCount(_generation) ?? 0; |
| | | 34 | | |
| | | 35 | | /// <summary>Gets the immutable exact fixed-point cost of the complete route.</summary> |
| | | 36 | | public Fixed64 TotalCost => _inner?.GetTotalCost(_generation) ?? Fixed64.Zero; |
| | | 37 | | |
| | | 38 | | /// <summary>Gets the current dependency-validated movement or action step.</summary> |
| | | 39 | | public NavigationGuideStatus TryGetCurrentStep(out NavigationGuideStep step) |
| | | 40 | | { |
| | | 41 | | NavigationAStarGuideLease? inner = _inner; |
| | | 42 | | if (inner == null) |
| | | 43 | | { |
| | | 44 | | step = default; |
| | | 45 | | return NavigationGuideStatus.Stale; |
| | | 46 | | } |
| | | 47 | | |
| | | 48 | | return NavigationGuideStatusMapper.ToPublic( |
| | | 49 | | inner.TryGetCurrentStep( |
| | | 50 | | _generation, |
| | | 51 | | out step)); |
| | | 52 | | } |
| | | 53 | | |
| | | 54 | | /// <summary>Advances one ordinary movement step; a pending action cannot be crossed.</summary> |
| | | 55 | | public NavigationGuideStatus TryAdvanceStep() |
| | | 56 | | { |
| | | 57 | | return _inner == null |
| | | 58 | | ? NavigationGuideStatus.Stale |
| | | 59 | | : NavigationGuideStatusMapper.ToPublic( |
| | | 60 | | _inner.TryAdvanceWaypoint(_generation)); |
| | | 61 | | } |
| | | 62 | | |
| | | 63 | | /// <summary>Completes the exact current pending semantic action.</summary> |
| | | 64 | | public NavigationGuideStatus CompletePendingTransition( |
| | | 65 | | in NavigationTransitionInstruction instruction) => |
| | | 66 | | _inner == null |
| | | 67 | | ? NavigationGuideStatus.Stale |
| | | 68 | | : NavigationGuideStatusMapper.ToPublic( |
| | | 69 | | _inner.CompletePendingTransition(_generation, instruction)); |
| | | 70 | | |
| | | 71 | | /// <inheritdoc /> |
| | | 72 | | public void Dispose() => _inner?.Dispose(_generation); |
| | | 73 | | } |
| | | 74 | | |
| | | 75 | | internal static class NavigationGuideStatusMapper |
| | | 76 | | { |
| | 935 | 77 | | internal static NavigationGuideStatus ToPublic(NavigationAStarQueryStatus status) => status switch |
| | 935 | 78 | | { |
| | 864 | 79 | | NavigationAStarQueryStatus.Success => NavigationGuideStatus.Success, |
| | 1 | 80 | | NavigationAStarQueryStatus.Unsupported => NavigationGuideStatus.Unsupported, |
| | 2 | 81 | | NavigationAStarQueryStatus.NoMap => NavigationGuideStatus.NoMap, |
| | 2 | 82 | | NavigationAStarQueryStatus.InvalidProfile => NavigationGuideStatus.InvalidProfile, |
| | 2 | 83 | | NavigationAStarQueryStatus.InvalidStart => NavigationGuideStatus.InvalidStart, |
| | 4 | 84 | | NavigationAStarQueryStatus.InvalidEnd => NavigationGuideStatus.InvalidEnd, |
| | 13 | 85 | | NavigationAStarQueryStatus.NoPath => NavigationGuideStatus.NoPath, |
| | 4 | 86 | | NavigationAStarQueryStatus.BudgetExceeded => NavigationGuideStatus.BudgetExceeded, |
| | 2 | 87 | | NavigationAStarQueryStatus.CostOverflow => NavigationGuideStatus.CostOverflow, |
| | 8 | 88 | | NavigationAStarQueryStatus.CapacityExceeded => NavigationGuideStatus.CapacityExceeded, |
| | 30 | 89 | | NavigationAStarQueryStatus.Stale => NavigationGuideStatus.Stale, |
| | 3 | 90 | | _ => NavigationGuideStatus.Stale |
| | 935 | 91 | | }; |
| | | 92 | | |
| | 23 | 93 | | internal static NavigationGuideStatus ToPublic(NavigationFlowQueryStatus status) => status switch |
| | 23 | 94 | | { |
| | 1 | 95 | | NavigationFlowQueryStatus.Success => NavigationGuideStatus.Success, |
| | 1 | 96 | | NavigationFlowQueryStatus.Unsupported => NavigationGuideStatus.Unsupported, |
| | 2 | 97 | | NavigationFlowQueryStatus.NoMap => NavigationGuideStatus.NoMap, |
| | 1 | 98 | | NavigationFlowQueryStatus.InvalidProfile => NavigationGuideStatus.InvalidProfile, |
| | 2 | 99 | | NavigationFlowQueryStatus.InvalidStart => NavigationGuideStatus.InvalidStart, |
| | 4 | 100 | | NavigationFlowQueryStatus.InvalidEnd => NavigationGuideStatus.InvalidEnd, |
| | 3 | 101 | | NavigationFlowQueryStatus.NoPath => NavigationGuideStatus.NoPath, |
| | 2 | 102 | | NavigationFlowQueryStatus.BudgetExceeded => NavigationGuideStatus.BudgetExceeded, |
| | 2 | 103 | | NavigationFlowQueryStatus.CostOverflow => NavigationGuideStatus.CostOverflow, |
| | 2 | 104 | | NavigationFlowQueryStatus.CapacityExceeded => NavigationGuideStatus.CapacityExceeded, |
| | 2 | 105 | | NavigationFlowQueryStatus.Stale => NavigationGuideStatus.Stale, |
| | 1 | 106 | | _ => NavigationGuideStatus.Stale |
| | 23 | 107 | | }; |
| | | 108 | | |
| | | 109 | | internal static NavigationGuideStatus ToPublic(NavigationRayStatus status) |
| | | 110 | | { |
| | | 111 | | System.Diagnostics.Debug.Assert(status is |
| | | 112 | | NavigationRayStatus.Blocked or |
| | | 113 | | NavigationRayStatus.BudgetExceeded or |
| | | 114 | | NavigationRayStatus.CostOverflow or |
| | | 115 | | NavigationRayStatus.CapacityExceeded or |
| | | 116 | | NavigationRayStatus.Stale, |
| | | 117 | | "Ray recovery maps only terminal statuses not handled by its caller."); |
| | 19 | 118 | | return status switch |
| | 19 | 119 | | { |
| | 5 | 120 | | NavigationRayStatus.Blocked => NavigationGuideStatus.LocalRecoveryRequired, |
| | 9 | 121 | | NavigationRayStatus.BudgetExceeded => NavigationGuideStatus.BudgetExceeded, |
| | 1 | 122 | | NavigationRayStatus.CostOverflow => NavigationGuideStatus.CostOverflow, |
| | 2 | 123 | | NavigationRayStatus.CapacityExceeded => NavigationGuideStatus.CapacityExceeded, |
| | 2 | 124 | | _ => NavigationGuideStatus.Stale |
| | 19 | 125 | | }; |
| | | 126 | | } |
| | | 127 | | |
| | | 128 | | internal static NavigationFlowFieldStatus ToFlowField( |
| | | 129 | | NavigationTraversalEdgeAdvanceStatus status) |
| | | 130 | | { |
| | | 131 | | System.Diagnostics.Debug.Assert(status is |
| | | 132 | | NavigationTraversalEdgeAdvanceStatus.Complete or |
| | | 133 | | NavigationTraversalEdgeAdvanceStatus.BudgetExceeded or |
| | | 134 | | NavigationTraversalEdgeAdvanceStatus.CostOverflow or |
| | | 135 | | NavigationTraversalEdgeAdvanceStatus.CapacityExceeded or |
| | | 136 | | NavigationTraversalEdgeAdvanceStatus.Stale, |
| | | 137 | | "Flow traversal maps only terminal statuses not handled by its caller."); |
| | 9 | 138 | | return status switch |
| | 9 | 139 | | { |
| | 9 | 140 | | NavigationTraversalEdgeAdvanceStatus.BudgetExceeded => |
| | 4 | 141 | | NavigationFlowFieldStatus.BudgetExceeded, |
| | 9 | 142 | | NavigationTraversalEdgeAdvanceStatus.CostOverflow => |
| | 2 | 143 | | NavigationFlowFieldStatus.CostOverflow, |
| | 9 | 144 | | NavigationTraversalEdgeAdvanceStatus.CapacityExceeded => |
| | 1 | 145 | | NavigationFlowFieldStatus.CapacityExceeded, |
| | 2 | 146 | | _ => NavigationFlowFieldStatus.Stale |
| | 9 | 147 | | }; |
| | | 148 | | } |
| | | 149 | | } |