From 5299d6ddad7a8b11e34ad6387fefe35f9bfe7fc7 Mon Sep 17 00:00:00 2001 From: Evan Hemsley Date: Sun, 22 Dec 2019 11:54:37 -0800 Subject: [PATCH] remove bitarray allocations on query --- encompass-cs/ComponentUpdateManager.cs | 61 +++++++++++++++++--------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/encompass-cs/ComponentUpdateManager.cs b/encompass-cs/ComponentUpdateManager.cs index 3b270db..f8f38d5 100644 --- a/encompass-cs/ComponentUpdateManager.cs +++ b/encompass-cs/ComponentUpdateManager.cs @@ -14,6 +14,16 @@ namespace Encompass private Dictionary typeToIndex; public ComponentStore UpToDateComponentStore { get; private set; } + // bitarray references to avoid garbage collection + BitArray pendingMask; + BitArray readMask; + BitArray withMask; + BitArray withoutMask; + BitArray notWithMask; + BitArray solverArrayA; + BitArray solverArrayB; + BitArray solverArrayC; + public ComponentUpdateManager(Dictionary typeToIndex) { existingAndPendingComponentStore = new ComponentStore(typeToIndex); @@ -37,6 +47,15 @@ namespace Encompass existingComponentStore.FinishRegistering(); pendingComponentStore.FinishRegistering(); UpToDateComponentStore.FinishRegistering(); + + pendingMask = new BitArray(typeToIndex.Count); + readMask = new BitArray(typeToIndex.Count); + withMask = new BitArray(typeToIndex.Count); + withoutMask = new BitArray(typeToIndex.Count); + notWithMask = new BitArray(typeToIndex.Count); + solverArrayA = new BitArray(typeToIndex.Count); + solverArrayB = new BitArray(typeToIndex.Count); + solverArrayC = new BitArray(typeToIndex.Count); } internal void Clear() @@ -197,60 +216,60 @@ namespace Encompass internal IEnumerable QueryEntities(IEnumerable entities, HashSet readTypes, HashSet readPendingTypes, IEnumerable withTypes, IEnumerable withoutTypes) { - var pendingMask = new BitArray(typeToIndex.Count); + pendingMask.SetAll(false); foreach (var type in readPendingTypes) { pendingMask.Set(typeToIndex[type], true); } - var readMask = new BitArray(typeToIndex.Count); + readMask.SetAll(false); foreach (var type in readTypes) { readMask.Set(typeToIndex[type], true); } - var withMask = new BitArray(typeToIndex.Count); + withMask.SetAll(false); foreach (var type in withTypes) { withMask.Set(typeToIndex[type], true); } - var withoutMask = new BitArray(typeToIndex.Count); + withoutMask.SetAll(false); foreach (var type in withoutTypes) { withoutMask.Set(typeToIndex[type], true); } + notWithMask.SetAll(false); + notWithMask.Or(withMask).Not(); + foreach (var entity in entities) { var pendingEntity = pendingComponentStore.EntityBitArray(entity); var existingEntity = existingComponentStore.EntityBitArray(entity); - if (VerifyTypes(pendingEntity, existingEntity, readMask, pendingMask, withMask, withoutMask)) { yield return entity; } + if (VerifyTypes(pendingEntity, existingEntity, readMask, pendingMask, withMask, withoutMask, notWithMask)) { yield return entity; } } } - internal bool VerifyTypes(BitArray pendingEntity, BitArray existingEntity, BitArray readMask, BitArray pendingMask, BitArray withMask, BitArray withoutMask) + internal bool VerifyTypes(BitArray pendingEntity, BitArray existingEntity, BitArray readMask, BitArray pendingMask, BitArray withMask, BitArray withoutMask, BitArray notWithMask) { - var arrayA = new BitArray(typeToIndex.Count); - var arrayB = new BitArray(typeToIndex.Count); - var arrayC = new BitArray(typeToIndex.Count); + solverArrayA.SetAll(false); + solverArrayB.SetAll(false); + solverArrayC.SetAll(false); - var notWithMask = new BitArray(typeToIndex.Count); - notWithMask.Or(withMask).Not(); + solverArrayA.Or(pendingMask).And(withMask).And(pendingEntity); + solverArrayB.Or(readMask).And(withMask).And(existingEntity); + solverArrayA.Or(solverArrayB).Or(notWithMask); - arrayA.Or(pendingMask).And(withMask).And(pendingEntity); - arrayB.Or(readMask).And(withMask).And(existingEntity); - arrayA.Or(arrayB).Or(notWithMask); + solverArrayB.SetAll(false); + solverArrayB.Or(pendingMask).And(withoutMask).And(pendingEntity).Not(); + solverArrayC.Or(readMask).And(withoutMask).And(existingEntity).Not(); + solverArrayB.And(solverArrayC); - arrayB.SetAll(false); - arrayB.Or(pendingMask).And(withoutMask).And(pendingEntity).Not(); - arrayC.Or(readMask).And(withoutMask).And(existingEntity).Not(); - arrayB.And(arrayC); + solverArrayA.And(solverArrayB); - arrayA.And(arrayB); - - return !arrayA.Cast().Contains(false); + return !solverArrayA.Cast().Contains(false); } } }