< Summary

Information
Class: Trailblazer.Pathing.TraversalTransitionQuery
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Transition/Query/TraversalTransitionQuery.cs
Line coverage
100%
Covered lines: 196
Uncovered lines: 0
Coverable lines: 196
Total lines: 419
Line coverage: 100%
Branch coverage
100%
Covered branches: 60
Total branches: 60
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Cache()100%11100%
get__cacheLock()100%11100%
get__cachedRegistryVersion()100%11100%
set__cachedRegistryVersion(...)100%11100%
get__allDirectedTransitions()100%11100%
set__allDirectedTransitions(...)100%11100%
get__hasAllDirectedTransitions()100%11100%
set__hasAllDirectedTransitions(...)100%11100%
get__directedTransitionsByType()100%11100%
get__directedTransitionsByMediumPair()100%11100%
get__directedTransitionsFromSourceGrid()100%11100%
get__directedTransitionsFromSourceGridByType()100%11100%
get__directedTransitionsFromSourceGridByMediumPair()100%11100%
get__directedTransitionsToDestinationGrid()100%11100%
get__directedTransitionsToDestinationGridByMediumPair()100%11100%
get__sourceGridIndicesByType()100%11100%
GetDirectedTransitions()100%11100%
GetDirectedTransitions(...)100%22100%
GetDirectedTransitions(...)100%22100%
GetDirectedTransitionsFromSourceGrid(...)100%11100%
GetDirectedTransitionsFromSourceGrid(...)100%22100%
GetDirectedTransitionsFromSourceGrid(...)100%22100%
GetDirectedTransitionsToDestinationGrid(...)100%11100%
GetDirectedTransitionsToDestinationGrid(...)100%22100%
GetSourceGridIndices(...)100%22100%
EnsureCacheVersion()100%22100%
FilterDirectedTransitionsByType(...)100%88100%
FilterDirectedTransitionsByMediumPair(...)100%1010100%
GetOrBuildAllDirectedTransitions_NoLock()100%22100%
GetOrBuildDirectedTransitionsFromSourceGrid_NoLock(...)100%22100%
GetOrBuildDirectedTransitionsToDestinationGrid_NoLock(...)100%22100%
BuildAllDirectedTransitions(...)100%22100%
BuildDirectedTransitionsForGrid(...)100%88100%
BuildSourceGridIndices(...)100%66100%
MatchesGrid(...)100%22100%
AddAllDirectedTransitions(...)100%22100%
GetOppositeAxis(...)100%22100%
CreateReversedTransition(...)100%11100%
SortTransitions(...)100%11100%
MakeMediumPairKey(...)100%11100%
MakeGridTypeKey(...)100%11100%
MakeGridMediumPairKey(...)100%11100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Transition/Query/TraversalTransitionQuery.cs

