< Summary

Information
Class: Gravitas.ColliderRegistry<T>
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/Core/ColliderRegistry.cs
Line coverage
100%
Covered lines: 56
Uncovered lines: 0
Coverable lines: 56
Total lines: 135
Line coverage: 100%
Branch coverage
100%
Covered branches: 20
Total branches: 20
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_Count()100%11100%
get_PeakCount()100%11100%
get_Item(...)100%11100%
Register(...)100%11100%
Remove(...)100%44100%
Clear()100%22100%
TryGetById(...)100%44100%
TryGetByServiceIndex(...)100%44100%
PrepareReplayColliders()100%44100%
RemoveLiveCollider(...)100%22100%
Compare(...)100%11100%

File(s)

/home/runner/work/Gravitas/Gravitas/src/Gravitas/Core/ColliderRegistry.cs

#LineLine coverage
 1//=======================================================================
 2// ColliderRegistry.cs
 3//=======================================================================
 4// MIT License, Copyright (c) 2026-present David Oravsky (mrdav30)
 5// See LICENSE file in the project root for full license information.
 6//=======================================================================
 7
 8using Gravitas.Colliders;
 9using SwiftCollections;
 10using System.Collections.Generic;
 11using System.Runtime.CompilerServices;
 12
 13namespace Gravitas;
 14
 15internal sealed class ColliderRegistry<TCollider>
 16    where TCollider : class, IPhysicsColliderRegistryItem
 17{
 18    private readonly SwiftBucket<TCollider> _byId;
 19    private readonly SwiftList<TCollider> _liveColliders;
 20    private readonly SwiftList<TCollider> _replayColliders;
 21    private int _nextReplayOrder;
 22
 1017023    public ColliderRegistry(int capacity = SwiftBucket<TCollider>.DefaultCapacity)
 24    {
 1017025        _byId = new SwiftBucket<TCollider>(capacity);
 1017026        _liveColliders = new SwiftList<TCollider>(capacity);
 1017027        _replayColliders = new SwiftList<TCollider>(capacity);
 1017028    }
 29
 1335130    public int Count => _liveColliders.Count;
 31
 44932    public int PeakCount => _byId.PeakCount;
 33
 34    public TCollider this[int serviceIndex]
 35    {
 36        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 262037        get => _liveColliders[serviceIndex];
 38    }
 39
 40    public int Register(TCollider collider)
 41    {
 1085542        SwiftThrowHelper.ThrowIfNull(collider, nameof(collider));
 43
 1085544        int id = _byId.Add(collider);
 1085545        int serviceIndex = _liveColliders.Count;
 1085546        collider.SetRegistryState(id, serviceIndex, _nextReplayOrder++);
 1085547        _liveColliders.Add(collider);
 1085548        return id;
 49    }
 50
 51    public bool Remove(TCollider collider)
 52    {
 48753        SwiftThrowHelper.ThrowIfNull(collider, nameof(collider));
 54
 48755        int id = collider.Id;
 48756        if (!TryGetById(id, out TCollider? registered) || !ReferenceEquals(registered, collider))
 357            return false;
 58
 48459        RemoveLiveCollider(collider);
 48460        _byId.RemoveAt(id);
 48461        collider.ClearRegistryState();
 48462        return true;
 63    }
 64
 65    public void Clear()
 66    {
 23067        for (int i = 0; i < _liveColliders.Count; i++)
 4868            _liveColliders[i].ClearRegistryState();
 69
 6770        _liveColliders.FastClear();
 6771        _replayColliders.FastClear();
 6772        _byId.Clear();
 6773        _nextReplayOrder = 0;
 6774    }
 75
 76    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 77    public bool TryGetById(int id, out TCollider? collider)
 78    {
 166345179        if (id < 0 || !_byId.TryGetValue(id, out TCollider? value))
 80        {
 26681            collider = null;
 26682            return false;
 83        }
 84
 166318585        collider = value;
 166318586        return true;
 87    }
 88
 89    public bool TryGetByServiceIndex(int serviceIndex, out TCollider? collider)
 90    {
 1591        if (serviceIndex < 0 || serviceIndex >= _liveColliders.Count)
 92        {
 693            collider = null;
 694            return false;
 95        }
 96
 997        collider = _liveColliders[serviceIndex];
 998        return true;
 99    }
 100
 101    public SwiftList<TCollider> PrepareReplayColliders()
 102    {
 2754103        _replayColliders.FastClear();
 2754104        _replayColliders.EnsureCapacity(_liveColliders.Count);
 18300105        for (int i = 0; i < _liveColliders.Count; i++)
 6396106            _replayColliders.Add(_liveColliders[i]);
 107
 2754108        _replayColliders.SortInPlace(default(ReplayOrderComparer));
 18300109        for (int i = 0; i < _replayColliders.Count; i++)
 6396110            _replayColliders[i].SetRegistryReplayOrdinal(i);
 111
 2754112        return _replayColliders;
 113    }
 114
 115    private void RemoveLiveCollider(TCollider collider)
 116    {
 484117        int index = collider.ServiceIndex;
 484118        int lastIndex = _liveColliders.Count - 1;
 484119        if (index != lastIndex)
 120        {
 96121            TCollider moved = _liveColliders[lastIndex];
 96122            _liveColliders[index] = moved;
 96123            moved.SetRegistryServiceIndex(index);
 124        }
 125
 484126        _liveColliders.RemoveAt(lastIndex);
 484127    }
 128
 129    private readonly struct ReplayOrderComparer : IComparer<TCollider>
 130    {
 131        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 132        public int Compare(TCollider? x, TCollider? y) =>
 3658133            x!.ReplayOrder.CompareTo(y!.ReplayOrder);
 134    }
 135}