< Summary

Information
Class: Gravitas.CollisionHandling.ContactWarmStartCache2D
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/CollisionHandling/Contacts/2D/ContactWarmStartCache2D.cs
Line coverage
100%
Covered lines: 55
Uncovered lines: 0
Coverable lines: 55
Total lines: 140
Line coverage: 100%
Branch coverage
100%
Covered branches: 24
Total branches: 24
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
Clear()100%11100%
Set(...)100%66100%
TryGet(...)100%44100%
Remove(...)100%66100%
GetContactIdForReplayHash(...)100%11100%
GetImpulseForReplayHash(...)100%11100%
GetContactId(...)100%22100%
GetImpulseUnchecked(...)100%22100%
SetContactIdUnchecked(...)100%22100%
SetImpulseUnchecked(...)100%22100%

File(s)

/home/runner/work/Gravitas/Gravitas/src/Gravitas/CollisionHandling/Contacts/2D/ContactWarmStartCache2D.cs

#LineLine coverage
 1//=======================================================================
 2// ContactWarmStartCache2D.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 FixedMathSharp;
 9using System.Runtime.CompilerServices;
 10
 11namespace Gravitas.CollisionHandling;
 12
 13/// <summary>
 14/// Fixed-size 2D warm-start cache keyed by stable manifold contact identity.
 15/// </summary>
 16internal struct ContactWarmStartCache2D
 17{
 18    private ulong _contactId0;
 19    private ulong _contactId1;
 20    private ContactWarmStartImpulse _impulse0;
 21    private ContactWarmStartImpulse _impulse1;
 22
 23    public int Count { get; private set; }
 24
 25    public void Clear()
 26    {
 43327        Count = 0;
 43328        _contactId0 = 0UL;
 43329        _contactId1 = 0UL;
 43330        _impulse0 = default;
 43331        _impulse1 = default;
 43332    }
 33
 34    public void Set(ulong contactId, Fixed64 normalImpulse, Fixed64 tangentImpulse)
 35    {
 103736        ContactWarmStartImpulse impulse = new(normalImpulse, tangentImpulse);
 216237        for (int i = 0; i < Count; i++)
 38        {
 76539            if (GetContactId(i) != contactId)
 40                continue;
 41
 72142            SetImpulseUnchecked(i, impulse);
 72143            return;
 44        }
 45
 31646        if (Count < ContactManifold2D.MaxContactCount)
 47        {
 30848            SetContactIdUnchecked(Count, contactId);
 30849            SetImpulseUnchecked(Count, impulse);
 30850            Count++;
 30851            return;
 52        }
 53
 854        SetContactIdUnchecked(ContactManifold2D.MaxContactCount - 1, contactId);
 855        SetImpulseUnchecked(ContactManifold2D.MaxContactCount - 1, impulse);
 856    }
 57
 58    public bool TryGet(ulong contactId, out ContactWarmStartImpulse impulse)
 59    {
 216060        for (int i = 0; i < Count; i++)
 61        {
 77562            if (GetContactId(i) != contactId)
 63                continue;
 64
 73665            impulse = GetImpulseUnchecked(i);
 73666            return true;
 67        }
 68
 30569        impulse = default;
 30570        return false;
 71    }
 72
 73    public bool Remove(ulong contactId)
 74    {
 2075        for (int i = 0; i < Count; i++)
 76        {
 677            if (GetContactId(i) != contactId)
 78                continue;
 79
 580            Count--;
 1481            for (int shift = i; shift < Count; shift++)
 82            {
 283                SetContactIdUnchecked(
 284                    shift,
 285                    GetContactId(shift + 1));
 286                SetImpulseUnchecked(
 287                    shift,
 288                    GetImpulseUnchecked(shift + 1));
 89            }
 90
 591            SetContactIdUnchecked(Count, 0UL);
 592            SetImpulseUnchecked(Count, default);
 593            return true;
 94        }
 95
 496        return false;
 97    }
 98
 99    internal ulong GetContactIdForReplayHash(int index)
 100    {
 3101        SwiftThrowHelper.ThrowIfArrayIndexInvalid(index, Count, nameof(index));
 3102        return GetContactId(index);
 103    }
 104
 105    internal ContactWarmStartImpulse GetImpulseForReplayHash(int index)
 106    {
 2107        SwiftThrowHelper.ThrowIfArrayIndexInvalid(index, Count, nameof(index));
 2108        return GetImpulseUnchecked(index);
 109    }
 110
 111    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 1551112    private ulong GetContactId(int index) => index == 0 ? _contactId0 : _contactId1;
 113
 114    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 740115    private ContactWarmStartImpulse GetImpulseUnchecked(int index) => index == 0 ? _impulse0 : _impulse1;
 116
 117    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 118    private void SetContactIdUnchecked(int index, ulong contactId)
 119    {
 323120        if (index == 0)
 121        {
 300122            _contactId0 = contactId;
 300123            return;
 124        }
 125
 23126        _contactId1 = contactId;
 23127    }
 128
 129    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 130    private void SetImpulseUnchecked(int index, ContactWarmStartImpulse impulse)
 131    {
 1044132        if (index == 0)
 133        {
 1006134            _impulse0 = impulse;
 1006135            return;
 136        }
 137
 38138        _impulse1 = impulse;
 38139    }
 140}