< Summary

Information
Class: Trailblazer.Pathing.NavigationBaselineRebuild
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Graph/NavigationBaselineRebuild.cs
Line coverage
100%
Covered lines: 440
Uncovered lines: 0
Coverable lines: 440
Total lines: 678
Line coverage: 100%
Branch coverage
100%
Covered branches: 136
Total branches: 136
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// NavigationBaselineRebuild.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 System;
 9using System.Runtime.InteropServices;
 10using GridForge.Grids;
 11using GridForge.Grids.Topology;
 12using GridForge.Spatial;
 13
 14namespace Trailblazer.Pathing;
 15
 16/// <summary>Accumulates one immutable requested-address baseline under a finite frame budget.</summary>
 17internal sealed class NavigationBaselineRebuild
 18{
 19    private readonly NavigationMap _map;
 20    private readonly NavigationMapInstance _source;
 21    private readonly long _bakeVersion;
 22    private readonly long _overlayHighWater;
 23    private readonly long _dynamicSlotGeneration;
 24    private readonly int _dynamicSlotCount;
 25    private readonly int _addressCount;
 26    private readonly long _pageVersion;
 27    private readonly bool _discoversDefault;
 28    private GridCoveredAddressCursor? _coveredCursor;
 29    private NavigationMapInstance? _defaultCandidate;
 71730    private PersistentVoxelIndexMap<NavigationDynamicCellSlot> _defaultSeedSlots =
 71731        PersistentVoxelIndexMap<NavigationDynamicCellSlot>.Empty;
 71732    private PersistentIntMap<VoxelIndex> _defaultSeedIndexes =
 71733        PersistentIntMap<VoxelIndex>.Empty;
 71734    private NavigationSurfaceComponentKeySet _structuralChangedStates =
 71735        NavigationSurfaceComponentKeySet.Empty;
 36    private GridCoveredAddressGeneration _coveredGeneration;
 37    private bool _coveredGenerationBound;
 71738    private PersistentIntMap<NavigationPhysicalPage> _pages =
 71739        PersistentIntMap<NavigationPhysicalPage>.Empty;
 40    private int _cursor;
 41    private int _bakedCursor;
 42    private int _dynamicCursor;
 43    private int _defaultSeedCursor;
 44    private int _omittedDefaultSeedSlotCount;
 45    private int _omittedPhysicalDefaultSlotCount;
 46    private ulong _capturedChangeSequence;
 47    private long _worldSpawnToken;
 71748    private ushort _gridIndex = ushort.MaxValue;
 49    private long _gridSpawnToken;
 50    private ulong _gridLastChangeSequence;
 51    private bool _hasIdentity;
 52    private bool _completed;
 53    private bool _capacityBlocked;
 54    private bool _hasNewDefaultSlot;
 55    private bool _defaultPhysicalAddressSetChanged;
 56    private NavigationGridBaselineCapture _completedCapture;
 57
 71758    internal NavigationBaselineRebuild(NavigationMapInstance instance)
 59    {
 71760        _source = instance;
 71761        _map = instance.Map;
 71762        _bakeVersion = instance.BakeVersion;
 71763        _overlayHighWater = instance.Overlay.HighWaterSequence;
 71764        _dynamicSlotGeneration = instance.DynamicSlotGeneration;
 71765        _dynamicSlotCount = instance.DynamicSlotCount;
 71766        _addressCount = instance.AddressCount;
 71767        _pageVersion = instance.InstanceVersion;
 71768        _discoversDefault = instance.Map.DefaultCell.HasValue;
 71769        if (_discoversDefault)
 8670            _coveredCursor = new GridCoveredAddressCursor(generationCapacity: 1);
 71771    }
 72
 17273    internal string MapId => _map.MapId;
 74
 114175    internal long RetainedBytes => _discoversDefault
 114176        ? checked(320L
 114177            + _coveredCursor!.RetainedBytes
 114178            + (_defaultCandidate?.DefaultBaselineRetainedBytes
 114179                ?? _defaultSeedSlots.RetainedBytes + _defaultSeedIndexes.RetainedBytes)
 114180            + _structuralChangedStates.RetainedBytes)
 114181        : checked(192L + _pages.RetainedBytes + ((long)_pages.Count * 320L));
 82
 113783    internal int PersistentPageCount => _discoversDefault
 113784        ? checked(1
 113785            + (_defaultCandidate?.DefaultBaselinePersistentPages
 113786                ?? 2
 113787                    + _defaultSeedSlots.PersistentNodeCount
 113788                    + _defaultSeedIndexes.PersistentNodeCount)
 113789            + _structuralChangedStates.PersistentPageCount)
 113790        : 1 + (_pages.PersistentNodeCount * 2);
 91
 22892    internal bool IsComplete => _completed;
 93
 1394    internal bool IsCapacityBlocked => _capacityBlocked;
 95
 23696    internal bool RequiresCoveredDiscovery => _discoversDefault;
 97
 98    internal bool TryGetCompletedCapture(out NavigationGridBaselineCapture capture)
 99    {
 102100        capture = _completedCapture;
 102101        return _completed;
 102    }
 103
 104    internal static void GetRetainedTotals(
 105        PersistentStringMap<NavigationBaselineRebuild> rebuilds,
 106        out long retainedBytes,
 107        out int persistentPageCount)
 108    {
 63096109        if (rebuilds.Count == 0)
 110        {
 62320111            retainedBytes = 0;
 62320112            persistentPageCount = 0;
 62320113            return;
 114        }
 115
 776116        retainedBytes = rebuilds.RetainedBytes;
 776117        persistentPageCount = 1 + rebuilds.PersistentNodeCount;
 3202118        for (int i = 0; i < rebuilds.Count; i++)
 119        {
 825120            NavigationBaselineRebuild rebuild = rebuilds.GetValueAt(i);
 825121            retainedBytes = checked(retainedBytes + rebuild.RetainedBytes);
 825122            persistentPageCount = checked(persistentPageCount + rebuild.PersistentPageCount);
 123        }
 776124    }
 125
 126    internal static int CountCapacityBlocked(
 127        PersistentStringMap<NavigationBaselineRebuild> rebuilds)
 128    {
 2201129        int count = 0;
 4416130        for (int i = 0; i < rebuilds.Count; i++)
 131        {
 7132            if (rebuilds.GetValueAt(i).IsCapacityBlocked)
 1133                count++;
 134        }
 2201135        return count;
 136    }
 137
 138    internal bool Matches(NavigationMapInstance instance) =>
 103139        ReferenceEquals(_map, instance.Map)
 103140        && _bakeVersion == instance.BakeVersion
 103141        && _overlayHighWater == instance.Overlay.HighWaterSequence
 103142        && _dynamicSlotGeneration == instance.DynamicSlotGeneration
 103143        && _dynamicSlotCount == instance.DynamicSlotCount;
 144
 145    internal static bool MatchesCapturedGridIdentity(
 146        long capturedWorldSpawnToken,
 147        ushort capturedGridIndex,
 148        long capturedGridSpawnToken,
 149        ulong capturedGridLastChangeSequence,
 150        long expectedWorldSpawnToken,
 151        ushort expectedGridIndex,
 152        long expectedGridSpawnToken,
 153        ulong expectedGridLastChangeSequence) =>
 117154        capturedWorldSpawnToken == expectedWorldSpawnToken
 117155        && capturedGridIndex == expectedGridIndex
 117156        && capturedGridSpawnToken == expectedGridSpawnToken
 117157        && capturedGridLastChangeSequence == expectedGridLastChangeSequence;
 158
 159    internal static bool IsCoveredBaselineCurrent(
 160        bool captured,
 161        GridNavigationBaseline? baseline,
 162        ulong expectedCapturedChangeSequence,
 163        long expectedWorldSpawnToken,
 164        ushort expectedGridIndex,
 165        long expectedGridSpawnToken,
 166        ulong expectedGridLastChangeSequence) =>
 83167        captured
 83168        && baseline != null
 83169        && baseline.CapturedChangeSequence == expectedCapturedChangeSequence
 83170        && MatchesCapturedGridIdentity(
 83171            baseline.WorldSpawnToken,
 83172            baseline.GridIndex,
 83173            baseline.GridSpawnToken,
 83174            baseline.GridLastChangeSequence,
 83175            expectedWorldSpawnToken,
 83176            expectedGridIndex,
 83177            expectedGridSpawnToken,
 83178            expectedGridLastChangeSequence);
 179
 180    internal int Advance(
 181        GridWorld world,
 182        NavigationMapInstance instance,
 183        int maximumAddresses,
 184        long maximumRetainedBytes,
 185        int maximumPersistentPages,
 186        Span<VoxelIndex> addressScratch,
 187        Span<GridCoveredAddress> coveredAddressScratch,
 188        out NavigationGridBaselineCapture capture,
 189        out bool completed)
 190    {
 808191        capture = default;
 808192        completed = false;
 808193        _completed = false;
 808194        if (_capacityBlocked)
 2195            return 0;
 806196        if (maximumAddresses <= 0)
 16197            return 0;
 790198        if (_discoversDefault)
 199        {
 125200            return AdvanceDefaultDiscovery(
 125201                world,
 125202                maximumAddresses,
 125203                maximumRetainedBytes,
 125204                maximumPersistentPages,
 125205                addressScratch,
 125206                coveredAddressScratch,
 125207                out capture,
 125208                out completed);
 209        }
 210
 665211        int count = Math.Min(maximumAddresses, _addressCount - _cursor);
 665212        Span<VoxelIndex> requestedScratch = addressScratch.Slice(0, count);
 665213        int bakedCursor = _bakedCursor;
 665214        int dynamicCursor = _dynamicCursor;
 665215        instance.CopyCanonicalAddressChunk(
 665216            ref bakedCursor,
 665217            ref dynamicCursor,
 665218            requestedScratch);
 665219        ReadOnlySpan<VoxelIndex> requested = requestedScratch;
 665220        if (!world.TryCaptureNavigationBaseline(
 665221                _map.GridBinding.Key,
 665222                requested,
 665223                out GridNavigationBaseline? baseline)
 665224            || baseline == null)
 225        {
 1226            completed = true;
 1227            _completed = true;
 1228            capture = new NavigationGridBaselineCapture(0, baseline: null, isDelta: false);
 1229            _completedCapture = capture;
 1230            return count;
 231        }
 232
 664233        if (_hasIdentity
 664234            && !MatchesCapturedGridIdentity(
 664235                baseline.WorldSpawnToken,
 664236                baseline.GridIndex,
 664237                baseline.GridSpawnToken,
 664238                baseline.GridLastChangeSequence,
 664239                _worldSpawnToken,
 664240                _gridIndex,
 664241                _gridSpawnToken,
 664242                _gridLastChangeSequence))
 243        {
 1244            ResetProgress();
 1245            return count;
 246        }
 247
 663248        if (!_hasIdentity)
 249        {
 631250            _capturedChangeSequence = baseline.CapturedChangeSequence;
 631251            _worldSpawnToken = baseline.WorldSpawnToken;
 631252            _gridIndex = baseline.GridIndex;
 631253            _gridSpawnToken = baseline.GridSpawnToken;
 631254            _gridLastChangeSequence = baseline.GridLastChangeSequence;
 631255            _hasIdentity = true;
 256        }
 663257        _capturedChangeSequence = baseline.CapturedChangeSequence;
 258
 663259        PersistentIntMap<NavigationPhysicalPage> pages = instance.AppendPhysicalBaselinePages(
 663260            _pages,
 663261            baseline.VoxelStates,
 663262            _pageVersion);
 663263        long retainedBytes = EstimateRetainedBytes(pages);
 663264        int persistentPageCount = EstimatePersistentPageCount(pages);
 663265        if (retainedBytes > maximumRetainedBytes
 663266            || persistentPageCount > maximumPersistentPages)
 267        {
 1268            _capacityBlocked = true;
 1269            return count;
 270        }
 271
 662272        _pages = pages;
 662273        _bakedCursor = bakedCursor;
 662274        _dynamicCursor = dynamicCursor;
 662275        _cursor += count;
 662276        if (_cursor != _addressCount)
 36277            return count;
 278
 626279        completed = true;
 626280        _completed = true;
 626281        capture = new NavigationGridBaselineCapture(
 626282            _addressCount,
 626283            _pages,
 626284            _capturedChangeSequence,
 626285            _worldSpawnToken,
 626286            _gridIndex,
 626287            _gridSpawnToken,
 626288            _gridLastChangeSequence,
 626289            _map.GridBinding.Key);
 626290        _completedCapture = capture;
 626291        return count;
 292    }
 293
 294    private void ResetProgress()
 295    {
 3296        _pages = PersistentIntMap<NavigationPhysicalPage>.Empty;
 3297        _cursor = 0;
 3298        _bakedCursor = 0;
 3299        _dynamicCursor = 0;
 3300        _capturedChangeSequence = 0;
 3301        _worldSpawnToken = 0;
 3302        _gridIndex = ushort.MaxValue;
 3303        _gridSpawnToken = 0;
 3304        _gridLastChangeSequence = 0;
 3305        _hasIdentity = false;
 3306        _completed = false;
 3307        _capacityBlocked = false;
 3308        _completedCapture = default;
 3309        if (_discoversDefault)
 310        {
 2311            _defaultCandidate = null;
 2312            _defaultSeedSlots = PersistentVoxelIndexMap<NavigationDynamicCellSlot>.Empty;
 2313            _defaultSeedIndexes = PersistentIntMap<VoxelIndex>.Empty;
 2314            _defaultSeedCursor = 0;
 2315            _omittedDefaultSeedSlotCount = 0;
 2316            _omittedPhysicalDefaultSlotCount = 0;
 2317            _hasNewDefaultSlot = false;
 2318            _defaultPhysicalAddressSetChanged = false;
 2319            _coveredGeneration = default;
 2320            _coveredGenerationBound = false;
 2321            _structuralChangedStates = NavigationSurfaceComponentKeySet.Empty;
 322        }
 3323    }
 324
 325    private int AdvanceDefaultDiscovery(
 326        GridWorld world,
 327        int maximumAddresses,
 328        long maximumRetainedBytes,
 329        int maximumPersistentPages,
 330        Span<VoxelIndex> addressScratch,
 331        Span<GridCoveredAddress> coveredAddressScratch,
 332        out NavigationGridBaselineCapture capture,
 333        out bool completed)
 334    {
 125335        capture = default;
 125336        completed = false;
 125337        int seedProbes = AdvanceDefaultSeed(
 125338            maximumAddresses,
 125339            maximumRetainedBytes,
 125340            maximumPersistentPages);
 125341        if (_capacityBlocked || seedProbes != 0 || _defaultCandidate == null)
 45342            return seedProbes;
 80343        GridCoveredAddressCursor cursor = _coveredCursor!;
 80344        if (cursor.Status == GridCoveredAddressCursorStatus.Stale)
 345        {
 73346            if (!world.TryCaptureNavigationBaseline(
 73347                    _map.GridBinding.Key,
 73348                    ReadOnlySpan<VoxelIndex>.Empty,
 73349                    out GridNavigationBaseline? identity)
 73350                || identity == null)
 351            {
 1352                completed = true;
 1353                _completed = true;
 1354                capture = new NavigationGridBaselineCapture(
 1355                    0,
 1356                    baseline: null,
 1357                    isDelta: false);
 1358                _completedCapture = capture;
 1359                return 0;
 360            }
 361
 72362            _capturedChangeSequence = identity.CapturedChangeSequence;
 72363            _worldSpawnToken = identity.WorldSpawnToken;
 72364            _gridIndex = identity.GridIndex;
 72365            _gridSpawnToken = identity.GridSpawnToken;
 72366            _gridLastChangeSequence = identity.GridLastChangeSequence;
 72367            _hasIdentity = true;
 72368            _coveredGeneration = new GridCoveredAddressGeneration(
 72369                identity.ConfigurationKey,
 72370                identity.GridIndex,
 72371                identity.GridSpawnToken,
 72372                identity.GridLastChangeSequence);
 72373            bool began = world.TryBeginCoveredAddresses(
 72374                cursor,
 72375                identity.ConfigurationKey.BoundsMin,
 72376                identity.ConfigurationKey.BoundsMax,
 72377                eligibleGenerationCount: 1,
 72378                identity.ConfigurationKey);
 379            System.Diagnostics.Debug.Assert(began,
 380                "The one-generation baseline cursor is constructed with exact capacity one.");
 381        }
 382
 79383        ReadOnlySpan<GridCoveredAddressGeneration> input = _coveredGenerationBound
 79384            ? ReadOnlySpan<GridCoveredAddressGeneration>.Empty
 79385            : MemoryMarshal.CreateReadOnlySpan(ref _coveredGeneration, 1);
 79386        int outputLimit = Math.Min(
 79387            maximumAddresses,
 79388            Math.Min(addressScratch.Length, coveredAddressScratch.Length));
 79389        GridCoveredAddressCursorStatus status = world.AdvanceCoveredAddresses(
 79390            cursor,
 79391            input,
 79392            coveredAddressScratch,
 79393            lookupProbeLimit: _coveredGenerationBound ? 0 : 1,
 79394            addressProbeLimit: maximumAddresses,
 79395            outputLimit,
 79396            out _,
 79397            out int addressProbes,
 79398            out int inputsConsumed,
 79399            out int outputCount);
 79400        _coveredGenerationBound |= inputsConsumed != 0;
 79401        bool invalidated = status == GridCoveredAddressCursorStatus.Stale;
 402        System.Diagnostics.Debug.Assert(!invalidated || outputCount == 0,
 403            "A stale covered-address cursor discards the run without emitting output.");
 404
 910405        for (int i = 0; i < outputCount; i++)
 376406            addressScratch[i] = coveredAddressScratch[i].VoxelIndex;
 79407        bool captured = false;
 79408        GridNavigationBaseline? baseline = null;
 79409        if (outputCount > 0)
 410        {
 78411            captured = world.TryCaptureNavigationBaseline(
 78412                    _map.GridBinding.Key,
 78413                    addressScratch.Slice(0, outputCount),
 78414                    out baseline);
 415        }
 79416        return FinalizeCoveredAddressAdvance(
 79417            status,
 79418            addressProbes,
 79419            outputCount,
 79420            invalidated,
 79421            captured,
 79422            baseline,
 79423            cursor.RunStamp.ChangeSequence,
 79424            cursor.RunStamp.WorldSpawnToken,
 79425            maximumRetainedBytes,
 79426            maximumPersistentPages,
 79427            out capture,
 79428            out completed);
 429    }
 430
 431    internal int FinalizeCoveredAddressAdvance(
 432        GridCoveredAddressCursorStatus status,
 433        int addressProbes,
 434        int outputCount,
 435        bool invalidated,
 436        bool captured,
 437        GridNavigationBaseline? baseline,
 438        ulong expectedCapturedChangeSequence,
 439        long expectedWorldSpawnToken,
 440        long maximumRetainedBytes,
 441        int maximumPersistentPages,
 442        out NavigationGridBaselineCapture capture,
 443        out bool completed)
 444    {
 80445        capture = default;
 80446        completed = false;
 80447        if (outputCount > 0)
 448        {
 79449            invalidated |= !IsCoveredBaselineCurrent(
 79450                captured,
 79451                baseline,
 79452                expectedCapturedChangeSequence,
 79453                expectedWorldSpawnToken,
 79454                _gridIndex,
 79455                _gridSpawnToken,
 79456                _gridLastChangeSequence);
 79457            if (!invalidated)
 458            {
 78459                NavigationMapInstance next = _defaultCandidate!.AppendDefaultBaselineStates(
 78460                    _source,
 78461                    baseline!.VoxelStates,
 78462                    baseline.CapturedChangeSequence,
 78463                    _pageVersion);
 908464                for (int i = 0; i < baseline.VoxelStates.Length; i++)
 465                {
 376466                    VoxelIndex index = baseline.VoxelStates[i].VoxelIndex;
 376467                    bool sourcePresent = _source.IsPhysicallyPresent(index);
 376468                    bool nextPresent = next.IsPhysicallyPresent(index);
 376469                    _defaultPhysicalAddressSetChanged |= sourcePresent != nextPresent;
 376470                    bool sourceHasDynamic = _source.TryGetDynamicSlot(
 376471                        index,
 376472                        out NavigationDynamicCellSlot sourceSlot);
 376473                    bool nextHasDynamic = next.TryGetDynamicSlot(
 376474                        index,
 376475                        out NavigationDynamicCellSlot nextSlot);
 376476                    bool rediscoveredOmittedSlot = sourceHasDynamic
 376477                        && nextHasDynamic
 376478                        && sourceSlot.Slot == nextSlot.Slot
 376479                        && !_defaultSeedSlots.TryGetValue(index, out _);
 376480                    if (rediscoveredOmittedSlot)
 481                    {
 482                        System.Diagnostics.Debug.Assert(_omittedDefaultSeedSlotCount > 0,
 483                            "Each unique rediscovered omitted seed owns one pending seed count.");
 51484                        _omittedDefaultSeedSlotCount--;
 51485                        UpdateStructuralStates(
 51486                            index,
 51487                            _source.GetEffectiveMedia(index),
 51488                            add: false);
 489                    }
 376490                    if (sourcePresent
 376491                        && nextPresent
 376492                        && rediscoveredOmittedSlot)
 493                    {
 494                        System.Diagnostics.Debug.Assert(_omittedPhysicalDefaultSlotCount > 0,
 495                            "Each physically present rediscovered omitted seed owns one pending physical count.");
 50496                        _omittedPhysicalDefaultSlotCount--;
 497                    }
 376498                    if (!sourceHasDynamic && nextHasDynamic)
 499                    {
 125500                        _hasNewDefaultSlot = true;
 125501                        UpdateStructuralStates(index, next.GetEffectiveMedia(index), add: true);
 502                    }
 503                }
 78504                if (EstimateDefaultRetainedBytes(next) > maximumRetainedBytes
 78505                    || EstimateDefaultPersistentPages(next) > maximumPersistentPages)
 506                {
 1507                    _capacityBlocked = true;
 1508                    return addressProbes;
 509                }
 77510                _defaultCandidate = next;
 77511                _cursor = checked(_cursor + outputCount);
 77512                _capturedChangeSequence = baseline.CapturedChangeSequence;
 513            }
 514        }
 79515        if (invalidated)
 2516            return ResetAfterDefaultDiscoveryInvalidation(addressProbes);
 517
 77518        if (status != GridCoveredAddressCursorStatus.Complete)
 7519            return addressProbes;
 520
 70521        NavigationMapInstance prepared = _defaultCandidate!.CompleteDefaultBaseline(
 70522            _pageVersion,
 70523            _omittedDefaultSeedSlotCount == 0 && !_hasNewDefaultSlot);
 70524        completed = true;
 70525        _completed = true;
 70526        capture = new NavigationGridBaselineCapture(
 70527            prepared,
 70528            _structuralChangedStates,
 70529            _defaultPhysicalAddressSetChanged || _omittedPhysicalDefaultSlotCount != 0,
 70530            prepared.AddressCount,
 70531            _capturedChangeSequence,
 70532            _worldSpawnToken,
 70533            _gridIndex,
 70534            _gridSpawnToken,
 70535            _gridLastChangeSequence,
 70536            _map.GridBinding.Key);
 70537        _completedCapture = capture;
 70538        return addressProbes;
 539    }
 540
 541    private int ResetAfterDefaultDiscoveryInvalidation(int addressProbes)
 542    {
 2543        ResetProgress();
 2544        return addressProbes;
 545    }
 546
 547    private int AdvanceDefaultSeed(
 548        int maximumAddresses,
 549        long maximumRetainedBytes,
 550        int maximumPersistentPages)
 551    {
 125552        if (_defaultCandidate != null)
 43553            return 0;
 82554        int remaining = _source.DynamicSlotCount - _defaultSeedCursor;
 82555        int count = Math.Min(maximumAddresses, remaining);
 82556        PersistentVoxelIndexMap<NavigationDynamicCellSlot> slots = _defaultSeedSlots;
 82557        PersistentIntMap<VoxelIndex> indexes = _defaultSeedIndexes;
 82558        int omittedSlotCount = _omittedDefaultSeedSlotCount;
 82559        int omittedPhysicalSlotCount = _omittedPhysicalDefaultSlotCount;
 82560        NavigationSurfaceComponentKeySet structuralChangedStates =
 82561            _structuralChangedStates;
 356562        for (int i = 0; i < count; i++)
 563        {
 96564            _source.TryGetDefaultBaselineSeedSlot(
 96565                _defaultSeedCursor + i,
 96566                out NavigationDynamicCellSlot slot,
 96567                out bool retain);
 96568            if (retain)
 569            {
 24570                slots = slots.Set(slot.Index, slot);
 24571                indexes = indexes.Set(slot.Slot, slot.Index);
 572            }
 573            else
 574            {
 72575                omittedSlotCount++;
 72576                AddMediaStates(
 72577                    _map.MapId,
 72578                    slot.Index,
 72579                    _source.GetEffectiveMedia(slot.Index),
 72580                    ref structuralChangedStates);
 72581                if (_source.IsPhysicallyPresent(slot.Index))
 62582                    omittedPhysicalSlotCount++;
 583            }
 584        }
 82585        bool seedComplete = _defaultSeedCursor + count == _source.DynamicSlotCount;
 82586        NavigationMapInstance? candidate = seedComplete
 82587            ? _source.CreateDefaultBaselineSeed(_pageVersion, slots, indexes)
 82588            : null;
 82589        long retainedBytes = candidate == null
 82590            ? checked(
 82591                320L
 82592                + _coveredCursor!.RetainedBytes
 82593                + slots.RetainedBytes
 82594                + indexes.RetainedBytes
 82595                + structuralChangedStates.RetainedBytes)
 82596            : EstimateDefaultRetainedBytes(candidate);
 82597        int retainedPages = candidate == null
 82598            ? checked(
 82599                3
 82600                + slots.PersistentNodeCount
 82601                + indexes.PersistentNodeCount
 82602                + structuralChangedStates.PersistentPageCount)
 82603            : EstimateDefaultPersistentPages(candidate);
 82604        if (retainedBytes > maximumRetainedBytes
 82605            || retainedPages > maximumPersistentPages)
 606        {
 2607            _capacityBlocked = true;
 2608            return count;
 609        }
 80610        _defaultSeedSlots = slots;
 80611        _defaultSeedIndexes = indexes;
 80612        _defaultSeedCursor += count;
 80613        _omittedDefaultSeedSlotCount = omittedSlotCount;
 80614        _omittedPhysicalDefaultSlotCount = omittedPhysicalSlotCount;
 80615        _structuralChangedStates = structuralChangedStates;
 80616        _defaultCandidate = candidate;
 80617        return count;
 618    }
 619
 620    private void UpdateStructuralStates(VoxelIndex index, TraversalMedia media, bool add)
 621    {
 176622        for (TraversalMedium medium = TraversalMedium.Solid;
 704623             medium <= TraversalMedium.Liquid;
 528624             medium++)
 625        {
 528626            TraversalMedia bit = (TraversalMedia)NavigationMediumSlots<byte>.GetBit(medium);
 528627            if ((media & bit) == 0)
 628                continue;
 187629            var key = new NavigationSurfaceComponentKey(
 187630                new NavigationCellAddress(_map.MapId, index),
 187631                medium);
 187632            _structuralChangedStates = add
 187633                ? _structuralChangedStates.Add(key)
 187634                : _structuralChangedStates.Remove(key);
 635        }
 176636    }
 637
 638    private static void AddMediaStates(
 639        string mapId,
 640        VoxelIndex index,
 641        TraversalMedia media,
 642        ref NavigationSurfaceComponentKeySet states)
 643    {
 72644        for (TraversalMedium medium = TraversalMedium.Solid;
 288645             medium <= TraversalMedium.Liquid;
 216646             medium++)
 647        {
 216648            TraversalMedia bit = (TraversalMedia)NavigationMediumSlots<byte>.GetBit(medium);
 216649            if ((media & bit) != 0)
 650            {
 72651                states = states.Add(new NavigationSurfaceComponentKey(
 72652                    new NavigationCellAddress(mapId, index),
 72653                    medium));
 654            }
 655        }
 72656    }
 657
 155658    private long EstimateDefaultRetainedBytes(NavigationMapInstance candidate) => checked(
 155659        320L
 155660        + _coveredCursor!.RetainedBytes
 155661        + candidate.DefaultBaselineRetainedBytes
 155662        + _structuralChangedStates.RetainedBytes);
 663
 154664    private int EstimateDefaultPersistentPages(NavigationMapInstance candidate) => checked(
 154665        1
 154666        + candidate.DefaultBaselinePersistentPages
 154667        + _structuralChangedStates.PersistentPageCount);
 668
 669    private static long EstimateRetainedBytes(
 663670        PersistentIntMap<NavigationPhysicalPage> pages) => checked(
 663671            192L
 663672            + pages.RetainedBytes
 663673            + ((long)pages.Count * 320L));
 674
 675    private static int EstimatePersistentPageCount(
 676        PersistentIntMap<NavigationPhysicalPage> pages) =>
 663677            1 + (pages.PersistentNodeCount * 2);
 678}

