< Summary

Information
Class: Trailblazer.Pathing.NavigationMaterializedComponentWork
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Graph/NavigationMaterializedComponentWork.cs
Line coverage
100%
Covered lines: 362
Uncovered lines: 0
Coverable lines: 362
Total lines: 573
Line coverage: 100%
Branch coverage
100%
Covered branches: 202
Total branches: 202
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%66100%
get_IsComplete()100%66100%
IsLifecycleComplete(...)100%88100%
get_Result()100%22100%
RevalidateForPublication()100%44100%
get_RequiresSnapshotRestart()100%11100%
get_RetainedEventCount()100%11100%
get_RetainedBytes()100%2424100%
get_PersistentPageCount()100%1414100%
Advance(...)100%3232100%
AdvanceFront(...)100%3636100%
AddChangedMedia(...)100%44100%
AdvanceAffectedCapture(...)100%3232100%
AdvanceSolidAdjacency(...)100%1414100%
AdvanceVolumeAdjacency(...)100%1414100%
CapturePriorComponent(...)100%66100%
CompleteState()100%11100%
ResetComponentState()100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// NavigationMaterializedComponentWork.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;
 9using GridForge.Spatial;
 10
 11namespace Trailblazer.Pathing;
 12
 13/// <summary>
 14/// Captures exact components incident to newly materialized medium states, then delegates the
 15/// bounded rebuild to the ordinary component builder.
 16/// </summary>
 17internal sealed class NavigationMaterializedComponentWork
 18{
 19    internal const long BaseRetainedBytes = 3_856L;
 20
 21    private readonly NavigationWorldGraph _candidate;
 22    private readonly GridWorld? _world;
 23    private readonly NavigationGridBaselineCapture[]? _baselineCaptures;
 24    private readonly int[]? _affectedMapOrdinals;
 25    private readonly int _affectedMapCount;
 26    private readonly GridEventInfo[]? _events;
 27    private readonly int _eventCount;
 28    private readonly NavigationOperationCandidate? _transitionCandidate;
 29    private readonly NavigationSurfaceComponentKeySet _initialAffectedKeys;
 30    private readonly NavigationCellAddressSet _initialSeeds;
 31    private readonly int _initialAffectedMemberCount;
 32    private NavigationSurfaceComponentKeySet _changedStates;
 290033    private PersistentStringMap<bool> _seamDiscoveryMaps = PersistentStringMap<bool>.Empty;
 290034    private PersistentStringMap<bool> _transitionChangedMaps = PersistentStringMap<bool>.Empty;
 35    private NavigationTransitionRefreshWork? _transitionRefresh;
 36    private NavigationWorldGraph? _transitionGraph;
 37    private NavigationAutomaticSeamRefreshWork? _seamRefresh;
 290038    private NavigationSurfaceComponentKeySet _affectedKeys =
 290039        NavigationSurfaceComponentKeySet.Empty;
 290040    private NavigationCellAddressSet _seeds = NavigationCellAddressSet.Empty;
 41    private NavigationSurfaceComponentBuildWork? _build;
 42    private NavigationWorldGraph? _componentGraph;
 43    private NavigationSurfaceComponentKeySet.Enumerator _changedStateEnumerator;
 44    private NavigationSurfaceComponentKey _state;
 45    private NavigationCellAddress? _pendingNeighbor;
 46    private NavigationSurfaceEdgeEnumerator _outgoing;
 47    private NavigationIncomingSurfaceEdgeEnumerator _incoming;
 48    private NavigationAutomaticSeamIndex.EndpointEnumerator _volumeSeams;
 49    private NavigationMediumStateRef _volumeSource;
 50    private int _stateOrdinal;
 51    private int _statePhase;
 52    private int _primaryOrdinal;
 53    private int _primaryCount;
 54    private int _affectedMemberCount;
 55    private int _frontAffectedOrdinal;
 56    private int _frontStateOrdinal;
 57    private int _frontEventOrdinal;
 290058    private long _seamRevision = -1;
 59    private NavigationSurfaceComponentKeySet.Enumerator _frontStateEnumerator;
 60    private bool _frontMapActive;
 61    private bool _frontComplete;
 62    private bool _hasNoChanges;
 63    private bool _outgoingComplete;
 64    private bool _requiresSnapshotRestart;
 65
 290066    internal NavigationMaterializedComponentWork(
 290067        NavigationWorldGraph candidate,
 290068        NavigationSurfaceComponentKeySet changedStates,
 290069        NavigationSurfaceComponentKeySet affectedKeys,
 290070        NavigationCellAddressSet seeds,
 290071        int affectedMemberCount,
 290072        GridWorld? world,
 290073        NavigationGridBaselineCapture[]? baselineCaptures,
 290074        int[]? affectedMapOrdinals,
 290075        int affectedMapCount,
 290076        GridEventInfo[]? events,
 290077        int eventCount,
 290078        NavigationOperationCandidate? transitionCandidate = null)
 79    {
 290080        _candidate = candidate;
 290081        _world = world;
 290082        _baselineCaptures = baselineCaptures;
 290083        _affectedMapOrdinals = affectedMapOrdinals;
 290084        _affectedMapCount = affectedMapCount;
 290085        _events = events;
 290086        _eventCount = eventCount;
 290087        _transitionCandidate = transitionCandidate;
 290088        _changedStates = changedStates;
 290089        _affectedKeys = affectedKeys;
 290090        _seeds = seeds;
 290091        _affectedMemberCount = affectedMemberCount;
 290092        _initialAffectedKeys = affectedKeys;
 290093        _initialSeeds = seeds;
 290094        _initialAffectedMemberCount = affectedMemberCount;
 290095        _frontComplete = world == null;
 290096        if (_frontComplete)
 97        {
 105198            _changedStateEnumerator = changedStates.GetEnumerator();
 105199            _componentGraph = candidate;
 1051100            _hasNoChanges = changedStates.Count == 0
 1051101                && affectedKeys.Count == 0
 1051102                && seeds.Count == 0;
 103        }
 2900104    }
 105
 71106    internal bool IsComplete => IsLifecycleComplete(
 71107        _frontComplete,
 71108        _transitionRefresh?.IsComplete,
 71109        _hasNoChanges,
 71110        _seamRefresh?.IsComplete,
 71111        _build?.IsComplete);
 112
 113    internal static bool IsLifecycleComplete(
 114        bool frontComplete,
 115        bool? transitionRefreshComplete,
 116        bool hasNoChanges,
 117        bool? seamRefreshComplete,
 78118        bool? buildComplete) => frontComplete
 78119        && transitionRefreshComplete != false
 78120        && (hasNoChanges
 78121            || (seamRefreshComplete != false && buildComplete == true));
 122
 123    internal NavigationWorldGraph Result
 124    {
 125        get
 126        {
 127            System.Diagnostics.Debug.Assert(_componentGraph != null,
 128                "Completed materialized work owns an explicit component graph.");
 2827129            return _build == null
 2827130                ? _componentGraph!
 2827131                : _componentGraph!.WithSurfaceComponents(_build.Result);
 132        }
 133    }
 134
 135    internal bool RevalidateForPublication()
 136    {
 2037137        if (_seamRefresh == null)
 2014138            return true;
 23139        long revision = _seamRefresh.Revision;
 23140        if (_seamRefresh.RevalidateForPublication())
 22141            return true;
 142        System.Diagnostics.Debug.Assert(_seamRefresh.Revision != revision,
 143            "Failed seam revalidation resets the refresh and advances its revision.");
 1144        ResetComponentState();
 1145        _requiresSnapshotRestart = true;
 1146        return false;
 147    }
 148
 7447149    internal bool RequiresSnapshotRestart => _requiresSnapshotRestart;
 150
 13151    internal int RetainedEventCount => _eventCount;
 152
 13209153    internal long RetainedBytes => checked(
 13209154        BaseRetainedBytes
 13209155        + _candidate.RetainedBytes
 13209156        + (_transitionGraph == null || ReferenceEquals(_transitionGraph, _candidate)
 13209157            ? 0L
 13209158            : NavigationWorldGraph.BaseRetainedBytes)
 13209159        + (_componentGraph == null
 13209160            || ReferenceEquals(_componentGraph, _candidate)
 13209161            || ReferenceEquals(_componentGraph, _transitionGraph)
 13209162                ? 0L
 13209163                : NavigationWorldGraph.BaseRetainedBytes)
 13209164        + _changedStates.RetainedBytes
 13209165        + (_seamRefresh == null ? _seamDiscoveryMaps.RetainedBytes : 0L)
 13209166        + (_world == null ? 0L : _transitionChangedMaps.RetainedBytes)
 13209167        + (_transitionRefresh?.RetainedBytes ?? 0L)
 13209168        + _affectedKeys.RetainedBytes
 13209169        + (ReferenceEquals(_initialAffectedKeys, _affectedKeys)
 13209170            ? 0L
 13209171            : _initialAffectedKeys.RetainedBytes)
 13209172        + _seeds.RetainedBytes
 13209173        + (ReferenceEquals(_initialSeeds, _seeds) ? 0L : _initialSeeds.RetainedBytes)
 13209174        + (_seamRefresh?.RetainedBytes ?? 0L)
 13209175        + (_build?.RetainedBytes ?? 0L));
 176
 13460177    internal int PersistentPageCount => checked(
 13460178        1
 13460179        + _candidate.PersistentPageCount
 13460180        + _changedStates.PersistentPageCount
 13460181        + (_seamRefresh == null ? 1 + _seamDiscoveryMaps.PersistentNodeCount : 0)
 13460182        + (_world == null ? 0 : 1 + _transitionChangedMaps.PersistentNodeCount)
 13460183        + (_transitionRefresh?.PersistentPageCount ?? 0)
 13460184        + _affectedKeys.PersistentPageCount
 13460185        + (ReferenceEquals(_initialAffectedKeys, _affectedKeys)
 13460186            ? 0
 13460187            : _initialAffectedKeys.PersistentPageCount)
 13460188        + _seeds.PersistentPageCount
 13460189        + (ReferenceEquals(_initialSeeds, _seeds)
 13460190            ? 0
 13460191            : _initialSeeds.PersistentPageCount)
 13460192        + (_seamRefresh?.PersistentPageCount ?? 0)
 13460193        + (_build?.PersistentPageCount ?? 0));
 194
 195    internal bool Advance(MaintenanceWorkMeter meter)
 196    {
 7755197        if (!_frontComplete && !AdvanceFront(meter))
 268198            return false;
 7487199        if (_world != null)
 200        {
 5333201            _transitionRefresh ??= new NavigationTransitionRefreshWork(
 5333202                _candidate,
 5333203                _candidate,
 5333204                _transitionCandidate,
 5333205                _transitionChangedMaps,
 5333206                rebuildRules: false,
 5333207                _candidate.GraphVersion);
 5333208            if (!_transitionRefresh.Advance(meter))
 749209                return false;
 4584210            if (_transitionGraph == null)
 211            {
 1846212                _transitionGraph = _candidate.WithTransitionPublication(
 1846213                    _transitionRefresh.Pages,
 1846214                    _transitionRefresh.Rules);
 215            }
 4584216            if (_seamRefresh == null)
 4432217                _componentGraph = _transitionGraph;
 218        }
 6738219        if (_hasNoChanges)
 1989220            return true;
 4749221        if (_seamRefresh != null)
 222        {
 152223            if (_seamRevision != _seamRefresh.Revision)
 22224                ResetComponentState();
 400225            while (!_seamRefresh.IsComplete)
 226            {
 264227                NavigationAutomaticSeamRefreshWork.SeamAdvanceStatus seamStatus =
 264228                    _seamRefresh.AdvanceOne(meter);
 264229                if (_seamRevision != _seamRefresh.Revision)
 230                {
 1231                    ResetComponentState();
 1232                    _requiresSnapshotRestart = true;
 1233                    return false;
 234                }
 263235                if (seamStatus == NavigationAutomaticSeamRefreshWork.SeamAdvanceStatus.Blocked)
 15236                    return false;
 237            }
 136238            if (_componentGraph == null)
 239            {
 21240                _seamRevision = _seamRefresh.Revision;
 241                System.Diagnostics.Debug.Assert(_transitionGraph != null,
 242                    "Seam refresh follows transition publication for materialized work.");
 21243                _componentGraph = _transitionGraph!
 21244                    .WithAutomaticSeams(_seamRefresh.Result);
 245            }
 246        }
 4733247        if (_build != null)
 2382248            return _build.Advance(meter);
 2351249        if (!AdvanceAffectedCapture(meter))
 1259250            return false;
 1092251        _build = new NavigationSurfaceComponentBuildWork(
 1092252            _componentGraph!,
 1092253            _candidate,
 1092254            _affectedKeys,
 1092255            _seeds,
 1092256            checked(_affectedMemberCount + _seeds.Count));
 1092257        return _build.Advance(meter);
 258    }
 259
 260    private bool AdvanceFront(MaintenanceWorkMeter meter)
 261    {
 8280262        while (_frontAffectedOrdinal < _affectedMapCount)
 263        {
 6402264            int mapOrdinal = _affectedMapOrdinals![_frontAffectedOrdinal];
 6402265            NavigationGridBaselineCapture capture = _baselineCaptures![mapOrdinal];
 6402266            NavigationSurfaceComponentKeySet? states = capture.StructuralChangedStates;
 6402267            if (!_frontMapActive)
 268            {
 1606269                if (!meter.TryConsumeComponentNodes(1))
 211270                    return false;
 1395271                string changedMapId = _candidate.GetInstance(mapOrdinal).MapId;
 1395272                _transitionChangedMaps = _transitionChangedMaps.Set(changedMapId, true);
 1395273                if (capture.DefaultPhysicalAddressSetChanged)
 274                {
 24275                    _seamDiscoveryMaps = _seamDiscoveryMaps.Set(
 24276                        _candidate.GetInstance(mapOrdinal).MapId,
 24277                        true);
 278                }
 1395279                _frontStateOrdinal = 0;
 1395280                _frontStateEnumerator = states?.GetEnumerator() ?? default;
 1395281                _frontMapActive = true;
 282            }
 6191283            if (states != null && _frontStateOrdinal < states.Count)
 284            {
 78285                if (!meter.TryConsumeDependencyEntries(1))
 1286                    return false;
 77287                _frontStateEnumerator.MoveNext();
 77288                _changedStates = _changedStates.Add(_frontStateEnumerator.Current);
 77289                _frontStateOrdinal++;
 77290                continue;
 291            }
 6113292            GridNavigationBaseline? baseline = states == null ? capture.Baseline : null;
 6113293            if (baseline != null && _frontStateOrdinal < baseline.VoxelStates.Length)
 294            {
 4719295                if (!meter.TryConsumeDependencyEntries(1))
 25296                    return false;
 4694297                AddChangedMedia(
 4694298                    _candidate.GetInstance(mapOrdinal),
 4694299                    baseline.VoxelStates[_frontStateOrdinal++].VoxelIndex);
 4694300                continue;
 301            }
 1394302            _frontMapActive = false;
 1394303            _frontAffectedOrdinal++;
 304        }
 305
 2925306        while (_frontEventOrdinal < _eventCount)
 307        {
 1078308            if (!meter.TryConsumeDependencyEntries(1))
 31309                return false;
 1047310            GridEventInfo eventInfo = _events![_frontEventOrdinal++];
 1047311            if (!_candidate.TryGetMapId(
 1047312                    eventInfo.Configuration.ToGridKey(),
 1047313                    out string mapId))
 314                continue;
 115315            bool foundMap = _candidate.TryGetMap(mapId, out NavigationMapInstance next);
 316            System.Diagnostics.Debug.Assert(foundMap,
 317                "The immutable configuration index and map directory share one candidate graph.");
 115318            _transitionChangedMaps = _transitionChangedMaps.Set(mapId, true);
 115319            if (eventInfo.HasVoxelState)
 80320                AddChangedMedia(next, eventInfo.VoxelIndex);
 321        }
 322
 1847323        _frontComplete = true;
 1847324        if (_changedStates.Count == 0)
 325        {
 1804326            _componentGraph = _candidate;
 1804327            _hasNoChanges = true;
 1804328            return true;
 329        }
 43330        _seamRefresh = _seamDiscoveryMaps.Count == 0
 43331            ? null
 43332            : new NavigationAutomaticSeamRefreshWork(
 43333                _world!,
 43334                _candidate,
 43335                _candidate,
 43336                _seamDiscoveryMaps);
 43337        _changedStateEnumerator = _changedStates.GetEnumerator();
 43338        return true;
 339    }
 340
 341    private void AddChangedMedia(NavigationMapInstance next, VoxelIndex index)
 342    {
 4774343        var address = new NavigationCellAddress(next.MapId, index);
 4774344        TraversalMedia nextMedia = next.GetEffectiveMedia(index);
 4774345        for (TraversalMedium medium = TraversalMedium.Solid;
 19096346             medium <= TraversalMedium.Liquid;
 14322347             medium++)
 348        {
 14322349            TraversalMedia bit = (TraversalMedia)NavigationMediumSlots<byte>.GetBit(medium);
 14322350            bool priorHasState = _candidate.SurfaceComponents.TryGet(address, medium, out _);
 14322351            bool nextHasState = (nextMedia & bit) != 0;
 14322352            if (priorHasState != nextHasState)
 353            {
 1199354                _changedStates = _changedStates.Add(
 1199355                    new NavigationSurfaceComponentKey(address, medium));
 356            }
 357        }
 4774358    }
 359
 360    private bool AdvanceAffectedCapture(MaintenanceWorkMeter meter)
 361    {
 35262362        while (_stateOrdinal < _changedStates.Count || _statePhase != 0)
 363        {
 34170364            if (_pendingNeighbor.HasValue)
 365            {
 9146366                if (!CapturePriorComponent(_pendingNeighbor.Value, _state.Medium, meter))
 1367                    return false;
 9145368                _pendingNeighbor = null;
 9145369                continue;
 370            }
 25024371            if (_statePhase == 0)
 372            {
 3296373                if (!meter.TryConsumeComponentNodes(1))
 1230374                    return false;
 2066375                _changedStateEnumerator.MoveNext();
 2066376                _state = _changedStateEnumerator.Current;
 2066377                _stateOrdinal++;
 2066378                _statePhase = 1;
 379            }
 23794380            if (_statePhase == 1)
 381            {
 2067382                if (!_seeds.Contains(_state.Representative))
 383                {
 1271384                    if (!meter.TryConsumeDependencyEntries(1))
 1385                        return false;
 1270386                    _seeds = _seeds.Add(_state.Representative);
 387                }
 2066388                _pendingNeighbor = _state.Representative;
 2066389                _statePhase = 2;
 2066390                continue;
 391            }
 21727392            if (_statePhase == 2)
 393            {
 2066394                if (_state.Medium == TraversalMedium.Solid)
 395                {
 1255396                    if (!_componentGraph!.TryGetStructuralMediumStateRef(
 1255397                            _state.Representative,
 1255398                            TraversalMedium.Solid,
 1255399                            out NavigationMediumStateRef solidState))
 400                    {
 2401                        CompleteState();
 2402                        continue;
 403                    }
 1253404                    NavigationNodeRef node = solidState.Node;
 1253405                    _outgoing = _componentGraph.EnumerateStructuralSurfaceEdges(node);
 1253406                    _incoming = _componentGraph.EnumerateIncomingStructuralSurfaceEdges(node);
 1253407                    _outgoingComplete = false;
 408                }
 409                else
 410                {
 811411                    if (!_componentGraph!.TryGetStructuralMediumStateRef(
 811412                            _state.Representative,
 811413                            _state.Medium,
 811414                            out _volumeSource))
 415                    {
 12416                        CompleteState();
 12417                        continue;
 418                    }
 799419                    _primaryOrdinal = 0;
 799420                    _primaryCount = _componentGraph.GetPrimaryDirectionCount(_volumeSource.Node);
 799421                    _volumeSeams = _componentGraph.AutomaticSeams.GetActiveEndpointEnumerator(
 799422                        _state.Representative);
 423                }
 2052424                _statePhase = 3;
 425            }
 21713426            if (_state.Medium == TraversalMedium.Solid)
 427            {
 18717428                if (!AdvanceSolidAdjacency(meter))
 15429                    return false;
 430            }
 2996431            else if (!AdvanceVolumeAdjacency(meter))
 432            {
 12433                return false;
 434            }
 435        }
 1092436        return true;
 437    }
 438
 439    private bool AdvanceSolidAdjacency(MaintenanceWorkMeter meter)
 440    {
 18717441        int remaining = meter.RemainingSurfaceComponentEdges;
 18717442        if (!_outgoingComplete)
 443        {
 7523444            NavigationSurfaceEdgeAdvanceStatus status = _outgoing.AdvanceOne(
 7523445                meter,
 7523446                ref remaining);
 7523447            if (status == NavigationSurfaceEdgeAdvanceStatus.Blocked)
 6448                return false;
 7517449            if (status == NavigationSurfaceEdgeAdvanceStatus.Pending)
 3817450                return true;
 3700451            if (status == NavigationSurfaceEdgeAdvanceStatus.Edge)
 452            {
 2447453                bool found = _componentGraph!.TryGetNodeAddress(
 2447454                    _outgoing.Current.Target,
 2447455                    out NavigationCellAddress address);
 456                System.Diagnostics.Debug.Assert(found,
 457                    "A published outgoing surface edge targets a node in the same graph.");
 2447458                _pendingNeighbor = address;
 2447459                return true;
 460            }
 1253461            _outgoingComplete = true;
 462        }
 12447463        NavigationSurfaceEdgeAdvanceStatus incoming = _incoming.AdvanceOne(
 12447464            meter,
 12447465            ref remaining);
 12447466        if (incoming == NavigationSurfaceEdgeAdvanceStatus.Blocked)
 9467            return false;
 12438468        if (incoming == NavigationSurfaceEdgeAdvanceStatus.Pending)
 8738469            return true;
 3700470        if (incoming == NavigationSurfaceEdgeAdvanceStatus.Edge)
 471        {
 2447472            bool found = _componentGraph!.TryGetNodeAddress(
 2447473                _incoming.Current.Predecessor,
 2447474                out NavigationCellAddress address);
 475            System.Diagnostics.Debug.Assert(found,
 476                "A published incoming surface edge originates at a node in the same graph.");
 2447477            _pendingNeighbor = address;
 2447478            return true;
 479        }
 1253480        CompleteState();
 1253481        return true;
 482    }
 483
 484    private bool AdvanceVolumeAdjacency(MaintenanceWorkMeter meter)
 485    {
 5996486        while (_primaryOrdinal < _primaryCount)
 487        {
 5148488            if (!meter.TryConsumeSurfaceComponentEdges(1))
 10489                return false;
 5138490            if (_componentGraph!.TryGetStructuralPrimaryMediumNeighbor(
 5138491                    _volumeSource,
 5138492                    _primaryOrdinal++,
 5138493                    out NavigationMediumStateRef neighbor)
 5138494                && _componentGraph.TryGetNodeAddress(
 5138495                    neighbor.Node,
 5138496                    out NavigationCellAddress address))
 497            {
 2138498                _pendingNeighbor = address;
 2138499                return true;
 500            }
 501        }
 861502        while (meter.RemainingSurfaceComponentEdges > 0)
 503        {
 859504            if (!_volumeSeams.MoveNext())
 505            {
 799506                CompleteState();
 799507                return true;
 508            }
 60509            meter.TryConsumeSurfaceComponentEdges(1);
 60510            NavigationCellAddress destination = _volumeSeams.Current.Destination;
 60511            if (_componentGraph!.TryGetStructuralMediumStateRef(
 60512                    destination,
 60513                    _state.Medium,
 60514                    out _))
 515            {
 47516                _pendingNeighbor = destination;
 47517                return true;
 518            }
 519        }
 2520        return false;
 521    }
 522
 523    private bool CapturePriorComponent(
 524        NavigationCellAddress address,
 525        TraversalMedium medium,
 526        MaintenanceWorkMeter meter)
 527    {
 9146528        if (!_candidate.SurfaceComponents.TryGet(
 9146529                address,
 9146530                medium,
 9146531                out NavigationSurfaceComponent component)
 9146532            || _affectedKeys.Contains(component.Key))
 533        {
 9131534            return true;
 535        }
 15536        if (!meter.TryConsumeDependencyEntries(1))
 1537            return false;
 14538        _affectedKeys = _affectedKeys.Add(component.Key);
 14539        _affectedMemberCount = checked(_affectedMemberCount + component.Members.Count);
 14540        return true;
 541    }
 542
 543    private void CompleteState()
 544    {
 2090545        _statePhase = 0;
 2090546        _pendingNeighbor = null;
 2090547        _outgoing = default;
 2090548        _incoming = default;
 2090549        _volumeSeams = default;
 2090550        _volumeSource = default;
 2090551        _primaryOrdinal = 0;
 2090552        _primaryCount = 0;
 2090553        _outgoingComplete = false;
 2090554    }
 555
 556    private void ResetComponentState()
 557    {
 558        System.Diagnostics.Debug.Assert(_seamRefresh != null,
 559            "Only seam revision changes restart component discovery.");
 24560        _affectedKeys = _initialAffectedKeys;
 24561        _seeds = _initialSeeds;
 24562        _affectedMemberCount = _initialAffectedMemberCount;
 24563        _changedStateEnumerator = _changedStates.GetEnumerator();
 24564        _state = default;
 24565        _stateOrdinal = 0;
 24566        _statePhase = 0;
 24567        _pendingNeighbor = null;
 24568        _build = null;
 24569        _componentGraph = null;
 24570        _seamRevision = _seamRefresh!.Revision;
 24571        CompleteState();
 24572    }
 573}