< Summary

Information
Class: Trailblazer.Pathing.NavigationSurfaceComponentIndex
Assembly: Trailblazer
File(s): /home/runner/work/Trailblazer/Trailblazer/src/Trailblazer/Pathing/Graph/NavigationSurfaceComponentIndex.cs
Line coverage
100%
Covered lines: 210
Uncovered lines: 0
Coverable lines: 210
Total lines: 344
Line coverage: 100%
Branch coverage
100%
Covered branches: 56
Total branches: 56
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%11100%
get_PersistentPageCount()100%11100%
get_PersistentMapNodeCount()100%11100%
TryGet(...)100%88100%
TryGet(...)100%44100%
AddComponentRecord(...)100%1010100%
AddMembership(...)100%66100%
RemoveComponentRecord(...)100%66100%
RemoveMembership(...)100%88100%
CreateEmptyRoots()100%22100%
GetRootBytes(...)100%66100%
GetRootNodeCount(...)100%22100%
GetRootObjectCount(...)100%44100%
GetRoots(...)100%11100%

File(s)

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

#LineLine coverage
 1//=======================================================================
 2// NavigationSurfaceComponentIndex.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>Maps exact stable surface addresses to immutable weak components.</summary>
 11internal sealed class NavigationSurfaceComponentIndex
 12{
 13    private const long BaseRetainedBytes = 112L;
 14
 15    private readonly NavigationMediumSlots<
 16        PersistentStringMap<PersistentVoxelIndexMap<NavigationSurfaceComponentKey>>>
 17        _membership;
 18    private readonly NavigationMediumSlots<
 19        PersistentStringMap<PersistentVoxelIndexMap<NavigationSurfaceComponent>>>
 20        _components;
 21    private readonly long _membershipMapBytes;
 22    private readonly long _componentMapBytes;
 23    private readonly long _componentValueBytes;
 24    private readonly int _membershipMapPages;
 25    private readonly int _componentMapPages;
 26    private readonly int _componentValuePages;
 27
 7215228    private NavigationSurfaceComponentIndex(
 7215229        NavigationMediumSlots<
 7215230            PersistentStringMap<PersistentVoxelIndexMap<NavigationSurfaceComponentKey>>>
 7215231            membership,
 7215232        NavigationMediumSlots<
 7215233            PersistentStringMap<PersistentVoxelIndexMap<NavigationSurfaceComponent>>>
 7215234            components,
 7215235        long membershipMapBytes,
 7215236        long componentMapBytes,
 7215237        long componentValueBytes,
 7215238        int membershipMapPages,
 7215239        int componentMapPages,
 7215240        int componentValuePages)
 41    {
 7215242        _membership = membership;
 7215243        _components = components;
 7215244        _membershipMapBytes = membershipMapBytes;
 7215245        _componentMapBytes = componentMapBytes;
 7215246        _componentValueBytes = componentValueBytes;
 7215247        _membershipMapPages = membershipMapPages;
 7215248        _componentMapPages = componentMapPages;
 7215249        _componentValuePages = componentValuePages;
 7215250    }
 51
 52    internal static NavigationSurfaceComponentIndex Empty { get; } = new(
 53        CreateEmptyRoots<NavigationSurfaceComponentKey>(),
 54        CreateEmptyRoots<NavigationSurfaceComponent>(),
 55        0,
 56        0,
 57        0,
 58        0,
 59        0,
 60        0);
 61
 379562    internal long RetainedBytes => checked(
 379563        BaseRetainedBytes
 379564        + GetRootBytes(_membership)
 379565        + GetRootBytes(_components)
 379566        + _membershipMapBytes
 379567        + _componentMapBytes
 379568        + _componentValueBytes);
 69
 379470    internal int PersistentPageCount => checked(
 379471        GetRootObjectCount(_membership)
 379472        + GetRootObjectCount(_components)
 379473        + GetRootNodeCount(_membership)
 379474        + GetRootNodeCount(_components)
 379475        + _membershipMapPages
 379476        + _componentMapPages
 379477        + _componentValuePages);
 78
 1759179    internal int PersistentMapNodeCount => checked(
 1759180        GetRootNodeCount(_membership)
 1759181        + GetRootNodeCount(_components)
 1759182        + _membershipMapPages
 1759183        + _componentMapPages);
 84
 85    internal bool TryGet(
 86        NavigationCellAddress address,
 87        TraversalMedium medium,
 88        out NavigationSurfaceComponent component)
 89    {
 337587090        if (!NavigationCell.IsKnownMedium(medium))
 91        {
 192            component = null!;
 193            return false;
 94        }
 337586995        _membership.TryGet(medium, out var membership);
 337586996        if (membership.TryGetValue(
 337586997                address.MapId,
 337586998                out PersistentVoxelIndexMap<NavigationSurfaceComponentKey> membershipMap)
 337586999            && membershipMap.TryGetValue(address.Index, out NavigationSurfaceComponentKey key)
 3375869100            && TryGet(key, out component))
 101        {
 3213191102            return true;
 103        }
 162678104        component = null!;
 162678105        return false;
 106    }
 107
 108    internal bool TryGet(
 109        NavigationSurfaceComponentKey key,
 110        out NavigationSurfaceComponent component)
 111    {
 3249362112        _components.TryGet(key.Medium, out var components);
 3249362113        if (components.TryGetValue(
 3249362114                key.Representative.MapId,
 3249362115                out PersistentVoxelIndexMap<NavigationSurfaceComponent> componentMap)
 3249362116            && componentMap.TryGetValue(key.Representative.Index, out component!))
 117        {
 3249337118            return true;
 119        }
 25120        component = null!;
 25121        return false;
 122    }
 123
 124    internal NavigationSurfaceComponentIndex AddComponentRecord(
 125        NavigationSurfaceComponent component,
 126        out int copiedPersistentNodes)
 127    {
 1964128        copiedPersistentNodes = 0;
 1964129        NavigationSurfaceComponentKey key = component.Key;
 1964130        _components.TryGet(key.Medium, out var components);
 1964131        bool hadComponentMap = components.TryGetValue(
 1964132            key.Representative.MapId,
 1964133            out PersistentVoxelIndexMap<NavigationSurfaceComponent> componentMap);
 1964134        componentMap ??= PersistentVoxelIndexMap<NavigationSurfaceComponent>.Empty;
 1964135        long componentMapBytes = _componentMapBytes
 1964136            - (hadComponentMap ? componentMap.RetainedBytes : 0L);
 1964137        int componentMapPages = _componentMapPages
 1964138            - (hadComponentMap ? componentMap.PersistentNodeCount : 0);
 1964139        bool replaced = componentMap.TryGetValue(
 1964140            key.Representative.Index,
 1964141            out NavigationSurfaceComponent prior);
 1964142        componentMap = componentMap.Set(
 1964143            key.Representative.Index,
 1964144            component,
 1964145            out int copied);
 1964146        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 1964147        componentMapBytes = checked(componentMapBytes + componentMap.RetainedBytes);
 1964148        componentMapPages = checked(componentMapPages + componentMap.PersistentNodeCount);
 1964149        components = components.Set(key.Representative.MapId, componentMap, out copied);
 1964150        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 151
 1964152        return new NavigationSurfaceComponentIndex(
 1964153            _membership,
 1964154            _components.Set(key.Medium, components),
 1964155            _membershipMapBytes,
 1964156            componentMapBytes,
 1964157            checked(_componentValueBytes
 1964158                - (replaced ? prior.RetainedBytes : 0L)
 1964159                + component.RetainedBytes),
 1964160            _membershipMapPages,
 1964161            componentMapPages,
 1964162            checked(_componentValuePages
 1964163                - (replaced ? prior.PersistentPageCount : 0)
 1964164                + component.PersistentPageCount));
 165    }
 166
 167    internal NavigationSurfaceComponentIndex AddMembership(
 168        NavigationCellAddress address,
 169        NavigationSurfaceComponentKey key,
 170        out int copiedPersistentNodes)
 171    {
 52971172        copiedPersistentNodes = 0;
 52971173        _membership.TryGet(key.Medium, out var membership);
 52971174        bool hadMembershipMap = membership.TryGetValue(
 52971175            address.MapId,
 52971176            out PersistentVoxelIndexMap<NavigationSurfaceComponentKey> membershipMap);
 52971177        membershipMap ??= PersistentVoxelIndexMap<NavigationSurfaceComponentKey>.Empty;
 52971178        long membershipMapBytes = _membershipMapBytes
 52971179            - (hadMembershipMap ? membershipMap.RetainedBytes : 0L);
 52971180        int membershipMapPages = _membershipMapPages
 52971181            - (hadMembershipMap ? membershipMap.PersistentNodeCount : 0);
 52971182        membershipMap = membershipMap.Set(address.Index, key, out int copied);
 52971183        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 52971184        membershipMapBytes = checked(membershipMapBytes + membershipMap.RetainedBytes);
 52971185        membershipMapPages = checked(membershipMapPages + membershipMap.PersistentNodeCount);
 52971186        membership = membership.Set(address.MapId, membershipMap, out copied);
 52971187        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 52971188        return new NavigationSurfaceComponentIndex(
 52971189            _membership.Set(key.Medium, membership),
 52971190            _components,
 52971191            membershipMapBytes,
 52971192            _componentMapBytes,
 52971193            _componentValueBytes,
 52971194            membershipMapPages,
 52971195            _componentMapPages,
 52971196            _componentValuePages);
 197    }
 198
 199    internal NavigationSurfaceComponentIndex RemoveComponentRecord(
 200        NavigationSurfaceComponent component,
 201        out int copiedPersistentNodes)
 202    {
 204203        copiedPersistentNodes = 0;
 204204        NavigationSurfaceComponentKey key = component.Key;
 204205        _components.TryGet(key.Medium, out var components);
 204206        if (!components.TryGetValue(
 204207                key.Representative.MapId,
 204208                out PersistentVoxelIndexMap<NavigationSurfaceComponent> componentMap)
 204209            || !componentMap.TryGetValue(
 204210                key.Representative.Index,
 204211                out NavigationSurfaceComponent existing))
 212        {
 1213            return this;
 214        }
 203215        long componentMapBytes = _componentMapBytes - componentMap.RetainedBytes;
 203216        int componentMapPages = _componentMapPages - componentMap.PersistentNodeCount;
 203217        componentMap = componentMap.Remove(key.Representative.Index, out bool removed, out int copied);
 203218        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 219        System.Diagnostics.Debug.Assert(removed);
 203220        if (componentMap.Count == 0)
 221        {
 154222            components = components.Remove(key.Representative.MapId, out _, out copied);
 223        }
 224        else
 225        {
 49226            components = components.Set(key.Representative.MapId, componentMap, out copied);
 49227            componentMapBytes = checked(componentMapBytes + componentMap.RetainedBytes);
 49228            componentMapPages = checked(componentMapPages + componentMap.PersistentNodeCount);
 229        }
 203230        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 203231        return new NavigationSurfaceComponentIndex(
 203232            _membership,
 203233            _components.Set(key.Medium, components),
 203234            _membershipMapBytes,
 203235            componentMapBytes,
 203236            checked(_componentValueBytes - existing.RetainedBytes),
 203237            _membershipMapPages,
 203238            componentMapPages,
 203239            checked(_componentValuePages - existing.PersistentPageCount));
 240    }
 241
 242    internal NavigationSurfaceComponentIndex RemoveMembership(
 243        NavigationCellAddress address,
 244        NavigationSurfaceComponentKey expectedKey,
 245        out int copiedPersistentNodes)
 246    {
 17015247        copiedPersistentNodes = 0;
 17015248        _membership.TryGet(expectedKey.Medium, out var membership);
 17015249        if (!membership.TryGetValue(
 17015250                address.MapId,
 17015251                out PersistentVoxelIndexMap<NavigationSurfaceComponentKey> membershipMap)
 17015252            || !membershipMap.TryGetValue(address.Index, out NavigationSurfaceComponentKey key)
 17015253            || !key.Equals(expectedKey))
 254        {
 2255            return this;
 256        }
 17013257        long membershipMapBytes = _membershipMapBytes - membershipMap.RetainedBytes;
 17013258        int membershipMapPages = _membershipMapPages - membershipMap.PersistentNodeCount;
 17013259        membershipMap = membershipMap.Remove(address.Index, out _, out int copied);
 17013260        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 17013261        if (membershipMap.Count == 0)
 262        {
 196263            membership = membership.Remove(address.MapId, out _, out copied);
 264        }
 265        else
 266        {
 16817267            membership = membership.Set(address.MapId, membershipMap, out copied);
 16817268            membershipMapBytes = checked(membershipMapBytes + membershipMap.RetainedBytes);
 16817269            membershipMapPages = checked(membershipMapPages + membershipMap.PersistentNodeCount);
 270        }
 17013271        copiedPersistentNodes = checked(copiedPersistentNodes + copied);
 17013272        return new NavigationSurfaceComponentIndex(
 17013273            _membership.Set(expectedKey.Medium, membership),
 17013274            _components,
 17013275            membershipMapBytes,
 17013276            _componentMapBytes,
 17013277            _componentValueBytes,
 17013278            membershipMapPages,
 17013279            _componentMapPages,
 17013280            _componentValuePages);
 281    }
 282
 283    private static NavigationMediumSlots<PersistentStringMap<PersistentVoxelIndexMap<T>>>
 284        CreateEmptyRoots<T>()
 285    {
 2286        var roots = default(
 2287            NavigationMediumSlots<PersistentStringMap<PersistentVoxelIndexMap<T>>>);
 2288        for (TraversalMedium medium = TraversalMedium.Solid;
 8289             medium <= TraversalMedium.Liquid;
 6290             medium++)
 291        {
 6292            roots = roots.Set(
 6293                medium,
 6294                PersistentStringMap<PersistentVoxelIndexMap<T>>.Empty);
 295        }
 2296        return roots;
 297    }
 298
 299    private static long GetRootBytes<T>(
 300        NavigationMediumSlots<PersistentStringMap<PersistentVoxelIndexMap<T>>> roots)
 301    {
 7590302        GetRoots(roots, out var solid, out var gas, out var liquid);
 7590303        return checked(
 7590304            solid.RetainedBytes
 7590305            + (ReferenceEquals(gas, solid) ? 0L : gas.RetainedBytes)
 7590306            + (ReferenceEquals(liquid, solid) || ReferenceEquals(liquid, gas)
 7590307                ? 0L
 7590308                : liquid.RetainedBytes));
 309    }
 310
 311    private static int GetRootNodeCount<T>(
 312        NavigationMediumSlots<PersistentStringMap<PersistentVoxelIndexMap<T>>> roots)
 313    {
 42770314        int total = 0;
 42770315        for (TraversalMedium medium = TraversalMedium.Solid;
 171080316             medium <= TraversalMedium.Liquid;
 128310317             medium++)
 318        {
 128310319            roots.TryGet(medium, out var root);
 128310320            total = checked(total + root.PersistentNodeCount);
 321        }
 42770322        return total;
 323    }
 324
 325    private static int GetRootObjectCount<T>(
 326        NavigationMediumSlots<PersistentStringMap<PersistentVoxelIndexMap<T>>> roots)
 327    {
 7588328        GetRoots(roots, out var solid, out var gas, out var liquid);
 7588329        return 1
 7588330            + (ReferenceEquals(gas, solid) ? 0 : 1)
 7588331            + (ReferenceEquals(liquid, solid) || ReferenceEquals(liquid, gas) ? 0 : 1);
 332    }
 333
 334    private static void GetRoots<T>(
 335        NavigationMediumSlots<PersistentStringMap<PersistentVoxelIndexMap<T>>> roots,
 336        out PersistentStringMap<PersistentVoxelIndexMap<T>> solid,
 337        out PersistentStringMap<PersistentVoxelIndexMap<T>> gas,
 338        out PersistentStringMap<PersistentVoxelIndexMap<T>> liquid)
 339    {
 15178340        roots.TryGet(TraversalMedium.Solid, out solid!);
 15178341        roots.TryGet(TraversalMedium.Gas, out gas!);
 15178342        roots.TryGet(TraversalMedium.Liquid, out liquid!);
 15178343    }
 344}