Methods/Properties

.ctor(Trailblazer.Pathing.NavigationMapInstance)
get_MapId()
get_RetainedBytes()
get_PersistentPageCount()
get_IsComplete()
get_IsCapacityBlocked()
get_RequiresCoveredDiscovery()
TryGetCompletedCapture(Trailblazer.Pathing.NavigationGridBaselineCapture&)
GetRetainedTotals(Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.NavigationBaselineRebuild>,System.Int64&,System.Int32&)
CountCapacityBlocked(Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.NavigationBaselineRebuild>)
Matches(Trailblazer.Pathing.NavigationMapInstance)
MatchesCapturedGridIdentity(System.Int64,System.UInt16,System.Int64,System.UInt64,System.Int64,System.UInt16,System.Int64,System.UInt64)
IsCoveredBaselineCurrent(System.Boolean,GridForge.Grids.GridNavigationBaseline,System.UInt64,System.Int64,System.UInt16,System.Int64,System.UInt64)
Advance(GridForge.Grids.GridWorld,Trailblazer.Pathing.NavigationMapInstance,System.Int32,System.Int64,System.Int32,System.Span`1<GridForge.Spatial.VoxelIndex>,System.Span`1<GridForge.Grids.Topology.GridCoveredAddress>,Trailblazer.Pathing.NavigationGridBaselineCapture&,System.Boolean&)
ResetProgress()
AdvanceDefaultDiscovery(GridForge.Grids.GridWorld,System.Int32,System.Int64,System.Int32,System.Span`1<GridForge.Spatial.VoxelIndex>,System.Span`1<GridForge.Grids.Topology.GridCoveredAddress>,Trailblazer.Pathing.NavigationGridBaselineCapture&,System.Boolean&)
FinalizeCoveredAddressAdvance(GridForge.Grids.Topology.GridCoveredAddressCursorStatus,System.Int32,System.Int32,System.Boolean,System.Boolean,GridForge.Grids.GridNavigationBaseline,System.UInt64,System.Int64,System.Int64,System.Int32,Trailblazer.Pathing.NavigationGridBaselineCapture&,System.Boolean&)
ResetAfterDefaultDiscoveryInvalidation(System.Int32)
AdvanceDefaultSeed(System.Int32,System.Int64,System.Int32)
UpdateStructuralStates(GridForge.Spatial.VoxelIndex,Trailblazer.Pathing.TraversalMedia,System.Boolean)
AddMediaStates(System.String,GridForge.Spatial.VoxelIndex,Trailblazer.Pathing.TraversalMedia,Trailblazer.Pathing.NavigationSurfaceComponentKeySet&)
EstimateDefaultRetainedBytes(Trailblazer.Pathing.NavigationMapInstance)
EstimateDefaultPersistentPages(Trailblazer.Pathing.NavigationMapInstance)
EstimateRetainedBytes(Trailblazer.Pathing.PersistentIntMap`1<Trailblazer.Pathing.NavigationPhysicalPage>)
EstimatePersistentPageCount(Trailblazer.Pathing.PersistentIntMap`1<Trailblazer.Pathing.NavigationPhysicalPage>)