#LineLine coverage
 1using SwiftCollections;
 2using System;
 3
 4namespace Trailblazer.Pathing;
 5
 6/// <summary>
 7/// Provides deterministic directed transition snapshots for planners.
 8/// </summary>
 9/// <remarks>
 10/// The query layer favors grid-scoped snapshots first, while still allowing callers to fall back
 11/// to a full directed snapshot when they intentionally need world-wide transition discovery.
 12/// </remarks>
 13internal static class TraversalTransitionQuery
 14{
 15    private enum GridMatchAxis
 16    {
 17        Source,
 18        Destination
 19    }
 20
 383921    private static TraversalTransitionQueryCache Cache => PathManager.ActiveState.TransitionQueryCache;
 22
 55623    private static object _cacheLock => Cache.CacheLock;
 24
 25    private static int _cachedRegistryVersion
 26    {
 55627        get => Cache.CachedRegistryVersion;
 9028        set => Cache.CachedRegistryVersion = value;
 29    }
 30
 31    private static TraversalTransition[] _allDirectedTransitions
 32    {
 17333        get => Cache.AllDirectedTransitions;
 15634        set => Cache.AllDirectedTransitions = value;
 35    }
 36
 37    private static bool _hasAllDirectedTransitions
 38    {
 17339        get => Cache.HasAllDirectedTransitions;
 15640        set => Cache.HasAllDirectedTransitions = value;
 41    }
 42
 43    private static SwiftDictionary<TraversalTransitionType, TraversalTransition[]> _directedTransitionsByType =>
 12644        Cache.DirectedTransitionsByType;
 45
 46    private static SwiftDictionary<int, TraversalTransition[]> _directedTransitionsByMediumPair =>
 47447        Cache.DirectedTransitionsByMediumPair;
 48
 49    private static SwiftDictionary<int, TraversalTransition[]> _directedTransitionsFromSourceGrid =>
 28850        Cache.DirectedTransitionsFromSourceGrid;
 51
 52    private static SwiftDictionary<long, TraversalTransition[]> _directedTransitionsFromSourceGridByType =>
 13053        Cache.DirectedTransitionsFromSourceGridByType;
 54
 55    private static SwiftDictionary<long, TraversalTransition[]> _directedTransitionsFromSourceGridByMediumPair =>
 33856        Cache.DirectedTransitionsFromSourceGridByMediumPair;
 57
 58    private static SwiftDictionary<int, TraversalTransition[]> _directedTransitionsToDestinationGrid =>
 23859        Cache.DirectedTransitionsToDestinationGrid;
 60
 61    private static SwiftDictionary<long, TraversalTransition[]> _directedTransitionsToDestinationGridByMediumPair =>
 27662        Cache.DirectedTransitionsToDestinationGridByMediumPair;
 63
 64    private static SwiftDictionary<TraversalTransitionType, int[]> _sourceGridIndicesByType =>
 10965        Cache.SourceGridIndicesByType;
 66
 67    public static TraversalTransition[] GetDirectedTransitions()
 68    {
 269        lock (_cacheLock)
 70        {
 271            EnsureCacheVersion();
 272            return GetOrBuildAllDirectedTransitions_NoLock();
 73        }
 274    }
 75
 76    public static TraversalTransition[] GetDirectedTransitions(TraversalTransitionType type)
 77    {
 1978        lock (_cacheLock)
 79        {
 1980            EnsureCacheVersion();
 1981            if (_directedTransitionsByType.TryGetValue(type, out TraversalTransition[] cached))
 282                return cached;
 83
 1784            TraversalTransition[] filtered = FilterDirectedTransitionsByType(
 1785                GetOrBuildAllDirectedTransitions_NoLock(),
 1786                type);
 1787            _directedTransitionsByType[type] = filtered;
 1788            return filtered;
 89        }
 1990    }
 91
 92    public static TraversalTransition[] GetDirectedTransitions(
 93        TraversalMedium sourceMedium,
 94        TraversalMedium destinationMedium)
 95    {
 23096        lock (_cacheLock)
 97        {
 23098            EnsureCacheVersion();
 23099            int key = MakeMediumPairKey(sourceMedium, destinationMedium);
 230100            if (_directedTransitionsByMediumPair.TryGetValue(key, out TraversalTransition[] cached))
 76101                return cached;
 102
 154103            TraversalTransition[] filtered = FilterDirectedTransitionsByMediumPair(
 154104                GetOrBuildAllDirectedTransitions_NoLock(),
 154105                sourceMedium,
 154106                destinationMedium);
 154107            _directedTransitionsByMediumPair[key] = filtered;
 154108            return filtered;
 109        }
 230110    }
 111
 112    public static TraversalTransition[] GetDirectedTransitionsFromSourceGrid(int sourceGridIndex)
 113    {
 9114        lock (_cacheLock)
 115        {
 9116            EnsureCacheVersion();
 9117            return GetOrBuildDirectedTransitionsFromSourceGrid_NoLock(sourceGridIndex);
 118        }
 9119    }
 120
 121    public static TraversalTransition[] GetDirectedTransitionsFromSourceGrid(
 122        int sourceGridIndex,
 123        TraversalTransitionType type)
 124    {
 21125        lock (_cacheLock)
 126        {
 21127            EnsureCacheVersion();
 21128            long key = MakeGridTypeKey(sourceGridIndex, type);
 21129            if (_directedTransitionsFromSourceGridByType.TryGetValue(key, out TraversalTransition[] cached))
 2130                return cached;
 131
 19132            TraversalTransition[] filtered = FilterDirectedTransitionsByType(
 19133                GetOrBuildDirectedTransitionsFromSourceGrid_NoLock(sourceGridIndex),
 19134                type);
 19135            _directedTransitionsFromSourceGridByType[key] = filtered;
 19136            return filtered;
 137        }
 21138    }
 139
 140    public static TraversalTransition[] GetDirectedTransitionsFromSourceGrid(
 141        int sourceGridIndex,
 142        TraversalMedium sourceMedium,
 143        TraversalMedium destinationMedium)
 144    {
 149145        lock (_cacheLock)
 146        {
 149147            EnsureCacheVersion();
 149148            long key = MakeGridMediumPairKey(sourceGridIndex, sourceMedium, destinationMedium);
 149149            if (_directedTransitionsFromSourceGridByMediumPair.TryGetValue(key, out TraversalTransition[] cached))
 50150                return cached;
 151
 99152            TraversalTransition[] filtered = FilterDirectedTransitionsByMediumPair(
 99153                GetOrBuildDirectedTransitionsFromSourceGrid_NoLock(sourceGridIndex),
 99154                sourceMedium,
 99155                destinationMedium);
 99156            _directedTransitionsFromSourceGridByMediumPair[key] = filtered;
 99157            return filtered;
 158        }
 149159    }
 160
 161    public static TraversalTransition[] GetDirectedTransitionsToDestinationGrid(int destinationGridIndex)
 162    {
 10163        lock (_cacheLock)
 164        {
 10165            EnsureCacheVersion();
 10166            return GetOrBuildDirectedTransitionsToDestinationGrid_NoLock(destinationGridIndex);
 167        }
 10168    }
 169
 170    public static TraversalTransition[] GetDirectedTransitionsToDestinationGrid(
 171        int destinationGridIndex,
 172        TraversalMedium sourceMedium,
 173        TraversalMedium destinationMedium)
 174    {
 106175        lock (_cacheLock)
 176        {
 106177            EnsureCacheVersion();
 106178            long key = MakeGridMediumPairKey(destinationGridIndex, sourceMedium, destinationMedium);
 106179            if (_directedTransitionsToDestinationGridByMediumPair.TryGetValue(key, out TraversalTransition[] cached))
 26180                return cached;
 181
 80182            TraversalTransition[] filtered = FilterDirectedTransitionsByMediumPair(
 80183                GetOrBuildDirectedTransitionsToDestinationGrid_NoLock(destinationGridIndex),
 80184                sourceMedium,
 80185                destinationMedium);
 80186            _directedTransitionsToDestinationGridByMediumPair[key] = filtered;
 80187            return filtered;
 188        }
 106189    }
 190
 191    internal static int[] GetSourceGridIndices(TraversalTransitionType type)
 192    {
 10193        lock (_cacheLock)
 194        {
 10195            EnsureCacheVersion();
 10196            if (_sourceGridIndicesByType.TryGetValue(type, out int[] cached))
 1197                return cached;
 198
 9199            int[] sourceGridIndices = BuildSourceGridIndices(GetDirectedTransitions(type));
 9200            _sourceGridIndicesByType[type] = sourceGridIndices;
 9201            return sourceGridIndices;
 202        }
 10203    }
 204
 205    private static void EnsureCacheVersion()
 206    {
 556207        int registryVersion = TraversalTransitionRegistry.RegistryVersion;
 556208        if (_cachedRegistryVersion == registryVersion)
 466209            return;
 210
 90211        _allDirectedTransitions = Array.Empty<TraversalTransition>();
 90212        _hasAllDirectedTransitions = false;
 90213        _directedTransitionsByType.Clear();
 90214        _directedTransitionsByMediumPair.Clear();
 90215        _directedTransitionsFromSourceGrid.Clear();
 90216        _directedTransitionsFromSourceGridByType.Clear();
 90217        _directedTransitionsFromSourceGridByMediumPair.Clear();
 90218        _directedTransitionsToDestinationGrid.Clear();
 90219        _directedTransitionsToDestinationGridByMediumPair.Clear();
 90220        _sourceGridIndicesByType.Clear();
 90221        _cachedRegistryVersion = registryVersion;
 90222    }
 223
 224    private static TraversalTransition[] FilterDirectedTransitionsByType(
 225        TraversalTransition[] transitions,
 226        TraversalTransitionType type)
 227    {
 36228        if (transitions.Length == 0)
 9229            return Array.Empty<TraversalTransition>();
 230
 27231        SwiftList<TraversalTransition> filtered = new();
 264232        for (int i = 0; i < transitions.Length; i++)
 233        {
 105234            if (transitions[i].Type == type)
 94235                filtered.Add(transitions[i]);
 236        }
 237
 27238        return filtered.Count == 0
 27239            ? Array.Empty<TraversalTransition>()
 27240            : filtered.ToArray();
 241    }
 242
 243    private static TraversalTransition[] FilterDirectedTransitionsByMediumPair(
 244        TraversalTransition[] transitions,
 245        TraversalMedium sourceMedium,
 246        TraversalMedium destinationMedium)
 247    {
 333248        if (transitions.Length == 0)
 44249            return Array.Empty<TraversalTransition>();
 250
 289251        SwiftList<TraversalTransition> filtered = new();
 2204252        for (int i = 0; i < transitions.Length; i++)
 253        {
 813254            TraversalTransition transition = transitions[i];
 813255            if (transition.Source.Medium == sourceMedium
 813256                && transition.Destination.Medium == destinationMedium)
 257            {
 221258                filtered.Add(transition);
 259            }
 260        }
 261
 289262        return filtered.Count == 0
 289263            ? Array.Empty<TraversalTransition>()
 289264            : filtered.ToArray();
 265    }
 266
 267    private static TraversalTransition[] GetOrBuildAllDirectedTransitions_NoLock()
 268    {
 173269        if (_hasAllDirectedTransitions)
 107270            return _allDirectedTransitions;
 271
 66272        _allDirectedTransitions = BuildAllDirectedTransitions(TraversalTransitionRegistry.GetActiveTransitions());
 66273        _hasAllDirectedTransitions = true;
 66274        return _allDirectedTransitions;
 275    }
 276
 277    private static TraversalTransition[] GetOrBuildDirectedTransitionsFromSourceGrid_NoLock(int sourceGridIndex)
 278    {
 127279        if (_directedTransitionsFromSourceGrid.TryGetValue(sourceGridIndex, out TraversalTransition[] cached))
 56280            return cached;
 281
 71282        TraversalTransition[] directed = BuildDirectedTransitionsForGrid(
 71283            TraversalTransitionRegistry.GetActiveTransitionsTouchingGrid(sourceGridIndex),
 71284            sourceGridIndex,
 71285            GridMatchAxis.Source);
 71286        _directedTransitionsFromSourceGrid[sourceGridIndex] = directed;
 71287        return directed;
 288    }
 289
 290    private static TraversalTransition[] GetOrBuildDirectedTransitionsToDestinationGrid_NoLock(int destinationGridIndex)
 291    {
 90292        if (_directedTransitionsToDestinationGrid.TryGetValue(destinationGridIndex, out TraversalTransition[] cached))
 32293            return cached;
 294
 58295        TraversalTransition[] directed = BuildDirectedTransitionsForGrid(
 58296            TraversalTransitionRegistry.GetActiveTransitionsTouchingGrid(destinationGridIndex),
 58297            destinationGridIndex,
 58298            GridMatchAxis.Destination);
 58299        _directedTransitionsToDestinationGrid[destinationGridIndex] = directed;
 58300        return directed;
 301    }
 302
 303    private static TraversalTransition[] BuildAllDirectedTransitions(
 304        TraversalTransition[] transitions)
 305    {
 66306        SwiftList<TraversalTransition> directed = new(transitions.Length * 2);
 398307        for (int i = 0; i < transitions.Length; i++)
 133308            AddAllDirectedTransitions(directed, transitions[i]);
 309
 66310        return SortTransitions(directed);
 311    }
 312
 313    private static TraversalTransition[] BuildDirectedTransitionsForGrid(
 314        TraversalTransition[] transitions,
 315        int gridIndex,
 316        GridMatchAxis axis)
 317    {
 129318        SwiftList<TraversalTransition> directed = new(transitions.Length * 2);
 319
 770320        for (int i = 0; i < transitions.Length; i++)
 321        {
 256322            TraversalTransition transition = transitions[i];
 256323            if (MatchesGrid(transition, gridIndex, axis))
 254324                directed.Add(transition);
 325
 256326            if (transition.IsBidirectional
 256327                && MatchesGrid(transition, gridIndex, GetOppositeAxis(axis)))
 328            {
 5329                directed.Add(CreateReversedTransition(transition));
 330            }
 331        }
 332
 129333        return SortTransitions(directed);
 334    }
 335
 336    private static int[] BuildSourceGridIndices(TraversalTransition[] transitions)
 337    {
 9338        if (transitions.Length == 0)
 1339            return Array.Empty<int>();
 340
 8341        SwiftHashSet<int> uniqueGridIndices = new();
 8342        SwiftList<int> orderedGridIndices = new();
 46343        for (int i = 0; i < transitions.Length; i++)
 344        {
 15345            int gridIndex = transitions[i].Source.VoxelIndex.GridIndex;
 15346            if (uniqueGridIndices.Add(gridIndex))
 9347                orderedGridIndices.Add(gridIndex);
 348        }
 349
 8350        int[] result = orderedGridIndices.ToArray();
 8351        Array.Sort(result);
 8352        return result;
 353    }
 354
 355    private static bool MatchesGrid(
 356        TraversalTransition transition,
 357        int gridIndex,
 358        GridMatchAxis axis)
 359    {
 263360        return axis == GridMatchAxis.Source
 263361            ? transition.Source.VoxelIndex.GridIndex == gridIndex
 263362            : transition.Destination.VoxelIndex.GridIndex == gridIndex;
 363    }
 364
 365    private static void AddAllDirectedTransitions(
 366        SwiftList<TraversalTransition> directed,
 367        TraversalTransition transition)
 368    {
 133369        directed.Add(transition);
 370
 133371        if (transition.IsBidirectional)
 3372            directed.Add(CreateReversedTransition(transition));
 133373    }
 374
 375    private static GridMatchAxis GetOppositeAxis(GridMatchAxis axis)
 376    {
 7377        return axis == GridMatchAxis.Source
 7378            ? GridMatchAxis.Destination
 7379            : GridMatchAxis.Source;
 380    }
 381
 382    private static TraversalTransition CreateReversedTransition(TraversalTransition transition)
 383    {
 8384        return new TraversalTransition(
 8385            transition.Id,
 8386            transition.Type,
 8387            transition.Destination,
 8388            transition.Source,
 8389            transition.PathCostModifier,
 8390            transition.IsBidirectional);
 391    }
 392
 393    private static TraversalTransition[] SortTransitions(SwiftList<TraversalTransition> directed)
 394    {
 195395        TraversalTransition[] ordered = directed.ToArray();
 195396        TraversalTransitionOrdering.Sort(ordered);
 195397        return ordered;
 398    }
 399
 400    private static int MakeMediumPairKey(
 401        TraversalMedium sourceMedium,
 402        TraversalMedium destinationMedium)
 403    {
 485404        return ((int)sourceMedium << 16) | (int)destinationMedium;
 405    }
 406
 407    private static long MakeGridTypeKey(int gridIndex, TraversalTransitionType type)
 408    {
 21409        return ((long)(uint)gridIndex << 32) | (uint)type;
 410    }
 411
 412    private static long MakeGridMediumPairKey(
 413        int gridIndex,
 414        TraversalMedium sourceMedium,
 415        TraversalMedium destinationMedium)
 416    {
 255417        return ((long)(uint)gridIndex << 32) | (uint)MakeMediumPairKey(sourceMedium, destinationMedium);
 418    }
 419}