Methods/Properties

.ctor(Trailblazer.Pathing.NavigationMediumSlots`1<Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<Trailblazer.Pathing.NavigationSurfaceComponentKey>>>,Trailblazer.Pathing.NavigationMediumSlots`1<Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<Trailblazer.Pathing.NavigationSurfaceComponent>>>,System.Int64,System.Int64,System.Int64,System.Int32,System.Int32,System.Int32)
get_RetainedBytes()
get_PersistentPageCount()
get_PersistentMapNodeCount()
TryGet(Trailblazer.Pathing.NavigationCellAddress,Trailblazer.TraversalMedium,Trailblazer.Pathing.NavigationSurfaceComponent&)
TryGet(Trailblazer.Pathing.NavigationSurfaceComponentKey,Trailblazer.Pathing.NavigationSurfaceComponent&)
AddComponentRecord(Trailblazer.Pathing.NavigationSurfaceComponent,System.Int32&)
AddMembership(Trailblazer.Pathing.NavigationCellAddress,Trailblazer.Pathing.NavigationSurfaceComponentKey,System.Int32&)
RemoveComponentRecord(Trailblazer.Pathing.NavigationSurfaceComponent,System.Int32&)
RemoveMembership(Trailblazer.Pathing.NavigationCellAddress,Trailblazer.Pathing.NavigationSurfaceComponentKey,System.Int32&)
CreateEmptyRoots()
GetRootBytes(Trailblazer.Pathing.NavigationMediumSlots`1<Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<T>>>)
GetRootNodeCount(Trailblazer.Pathing.NavigationMediumSlots`1<Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<T>>>)
GetRootObjectCount(Trailblazer.Pathing.NavigationMediumSlots`1<Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<T>>>)
GetRoots(Trailblazer.Pathing.NavigationMediumSlots`1<Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<T>>>,Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<T>>&,Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<T>>&,Trailblazer.Pathing.PersistentStringMap`1<Trailblazer.Pathing.PersistentVoxelIndexMap`1<T>>&)