< Summary

Information
Class: GridForge.Grids.Topology.GridCoveredAddressCursor
Assembly: GridForge
File(s): /home/runner/work/GridForge/GridForge/src/GridForge/Grids/Topology/GridCoveredAddressCursor.cs
Line coverage
100%
Covered lines: 73
Uncovered lines: 0
Coverable lines: 73
Total lines: 189
Line coverage: 100%
Branch coverage
100%
Covered branches: 12
Total branches: 12
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%
.ctor(...)100%22100%
get_GenerationCapacity()100%11100%
get_RetainedBytes()100%22100%
get_Status()100%11100%
get_RunStamp()100%22100%
Begin(...)100%66100%
MarkStale()100%11100%

File(s)

/home/runner/work/GridForge/GridForge/src/GridForge/Grids/Topology/GridCoveredAddressCursor.cs

#LineLine coverage
 1//=======================================================================
 2// GridCoveredAddressCursor.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 FixedMathSharp;
 10using GridForge.Configuration;
 11using GridForge.Spatial;
 12using SwiftCollections.Utility;
 13
 14namespace GridForge.Grids.Topology;
 15
 16/// <summary>Describes the state of a resumable covered-address query.</summary>
 17public enum GridCoveredAddressCursorStatus : byte
 18{
 19    /// <summary>The bound revision or an eligible grid generation changed; discard the run.</summary>
 20    Stale = 0,
 21
 22    /// <summary>More generation-input, lookup, address, or output work is required.</summary>
 23    More = 1,
 24
 25    /// <summary>Every eligible covered topology address was examined.</summary>
 26    Complete = 2
 27}
 28
 29/// <summary>Stores caller-owned bounded progress for a value-only covered-address query.</summary>
 30/// <remarks>
 31/// Construct with the maximum eligible generation count, begin through <see cref="GridWorld"/>, then
 32/// supply the next canonical generation-input slice to each advance call until it is consumed. Once all
 33/// declared generations are bound, pass an empty input span. The cursor retains no live grid or voxel.
 34/// </remarks>
 35public sealed class GridCoveredAddressCursor
 36{
 37    private const long LogicalStateBytes = 512L;
 38    private const long ArrayHeaderBytes = 24L;
 39    private const long BoundGenerationBytes = 160L;
 40
 41    internal readonly struct BoundGeneration
 42    {
 43        internal BoundGeneration(
 44            GridCoveredAddressGeneration generation,
 45            VoxelIndex minimum,
 46            VoxelIndex maximum,
 47            bool hasRange)
 48        {
 5049            Generation = generation;
 5050            Minimum = minimum;
 5051            Maximum = maximum;
 5052            HasRange = hasRange;
 5053        }
 54
 55        internal GridCoveredAddressGeneration Generation { get; }
 56        internal VoxelIndex Minimum { get; }
 57        internal VoxelIndex Maximum { get; }
 58        internal bool HasRange { get; }
 59    }
 60
 61    internal readonly BoundGeneration[] Generations;
 62    internal long WorldSpawnToken;
 63    internal uint WorldVersion;
 64    internal ulong WorldChangeSequence;
 65    internal Vector3d QueryMinimum;
 66    internal Vector3d QueryMaximum;
 67    internal GridConfigurationKey FilterConfigurationKey;
 68    internal GridCoveredAddressGeneration LastBoundGeneration;
 69    internal GridCoveredAddress PendingOutput;
 70    internal VoxelIndex CurrentAddress;
 71    internal int ExpectedGenerationCount;
 72    internal int BoundGenerationCount;
 73    internal int RangeGenerationCount;
 74    internal int GenerationOrdinal;
 75    internal bool HasConfigurationFilter;
 76    internal bool HasLastBoundGeneration;
 77    internal bool HasPendingOutput;
 78    internal bool HasCurrentAddress;
 79    internal GridCoveredAddressCursorStatus CurrentStatus;
 80
 81    /// <summary>Initializes reusable storage for at most <paramref name="generationCapacity"/> eligible grids.</summary
 2482    public GridCoveredAddressCursor(int generationCapacity)
 83    {
 2484        SwiftThrowHelper.ThrowIfNegative(generationCapacity, nameof(generationCapacity));
 2485        Generations = generationCapacity == 0
 2486            ? Array.Empty<BoundGeneration>()
 2487            : new BoundGeneration[generationCapacity];
 2488    }
 89
 90    /// <summary>The maximum eligible generation count accepted by this cursor.</summary>
 191    public int GenerationCapacity => Generations.Length;
 92
 93    /// <summary>The deterministic logical bytes retained by this cursor and its owned generation storage.</summary>
 94    /// <remarks>Shared empty-array storage is not charged.</remarks>
 495    public long RetainedBytes => checked(
 496        LogicalStateBytes
 497        + (Generations.Length == 0
 498            ? 0L
 499            : ArrayHeaderBytes + ((long)Generations.Length * BoundGenerationBytes)));
 100
 101    /// <summary>The current query state.</summary>
 3102    public GridCoveredAddressCursorStatus Status => CurrentStatus;
 103
 104    /// <summary>The cumulative number of generation validation and spatial lookup probes.</summary>
 105    public ulong LookupProbeOrdinal { get; internal set; }
 106
 107    /// <summary>The cumulative number of topology-address probes.</summary>
 108    public ulong AddressProbeOrdinal { get; internal set; }
 109
 110    /// <summary>The cumulative number of covered addresses emitted.</summary>
 111    public ulong OutputOrdinal { get; internal set; }
 112
 113    /// <summary>The exact committed world revision bound by this cursor.</summary>
 114    public GridCoveredAddressRunStamp RunStamp =>
 19115        CurrentStatus == GridCoveredAddressCursorStatus.Stale
 19116            ? default
 19117            : new GridCoveredAddressRunStamp(
 19118                WorldSpawnToken,
 19119                WorldVersion,
 19120                WorldChangeSequence);
 121
 122    internal bool Begin(
 123        long worldSpawnToken,
 124        uint worldVersion,
 125        ulong worldChangeSequence,
 126        Vector3d queryMinimum,
 127        Vector3d queryMaximum,
 128        int expectedGenerationCount,
 129        bool hasConfigurationFilter,
 130        GridConfigurationKey filterConfigurationKey)
 131    {
 28132        if (expectedGenerationCount < 0 || expectedGenerationCount > Generations.Length)
 133        {
 2134            MarkStale();
 2135            return false;
 136        }
 137
 26138        WorldSpawnToken = worldSpawnToken;
 26139        WorldVersion = worldVersion;
 26140        WorldChangeSequence = worldChangeSequence;
 26141        QueryMinimum = queryMinimum;
 26142        QueryMaximum = queryMaximum;
 26143        ExpectedGenerationCount = expectedGenerationCount;
 26144        BoundGenerationCount = 0;
 26145        RangeGenerationCount = 0;
 26146        GenerationOrdinal = 0;
 26147        HasConfigurationFilter = hasConfigurationFilter;
 26148        FilterConfigurationKey = filterConfigurationKey;
 26149        LastBoundGeneration = default;
 26150        PendingOutput = default;
 26151        CurrentAddress = default;
 26152        HasPendingOutput = false;
 26153        HasCurrentAddress = false;
 26154        HasLastBoundGeneration = false;
 26155        LookupProbeOrdinal = 0;
 26156        AddressProbeOrdinal = 0;
 26157        OutputOrdinal = 0;
 26158        CurrentStatus = expectedGenerationCount == 0
 26159            ? GridCoveredAddressCursorStatus.Complete
 26160            : GridCoveredAddressCursorStatus.More;
 26161        return true;
 162    }
 163
 164    internal GridCoveredAddressCursorStatus MarkStale()
 165    {
 9166        WorldSpawnToken = 0;
 9167        WorldVersion = 0;
 9168        WorldChangeSequence = 0;
 9169        QueryMinimum = default;
 9170        QueryMaximum = default;
 9171        FilterConfigurationKey = default;
 9172        LastBoundGeneration = default;
 9173        PendingOutput = default;
 9174        CurrentAddress = default;
 9175        ExpectedGenerationCount = 0;
 9176        BoundGenerationCount = 0;
 9177        RangeGenerationCount = 0;
 9178        GenerationOrdinal = 0;
 9179        HasConfigurationFilter = false;
 9180        HasLastBoundGeneration = false;
 9181        HasPendingOutput = false;
 9182        HasCurrentAddress = false;
 9183        LookupProbeOrdinal = 0;
 9184        AddressProbeOrdinal = 0;
 9185        OutputOrdinal = 0;
 9186        CurrentStatus = GridCoveredAddressCursorStatus.Stale;
 9187        return CurrentStatus;
 188    }
 189}