diff --git a/encompass-cs/Collections/BitSet.cs b/encompass-cs/Collections/BitSet.cs new file mode 100644 index 0000000..abe9960 --- /dev/null +++ b/encompass-cs/Collections/BitSet.cs @@ -0,0 +1,182 @@ +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +namespace Encompass.Collections +{ + public static class BitSetBuilder + { + public static BitSet Zeroes() + { + return new BitSet(VectorBuilder.Zeroes(), VectorBuilder.Zeroes(), VectorBuilder.Zeroes(), VectorBuilder.Zeroes()); + } + + public static BitSet Ones() + { + return new BitSet(VectorBuilder.Ones(), VectorBuilder.Ones(), VectorBuilder.Ones(), VectorBuilder.Ones()); + } + } + + public static class VectorBuilder + { + static readonly uint[] zeroes = new uint[Vector.Count]; // max size of a Vector is 8 uints + static readonly uint[] ones = Enumerable.Repeat(uint.MaxValue, Vector.Count).ToArray(); + static uint[] builderInts = new uint[Vector.Count]; + + private static void ResetBuilder() + { + for (var i = 0; i < Vector.Count; i++) + { + builderInts[i] = 0; + } + } + + public static Vector Zeroes() + { + return new Vector(zeroes); + } + + public static Vector Ones() + { + return new Vector(ones); + } + + public static Vector Build(int index) + { + if (index > Vector.Count * 32) { throw new System.ArgumentOutOfRangeException(nameof(index)); } + ResetBuilder(); + builderInts[index / 32] |= (uint)(1 << (index % 32)); + return new Vector(builderInts); + } + } + + public struct BitSet + { + public static int VectorLength { get { return Vector.Count * 32; } } + + public Vector A { get; } + public Vector B { get; } + public Vector C { get; } + public Vector D { get; } + + internal BitSet(Vector a, Vector b, Vector c, Vector d) + { + A = a; + B = b; + C = c; + D = d; + } + + public BitSet And(BitSet other) + { + return new BitSet(A & other.A, B & other.B, C & other.C, D & other.D); + } + + public BitSet Or(BitSet other) + { + return new BitSet(A | other.A, B | other.B, C | other.C, D | other.D); + } + + public BitSet Not() + { + return new BitSet(~A, ~B, ~C, ~D); + } + + public BitSet Set(int index) + { + if (index < VectorLength) + { + return new BitSet(A | VectorBuilder.Build(index % VectorLength), B, C, D); + } + else if (index < VectorLength * 2) + { + return new BitSet(A, B | VectorBuilder.Build(index % VectorLength), C, D); + } + else if (index < VectorLength * 3) + { + return new BitSet(A, B, C | VectorBuilder.Build(index % VectorLength), D); + } + else if (index < VectorLength * 4) + { + return new BitSet(A, B, C, D | VectorBuilder.Build(index % VectorLength)); + } + else + { + throw new System.ArgumentOutOfRangeException(nameof(index)); + } + } + + public BitSet UnSet(int index) + { + if (index < VectorLength) + { + return new BitSet(A & ~VectorBuilder.Build(index % VectorLength), B, C, D); + } + else if (index < VectorLength * 2) + { + return new BitSet(A, B & ~VectorBuilder.Build(index % VectorLength), C, D); + } + else if (index < VectorLength * 3) + { + return new BitSet(A, B, C & ~VectorBuilder.Build(index % VectorLength), D); + } + else if (index < VectorLength * 4) + { + return new BitSet(A, B, C, D & ~VectorBuilder.Build(index % VectorLength)); + } + else + { + throw new System.ArgumentOutOfRangeException(nameof(index)); + } + } + + public bool Get(int index) + { + var vectorIndex = index % VectorLength; + if (index < VectorLength) + { + return (A[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; + } + else if (index < VectorLength * 2) + { + return (B[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; + } + else if (index < VectorLength * 3) + { + return (C[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; + } + else if (index < VectorLength * 4) + { + return (D[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; + } + else + { + throw new System.ArgumentOutOfRangeException(nameof(index)); + } + } + + public bool AllTrue() + { + for (var i = 0; i < Vector.Count; i++) + { + if (A[i] != uint.MaxValue) { return false; } + if (B[i] != uint.MaxValue) { return false; } + if (C[i] != uint.MaxValue) { return false; } + if (D[i] != uint.MaxValue) { return false; } + } + return true; + } + + public bool AllFalse() + { + for (var i = 0; i < Vector.Count; i++) + { + if (A[i] != 0) { return false; } + if (B[i] != 0) { return false; } + if (C[i] != 0) { return false; } + if (D[i] != 0) { return false; } + } + return true; + } + } +} diff --git a/encompass-cs/Collections/BitSet512.cs b/encompass-cs/Collections/BitSet512.cs deleted file mode 100644 index beef1e8..0000000 --- a/encompass-cs/Collections/BitSet512.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System.Numerics; - -namespace Encompass.Collections -{ - public static class BitSet512Builder - { - public static BitSet512 Zeroes() - { - return new BitSet512(Vector128Builder.Zeroes(), Vector128Builder.Zeroes(), Vector128Builder.Zeroes(), Vector128Builder.Zeroes()); - } - - public static BitSet512 Ones() - { - return new BitSet512(Vector128Builder.Ones(), Vector128Builder.Ones(), Vector128Builder.Ones(), Vector128Builder.Ones()); - } - } - - public static class Vector128Builder - { - static readonly uint[] zeroes = new uint[4]; // max size of a Vector is 8 uints - static readonly uint[] ones = new uint[4] { uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue }; - static uint[] builderInts = new uint[4]; - - private static void ResetBuilder() - { - for (var i = 0; i < 4; i++) - { - builderInts[i] = 0; - } - } - - public static Vector Zeroes() - { - return new Vector(zeroes); - } - - public static Vector Ones() - { - return new Vector(ones); - } - - public static Vector Build(int index) - { - if (index > 127) { throw new System.ArgumentOutOfRangeException(nameof(index)); } - ResetBuilder(); - builderInts[index / 32] |= (uint)(1 << (index % 32)); - return new Vector(builderInts); - } - } - - public struct BitSet512 - { - public Vector A { get; } - public Vector B { get; } - public Vector C { get; } - public Vector D { get; } - - internal BitSet512(Vector a, Vector b, Vector c, Vector d) - { - A = a; - B = b; - C = c; - D = d; - } - - public BitSet512 And(BitSet512 other) - { - return new BitSet512(A & other.A, B & other.B, C & other.C, D & other.D); - } - - public BitSet512 Or(BitSet512 other) - { - return new BitSet512(A | other.A, B | other.B, C | other.C, D | other.D); - } - - public BitSet512 Not() - { - return new BitSet512(~A, ~B, ~C, ~D); - } - - public BitSet512 Set(int index) - { - if (index < 128) - { - return new BitSet512(A | Vector128Builder.Build(index % 128), B, C, D); - } - else if (index < 256) - { - return new BitSet512(A, B | Vector128Builder.Build(index % 128), C, D); - } - else if (index < 384) - { - return new BitSet512(A, B, C | Vector128Builder.Build(index % 128), D); - } - else if (index < 512) - { - return new BitSet512(A, B, C, D | Vector128Builder.Build(index % 128)); - } - else - { - throw new System.ArgumentOutOfRangeException(nameof(index)); - } - } - - public BitSet512 UnSet(int index) - { - if (index < 128) - { - return new BitSet512(A & ~Vector128Builder.Build(index % 128), B, C, D); - } - else if (index < 256) - { - return new BitSet512(A, B & ~Vector128Builder.Build(index % 128), C, D); - } - else if (index < 384) - { - return new BitSet512(A, B, C & ~Vector128Builder.Build(index % 128), D); - } - else if (index < 512) - { - return new BitSet512(A, B, C, D & ~Vector128Builder.Build(index % 128)); - } - else - { - throw new System.ArgumentOutOfRangeException(nameof(index)); - } - } - - public bool Get(int index) - { - var vectorIndex = index % 128; - if (index < 128) - { - return (A[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; - } - else if (index < 256) - { - return (B[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; - } - else if (index < 384) - { - return (C[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; - } - else if (index < 512) - { - return (D[vectorIndex / 32] & (uint)(1 << vectorIndex % 32)) != 0; - } - else - { - throw new System.ArgumentOutOfRangeException(nameof(index)); - } - } - - public bool AllTrue() - { - for (var i = 0; i < 4; i++) - { - if (A[i] != uint.MaxValue) { return false; } - if (B[i] != uint.MaxValue) { return false; } - if (C[i] != uint.MaxValue) { return false; } - if (D[i] != uint.MaxValue) { return false; } - } - return true; - } - - public bool AllFalse() - { - for (var i = 0; i < 4; i++) - { - if (A[i] != 0) { return false; } - if (B[i] != 0) { return false; } - if (C[i] != 0) { return false; } - if (D[i] != 0) { return false; } - } - return true; - } - } -} diff --git a/encompass-cs/Collections/ComponentBitSet.cs b/encompass-cs/Collections/ComponentBitSet.cs index 5dad445..d1ab784 100644 --- a/encompass-cs/Collections/ComponentBitSet.cs +++ b/encompass-cs/Collections/ComponentBitSet.cs @@ -7,7 +7,7 @@ namespace Encompass { internal class ComponentBitSet { - Dictionary entities = new Dictionary(); + Dictionary entities = new Dictionary(); Dictionary TypeToIndex { get; } public ComponentBitSet(Dictionary typeToIndex) @@ -27,7 +27,7 @@ namespace Encompass public void AddEntity(Entity entity) { - entities.Add(entity, BitSet512Builder.Zeroes()); + entities.Add(entity, BitSetBuilder.Zeroes()); } public void Set(Entity entity) where TComponent : struct, IComponent @@ -52,9 +52,9 @@ namespace Encompass } } - public BitSet512 EntityBitArray(Entity entity) + public BitSet EntityBitArray(Entity entity) { - return entities.ContainsKey(entity) ? entities[entity] : BitSet512Builder.Zeroes(); + return entities.ContainsKey(entity) ? entities[entity] : BitSetBuilder.Zeroes(); } } } diff --git a/encompass-cs/Collections/ComponentStore.cs b/encompass-cs/Collections/ComponentStore.cs index 90280c5..6fe1af3 100644 --- a/encompass-cs/Collections/ComponentStore.cs +++ b/encompass-cs/Collections/ComponentStore.cs @@ -52,7 +52,7 @@ namespace Encompass return Stores.ContainsKey(type) && Stores[type].Has(entity); } - public BitSet512 EntityBitArray(Entity entity) + public BitSet EntityBitArray(Entity entity) { return ComponentBitSet.EntityBitArray(entity); } diff --git a/encompass-cs/Engine.cs b/encompass-cs/Engine.cs index b61752d..acd0e66 100644 --- a/encompass-cs/Engine.cs +++ b/encompass-cs/Engine.cs @@ -642,25 +642,25 @@ namespace Encompass /// internal void BuildEntityQuery() { - var withMask = BitSet512Builder.Zeroes(); + var withMask = BitSetBuilder.Zeroes(); foreach (var type in queryWithTypes) { withMask = withMask.Set(componentUpdateManager.TypeToIndex[type]); } - var withoutMask = BitSet512Builder.Zeroes(); + var withoutMask = BitSetBuilder.Zeroes(); foreach (var type in queryWithoutTypes) { withoutMask = withoutMask.Set(componentUpdateManager.TypeToIndex[type]); } - var pendingMask = BitSet512Builder.Zeroes(); + var pendingMask = BitSetBuilder.Zeroes(); foreach (var type in readPendingTypes) { pendingMask = pendingMask.Set(componentUpdateManager.TypeToIndex[type]); } - var existingMask = BitSet512Builder.Zeroes(); + var existingMask = BitSetBuilder.Zeroes(); foreach (var type in readTypes) { existingMask = existingMask.Set(componentUpdateManager.TypeToIndex[type]); diff --git a/encompass-cs/EntitySetQuery.cs b/encompass-cs/EntitySetQuery.cs index 219c712..b564212 100644 --- a/encompass-cs/EntitySetQuery.cs +++ b/encompass-cs/EntitySetQuery.cs @@ -6,13 +6,13 @@ namespace Encompass { internal struct EntitySetQuery { - private BitSet512 WithPendingMask { get; } - private BitSet512 WithExistingMask { get; } - private BitSet512 WithoutPendingMask { get; } - private BitSet512 WithoutExistingMask { get; } - private BitSet512 NotWithMask { get; } + private BitSet WithPendingMask { get; } + private BitSet WithExistingMask { get; } + private BitSet WithoutPendingMask { get; } + private BitSet WithoutExistingMask { get; } + private BitSet NotWithMask { get; } - internal EntitySetQuery(BitSet512 withPendingMask, BitSet512 withExistingMask, BitSet512 withoutPendingMask, BitSet512 withoutExistingMask, BitSet512 notWithMask) + internal EntitySetQuery(BitSet withPendingMask, BitSet withExistingMask, BitSet withoutPendingMask, BitSet withoutExistingMask, BitSet notWithMask) { WithPendingMask = withPendingMask; WithExistingMask = withExistingMask; diff --git a/test/BitSet1024Test.cs b/test/BitSetTest.cs similarity index 65% rename from test/BitSet1024Test.cs rename to test/BitSetTest.cs index 9eeac8a..dfcfb6d 100644 --- a/test/BitSet1024Test.cs +++ b/test/BitSetTest.cs @@ -4,42 +4,42 @@ using NUnit.Framework; namespace Tests { - public class BitSet512Test + public class BitSetTest { [Test] public void Zeroes() { - var bitSet = BitSet512Builder.Zeroes(); + var bitSet = BitSetBuilder.Zeroes(); bitSet.AllFalse().Should().BeTrue(); } [Test] public void Ones() { - var bitSet = BitSet512Builder.Ones(); + var bitSet = BitSetBuilder.Ones(); bitSet.AllTrue().Should().BeTrue(); } [Test] public void Set() { - var bitSet = BitSet512Builder.Zeroes().Set(5); + var bitSet = BitSetBuilder.Zeroes().Set(5); bitSet.AllFalse().Should().BeFalse(); - bitSet = BitSet512Builder.Zeroes().Set(132); + bitSet = BitSetBuilder.Zeroes().Set(132); bitSet.AllFalse().Should().BeFalse(); - bitSet = BitSet512Builder.Zeroes().Set(268); + bitSet = BitSetBuilder.Zeroes().Set(268); bitSet.AllFalse().Should().BeFalse(); - bitSet = BitSet512Builder.Zeroes().Set(450); + bitSet = BitSetBuilder.Zeroes().Set(450); bitSet.AllFalse().Should().BeFalse(); } [Test] public void UnSet() { - var bitSet = BitSet512Builder.Ones().UnSet(285); + var bitSet = BitSetBuilder.Ones().UnSet(285); bitSet.Get(285).Should().BeFalse(); bitSet.Set(285).AllTrue().Should().BeTrue(); } @@ -47,7 +47,7 @@ namespace Tests [Test] public void Get() { - var bitSet = BitSet512Builder.Zeroes().Set(359); + var bitSet = BitSetBuilder.Zeroes().Set(359); bitSet.Get(359).Should().BeTrue(); bitSet.UnSet(359).AllFalse().Should().BeTrue(); } @@ -55,7 +55,7 @@ namespace Tests [Test] public void Not() { - var bitSet = BitSet512Builder.Ones().Not(); + var bitSet = BitSetBuilder.Ones().Not(); bitSet.AllFalse().Should().BeTrue(); } }