< Summary

Information
Class: Trailblazer.Pathing.NavigationFlowFieldOpenHeap
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Flow/NavigationFlowFieldOpenHeap.cs
Line coverage
100%
Covered lines: 59
Uncovered lines: 0
Coverable lines: 59
Total lines: 110
Line coverage: 100%
Branch coverage
100%
Covered branches: 20
Total branches: 20
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
TryPeek(...)100%22100%
Push(...)100%11100%
Pop()100%22100%
DecreaseKey(...)100%11100%
SortUp(...)100%44100%
SortDown(...)100%88100%
Compare(...)100%44100%
Swap(...)100%11100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Search/Flow/NavigationFlowFieldOpenHeap.cs

#LineLine coverage
 1//=======================================================================
 2// NavigationFlowFieldOpenHeap.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
 8namespace Trailblazer.Pathing;
 9
 10/// <summary>Orders flow nodes by exact integration cost and stable address.</summary>
 11internal struct NavigationFlowFieldOpenHeap
 12{
 13    private readonly NavigationFlowFieldWorkspace _workspace;
 14
 15    internal NavigationFlowFieldOpenHeap(NavigationFlowFieldWorkspace workspace) =>
 73616        _workspace = workspace;
 17
 18    internal bool TryPeek(out int slot)
 19    {
 462620        if (_workspace.HeapCount == 0)
 21        {
 37222            slot = -1;
 37223            return false;
 24        }
 425425        slot = _workspace.HeapSlots[0];
 425426        return true;
 27    }
 28
 29    internal void Push(int slot)
 30    {
 391431        int index = _workspace.HeapCount++;
 391432        _workspace.HeapSlots[index] = slot;
 391433        _workspace.GetRecord(slot).HeapIndex = index;
 391434        SortUp(index);
 391435    }
 36
 37    internal int Pop()
 38    {
 352839        int result = _workspace.HeapSlots[0];
 352840        _workspace.GetRecord(result).HeapIndex = -1;
 352841        int last = --_workspace.HeapCount;
 352842        if (last > 0)
 43        {
 6944            int moved = _workspace.HeapSlots[last];
 6945            _workspace.HeapSlots[0] = moved;
 6946            _workspace.GetRecord(moved).HeapIndex = 0;
 6947            SortDown(0);
 48        }
 352849        return result;
 50    }
 51
 52    internal void DecreaseKey(int slot) =>
 1053        SortUp(_workspace.GetRecord(slot).HeapIndex);
 54
 55    private void SortUp(int index)
 56    {
 394957        while (index > 0)
 58        {
 11959            int parent = (index - 1) / 2;
 11960            if (Compare(index, parent) >= 0)
 9461                return;
 2562            Swap(index, parent);
 2563            index = parent;
 64        }
 383065    }
 66
 67    private void SortDown(int index)
 68    {
 6669        while (true)
 70        {
 13571            int left = checked((index * 2) + 1);
 13572            if (left >= _workspace.HeapCount)
 4973                return;
 8674            int right = left + 1;
 8675            int best = right < _workspace.HeapCount && Compare(right, left) < 0
 8676                ? right
 8677                : left;
 8678            if (Compare(best, index) >= 0)
 2079                return;
 6680            Swap(index, best);
 6681            index = best;
 82        }
 83    }
 84
 85    private int Compare(int leftIndex, int rightIndex)
 86    {
 26487        ref NavigationFlowFieldSearchNode left = ref _workspace.GetRecord(
 26488            _workspace.HeapSlots[leftIndex]);
 26489        ref NavigationFlowFieldSearchNode right = ref _workspace.GetRecord(
 26490            _workspace.HeapSlots[rightIndex]);
 26491        int comparison = left.IntegrationCost.CompareTo(right.IntegrationCost);
 26492        if (comparison != 0)
 23793            return comparison;
 2794        comparison = left.Address.CompareTo(right.Address);
 2795        return comparison != 0
 2796            ? comparison
 2797            : _workspace.GetNode(_workspace.HeapSlots[leftIndex]).Medium.CompareTo(
 2798                _workspace.GetNode(_workspace.HeapSlots[rightIndex]).Medium);
 99    }
 100
 101    private void Swap(int left, int right)
 102    {
 91103        int leftSlot = _workspace.HeapSlots[left];
 91104        int rightSlot = _workspace.HeapSlots[right];
 91105        _workspace.HeapSlots[left] = rightSlot;
 91106        _workspace.HeapSlots[right] = leftSlot;
 91107        _workspace.GetRecord(rightSlot).HeapIndex = left;
 91108        _workspace.GetRecord(leftSlot).HeapIndex = right;
 91109    }
 110}