< Summary

Information
Class: Gravitas.Support.PhysicsLayer
Assembly: Gravitas
File(s): /home/runner/work/Gravitas/Gravitas/src/Gravitas/Support/PhysicsLayer.cs
Line coverage
100%
Covered lines: 31
Uncovered lines: 0
Coverable lines: 31
Total lines: 253
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%22100%
get_Index()100%11100%
get_MaskBit()100%11100%
Set(...)100%11100%
Equals(...)100%11100%
Equals(...)100%22100%
GetHashCode()100%11100%
ToString()100%11100%
op_Equality(...)100%11100%
op_Inequality(...)100%11100%
.cctor()100%11100%
LayerToName(...)100%22100%
NameToLayer(...)100%44100%
ValidateIndex(...)100%22100%

File(s)

/home/runner/work/Gravitas/Gravitas/src/Gravitas/Support/PhysicsLayer.cs

#LineLine coverage
 1//=======================================================================
 2// PhysicsLayer.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 MemoryPack;
 9using SwiftCollections;
 10using System;
 11using System.Runtime.CompilerServices;
 12using System.Text.Json.Serialization;
 13
 14namespace Gravitas.Support;
 15
 16/// <summary>
 17/// Identifies one physics layer by index.
 18/// </summary>
 19[Serializable]
 20[MemoryPackable]
 21public partial struct PhysicsLayer : IEquatable<PhysicsLayer>
 22{
 23    /// <summary>
 24    /// Minimum valid physics layer index.
 25    /// </summary>
 26    public const int MinIndex = 0;
 27
 28    /// <summary>
 29    /// Maximum valid physics layer index.
 30    /// </summary>
 31    public const int MaxIndex = 31;
 32
 33    [JsonInclude]
 34    [MemoryPackInclude]
 35    private int _index;
 36
 37    /// <summary>
 38    /// Creates a physics layer and optionally registers its display name.
 39    /// </summary>
 40    public PhysicsLayer(int index, string? layerName = null)
 41    {
 28742        ValidateIndex(index, nameof(index));
 28643        _index = index;
 28644        if (layerName != null)
 345            LayerNamesCache[index] = layerName;
 28646    }
 47
 48    /// <summary>
 49    /// Gets the layer index.
 50    /// </summary>
 51    [JsonIgnore]
 52    [MemoryPackIgnore]
 53    public readonly int Index
 54    {
 55        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 33922356        get => _index;
 57    }
 58
 59    /// <summary>
 60    /// Gets the single bit corresponding to this layer index.
 61    /// </summary>
 62    [JsonIgnore]
 63    [MemoryPackIgnore]
 64    public readonly int MaskBit
 65    {
 66        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 64122967        get => 1 << _index;
 68    }
 69
 70    /// <summary>
 71    /// Replaces the layer index after validating its range.
 72    /// </summary>
 73    public void Set(int index)
 74    {
 275        ValidateIndex(index, nameof(index));
 176        _index = index;
 177    }
 78
 79    /// <inheritdoc />
 217980    public readonly bool Equals(PhysicsLayer other) => _index == other._index;
 81
 82    /// <inheritdoc />
 1383    public override readonly bool Equals(object? obj) => obj is PhysicsLayer other && Equals(other);
 84
 85    /// <inheritdoc />
 186    public override readonly int GetHashCode() => _index;
 87
 88    /// <inheritdoc />
 189    public override readonly string ToString() => _index.ToString();
 90
 91    /// <summary>
 92    /// Determines whether two physics layers have the same index.
 93    /// </summary>
 206194    public static bool operator ==(PhysicsLayer left, PhysicsLayer right) => left.Equals(right);
 95
 96    /// <summary>
 97    /// Determines whether two physics layers have different indices.
 98    /// </summary>
 199    public static bool operator !=(PhysicsLayer left, PhysicsLayer right) => !left.Equals(right);
 100
 101    /// <summary>
 102    /// Maps registered layer indices to their names.
 103    /// </summary>
 1104    public static SwiftDictionary<int, string> LayerNamesCache = new();
 105
 106    /// <summary>
 107    /// Given a layer number, returns the registered layer name.
 108    /// </summary>
 109    public static string? LayerToName(int layer)
 110    {
 179074111        if (LayerNamesCache.TryGetValue(layer, out string name))
 4350112            return name;
 174724113        return null;
 114    }
 115
 116    /// <summary>
 117    /// Given a layer name, returns the registered layer index or -1 if the layer name is invalid.
 118    /// </summary>
 119    public static int NameToLayer(string layerName)
 120    {
 7121        foreach (var kvp in LayerNamesCache)
 122        {
 2123            if (kvp.Value == layerName)
 1124                return kvp.Key;
 125        }
 126
 1127        return -1;
 1128    }
 129
 130    private static void ValidateIndex(int index, string paramName)
 131    {
 289132        SwiftThrowHelper.ThrowIfArgumentOutOfRange(
 289133            index < MinIndex || index > MaxIndex,
 289134            index,
 289135            paramName,
 289136            "Physics layer index must be between 0 and 31 inclusive.");
 287137    }
 138}
 139
 140/// <summary>
 141/// Represents an include mask for physics layer queries and filters.
 142/// </summary>
 143[Serializable]
 144[MemoryPackable]
 145public partial struct PhysicsLayerMask : IEquatable<PhysicsLayerMask>
 146{
 147    [JsonInclude]
 148    [MemoryPackInclude]
 149    private int _bits;
 150
 151    /// <summary>
 152    /// Creates an include mask from its raw bit field.
 153    /// </summary>
 154    public PhysicsLayerMask(int bits)
 155    {
 156        _bits = bits;
 157    }
 158
 159    /// <summary>
 160    /// Gets the raw include-mask bits.
 161    /// </summary>
 162    [JsonIgnore]
 163    [MemoryPackIgnore]
 164    public readonly int Bits
 165    {
 166        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 167        get => _bits;
 168    }
 169
 170    /// <summary>
 171    /// Gets a mask that includes no physics layers.
 172    /// </summary>
 173    [JsonIgnore]
 174    [MemoryPackIgnore]
 175    public static PhysicsLayerMask None => new(0);
 176
 177    /// <summary>
 178    /// Gets a mask that includes every physics layer.
 179    /// </summary>
 180    [JsonIgnore]
 181    [MemoryPackIgnore]
 182    public static PhysicsLayerMask All => new(-1);
 183
 184    /// <summary>
 185    /// Determines whether this mask includes the specified layer.
 186    /// </summary>
 187    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 188    public readonly bool Includes(PhysicsLayer layer) => (_bits & layer.MaskBit) != 0;
 189
 190    /// <summary>
 191    /// Determines whether this mask includes the specified layer index.
 192    /// </summary>
 193    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 194    public readonly bool Includes(int layerIndex) => Includes(new PhysicsLayer(layerIndex));
 195
 196    /// <inheritdoc />
 197    public readonly bool Equals(PhysicsLayerMask other) => _bits == other._bits;
 198
 199    /// <inheritdoc />
 200    public override readonly bool Equals(object? obj) => obj is PhysicsLayerMask other && Equals(other);
 201
 202    /// <inheritdoc />
 203    public override readonly int GetHashCode() => _bits;
 204
 205    /// <inheritdoc />
 206    public override readonly string ToString() => _bits.ToString();
 207
 208    /// <summary>
 209    /// Creates an include mask containing one layer index.
 210    /// </summary>
 211    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 212    public static PhysicsLayerMask FromLayer(int layerIndex) => FromLayer(new PhysicsLayer(layerIndex));
 213
 214    /// <summary>
 215    /// Creates an include mask containing one layer.
 216    /// </summary>
 217    [MethodImpl(MethodImplOptions.AggressiveInlining)]
 218    public static PhysicsLayerMask FromLayer(PhysicsLayer layer) => new(layer.MaskBit);
 219
 220    /// <summary>
 221    /// Creates an include mask containing the specified layers.
 222    /// </summary>
 223    public static PhysicsLayerMask FromLayers(params PhysicsLayer[] layers)
 224    {
 225        int bits = 0;
 226        for (int i = 0; i < layers.Length; i++)
 227            bits |= layers[i].MaskBit;
 228
 229        return new PhysicsLayerMask(bits);
 230    }
 231
 232    /// <summary>
 233    /// Creates an include mask containing every layer except those specified.
 234    /// </summary>
 235    public static PhysicsLayerMask Excluding(params PhysicsLayer[] excludedLayers)
 236    {
 237        int bits = -1;
 238        for (int i = 0; i < excludedLayers.Length; i++)
 239            bits &= ~excludedLayers[i].MaskBit;
 240
 241        return new PhysicsLayerMask(bits);
 242    }
 243
 244    /// <summary>
 245    /// Determines whether two layer masks contain the same bits.
 246    /// </summary>
 247    public static bool operator ==(PhysicsLayerMask left, PhysicsLayerMask right) => left.Equals(right);
 248
 249    /// <summary>
 250    /// Determines whether two layer masks contain different bits.
 251    /// </summary>
 252    public static bool operator !=(PhysicsLayerMask left, PhysicsLayerMask right) => !left.Equals(right);
 253}