< Summary

Information
Class: Trailblazer.Pathing.NavigationAutomaticSeamLifecycleWork
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Graph/NavigationAutomaticSeamLifecycleWork.cs
Line coverage
100%
Covered lines: 99
Uncovered lines: 0
Coverable lines: 99
Total lines: 168
Line coverage: 100%
Branch coverage
100%
Covered branches: 48
Total branches: 48
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%
get_RetainedBytes()100%66100%
get_PersistentPageCount()100%66100%
get_Result()100%11100%
RevalidateForPublication()100%11100%
AdvanceOne(...)100%3434100%
ExceedsCapacity(...)100%22100%

File(s)

/home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Graph/NavigationAutomaticSeamLifecycleWork.cs

#LineLine coverage
 1//=======================================================================
 2// NavigationAutomaticSeamLifecycleWork.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
 8using GridForge.Grids;
 9
 10namespace Trailblazer.Pathing;
 11
 12/// <summary>Retains one fail-closed GridForge lifecycle prefix until seam state is atomic.</summary>
 13internal sealed class NavigationAutomaticSeamLifecycleWork
 14{
 15    internal const long BaseRetainedBytes = 80L;
 16
 17    private readonly NavigationWorldGraph _source;
 18    private readonly NavigationAutomaticSeamRefreshWork _refresh;
 106419    private NavigationSurfaceComponentKeySet _affectedComponents =
 106420        NavigationSurfaceComponentKeySet.Empty;
 106421    private NavigationCellAddressSet _affectedAddresses = NavigationCellAddressSet.Empty;
 22    private NavigationWorldGraph? _structuralGraph;
 23    private NavigationSurfaceComponentBuildWork? _componentUpdate;
 24    private int _affectedMemberCount;
 25    private int _endpointOrdinal;
 106426    private TraversalMedium _endpointMedium = TraversalMedium.Solid;
 27    private bool _affectedCaptureComplete;
 28
 106429    internal NavigationAutomaticSeamLifecycleWork(
 106430        GridWorld world,
 106431        NavigationWorldGraph source,
 106432        GridEventInfo[] events,
 106433        int eventCount,
 106434        bool fullRebuild = false)
 35    {
 106436        _source = source;
 106437        _refresh = new NavigationAutomaticSeamRefreshWork(
 106438            world,
 106439            source,
 106440            source,
 106441            events,
 106442            eventCount,
 106443            fullRebuild);
 106444    }
 45
 153946    internal long RetainedBytes => checked(
 153947        BaseRetainedBytes
 153948        + _refresh.RetainedBytes
 153949        + (ReferenceEquals(_affectedComponents, NavigationSurfaceComponentKeySet.Empty)
 153950            ? 0L
 153951            : _affectedComponents.RetainedBytes)
 153952        + (ReferenceEquals(_affectedAddresses, NavigationCellAddressSet.Empty)
 153953            ? 0L
 153954            : _affectedAddresses.RetainedBytes)
 153955        + (_componentUpdate?.RetainedBytes ?? 0L));
 56
 153657    internal int PersistentPageCount => checked(
 153658        1
 153659        + _refresh.PersistentPageCount
 153660        + (ReferenceEquals(_affectedComponents, NavigationSurfaceComponentKeySet.Empty)
 153661            ? 0
 153662            : _affectedComponents.PersistentPageCount)
 153663        + (ReferenceEquals(_affectedAddresses, NavigationCellAddressSet.Empty)
 153664            ? 0
 153665            : _affectedAddresses.PersistentPageCount)
 153666        + (_componentUpdate?.PersistentPageCount ?? 0));
 67
 68    internal NavigationWorldGraph Result
 69    {
 70        get
 71        {
 6672            return _structuralGraph!.WithSurfaceComponents(_componentUpdate!.Result);
 73        }
 74    }
 75
 3376    internal bool RevalidateForPublication() => _refresh.RevalidateForPublication();
 77
 78    internal AdvanceStatus AdvanceOne(
 79        MaintenanceWorkMeter meter,
 80        long maximumRetainedBytes,
 81        int maximumPersistentPages)
 82    {
 146983        if (!_refresh.IsComplete)
 84        {
 140585            long revision = _refresh.Revision;
 140586            NavigationAutomaticSeamRefreshWork.SeamAdvanceStatus status =
 140587                _refresh.AdvanceOne(meter);
 140588            if (_refresh.Revision != revision)
 289                return AdvanceStatus.RestartRequired;
 140390            if (ExceedsCapacity(maximumRetainedBytes, maximumPersistentPages))
 191                return AdvanceStatus.CapacityExceeded;
 140292            return status switch
 140293            {
 140294                NavigationAutomaticSeamRefreshWork.SeamAdvanceStatus.Blocked =>
 15495                    AdvanceStatus.Blocked,
 140296                NavigationAutomaticSeamRefreshWork.SeamAdvanceStatus.Complete =>
 3697                    AdvanceStatus.Progressed,
 121298                _ => AdvanceStatus.Progressed
 140299            };
 100        }
 101
 142102        while (!_affectedCaptureComplete)
 103        {
 125104            if (_endpointOrdinal >= _refresh.ChangedStructuralEndpointCount)
 105            {
 34106                _affectedCaptureComplete = true;
 34107                break;
 108            }
 91109            if (!meter.TryConsumeDependencyEntries(1))
 12110                return AdvanceStatus.Blocked;
 79111            NavigationCellAddress address =
 79112                _refresh.GetChangedStructuralEndpointAt(_endpointOrdinal);
 79113            if (_endpointMedium == TraversalMedium.Solid)
 27114                _affectedAddresses = _affectedAddresses.Add(address);
 79115            if (_source.TryGetSurfaceComponent(
 79116                    address,
 79117                    _endpointMedium,
 79118                    out NavigationSurfaceComponentKey key,
 79119                    out _)
 79120                && !_affectedComponents.Contains(key))
 121            {
 18122                _affectedComponents = _affectedComponents.Add(key);
 18123                _source.SurfaceComponents.TryGet(key, out NavigationSurfaceComponent component);
 18124                _affectedMemberCount = checked(
 18125                    _affectedMemberCount + component.Members.Count);
 126            }
 79127            if (_endpointMedium == TraversalMedium.Liquid)
 128            {
 26129                _endpointMedium = TraversalMedium.Solid;
 26130                _endpointOrdinal++;
 131            }
 132            else
 133            {
 53134                _endpointMedium++;
 135            }
 79136            if (ExceedsCapacity(maximumRetainedBytes, maximumPersistentPages))
 1137                return AdvanceStatus.CapacityExceeded;
 138        }
 139
 51140        NavigationWorldGraph next = _source
 51141            .WithAutomaticSeams(_refresh.Result)
 51142            .ReopenStructuralScopes(_source.GraphVersion + 1);
 51143        _structuralGraph ??= next;
 51144        _componentUpdate ??= new NavigationSurfaceComponentBuildWork(
 51145            _structuralGraph,
 51146            _source,
 51147            _affectedComponents,
 51148            _affectedAddresses,
 51149            checked(_affectedMemberCount + _affectedAddresses.Count));
 51150        bool complete = _componentUpdate.Advance(meter);
 51151        if (ExceedsCapacity(maximumRetainedBytes, maximumPersistentPages))
 1152            return AdvanceStatus.CapacityExceeded;
 50153        return complete ? AdvanceStatus.Complete : AdvanceStatus.Blocked;
 154    }
 155
 156    private bool ExceedsCapacity(long maximumRetainedBytes, int maximumPersistentPages) =>
 1533157        RetainedBytes > maximumRetainedBytes
 1533158        || PersistentPageCount > maximumPersistentPages;
 159
 160    internal enum AdvanceStatus : byte
 161    {
 162        Blocked,
 163        Progressed,
 164        Complete,
 165        RestartRequired,
 166        CapacityExceeded
 167    }
 168}