Methods/Properties

get_Cache()
get__cacheLock()
get__cachedRegistryVersion()
set__cachedRegistryVersion(System.Int32)
get__allDirectedTransitions()
set__allDirectedTransitions(Trailblazer.Pathing.TraversalTransition[])
get__hasAllDirectedTransitions()
set__hasAllDirectedTransitions(System.Boolean)
get__directedTransitionsByType()
get__directedTransitionsByMediumPair()
get__directedTransitionsFromSourceGrid()
get__directedTransitionsFromSourceGridByType()
get__directedTransitionsFromSourceGridByMediumPair()
get__directedTransitionsToDestinationGrid()
get__directedTransitionsToDestinationGridByMediumPair()
get__sourceGridIndicesByType()
GetDirectedTransitions()
GetDirectedTransitions(Trailblazer.Pathing.TraversalTransitionType)
GetDirectedTransitions(Trailblazer.TraversalMedium,Trailblazer.TraversalMedium)
GetDirectedTransitionsFromSourceGrid(System.Int32)
GetDirectedTransitionsFromSourceGrid(System.Int32,Trailblazer.Pathing.TraversalTransitionType)
GetDirectedTransitionsFromSourceGrid(System.Int32,Trailblazer.TraversalMedium,Trailblazer.TraversalMedium)
GetDirectedTransitionsToDestinationGrid(System.Int32)
GetDirectedTransitionsToDestinationGrid(System.Int32,Trailblazer.TraversalMedium,Trailblazer.TraversalMedium)
GetSourceGridIndices(Trailblazer.Pathing.TraversalTransitionType)
EnsureCacheVersion()
FilterDirectedTransitionsByType(Trailblazer.Pathing.TraversalTransition[],Trailblazer.Pathing.TraversalTransitionType)
FilterDirectedTransitionsByMediumPair(Trailblazer.Pathing.TraversalTransition[],Trailblazer.TraversalMedium,Trailblazer.TraversalMedium)
GetOrBuildAllDirectedTransitions_NoLock()
GetOrBuildDirectedTransitionsFromSourceGrid_NoLock(System.Int32)
GetOrBuildDirectedTransitionsToDestinationGrid_NoLock(System.Int32)
BuildAllDirectedTransitions(Trailblazer.Pathing.TraversalTransition[])
BuildDirectedTransitionsForGrid(Trailblazer.Pathing.TraversalTransition[],System.Int32,Trailblazer.Pathing.TraversalTransitionQuery/GridMatchAxis)
BuildSourceGridIndices(Trailblazer.Pathing.TraversalTransition[])
MatchesGrid(Trailblazer.Pathing.TraversalTransition,System.Int32,Trailblazer.Pathing.TraversalTransitionQuery/GridMatchAxis)
AddAllDirectedTransitions(SwiftCollections.SwiftList`1<Trailblazer.Pathing.TraversalTransition>,Trailblazer.Pathing.TraversalTransition)
GetOppositeAxis(Trailblazer.Pathing.TraversalTransitionQuery/GridMatchAxis)
CreateReversedTransition(Trailblazer.Pathing.TraversalTransition)
SortTransitions(SwiftCollections.SwiftList`1<Trailblazer.Pathing.TraversalTransition>)
MakeMediumPairKey(Trailblazer.TraversalMedium,Trailblazer.TraversalMedium)
MakeGridTypeKey(System.Int32,Trailblazer.Pathing.TraversalTransitionType)
MakeGridMediumPairKey(System.Int32,Trailblazer.TraversalMedium,Trailblazer.TraversalMedium)