Created
November 18, 2018 19:24
-
-
Save Valeour/6e65c1963603121be101227a1c7e1ece to your computer and use it in GitHub Desktop.
BoolPool: Using ints as bools instead of wasting 7 bits. Creates an internal int array to accomodate as many bools needed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// BoolPool by Chance Millar 18/11/18 | |
using UnityEngine; | |
/// Class is used to create a pool of bits to be used as bools. | |
/// Bools typically take up 1 byte (8bits), which is a collosal waste of space. | |
/// This class is overall slower than just an array of bools, however the memory footprint is significantly smaller. (655464 bools array is around 512kb, however using ints will reduce it to around 17kb) | |
/// This class converts integer types into a collection of boots. An int is 4 bytes / 32 bits, so that's 32 bools to be used. | |
/// If you need a smaller footprint, converting the ints into bytes as appropriate works too, but you'll need to do some casting depending on the C# version you're on. | |
[System.Serializable] | |
public class BoolPool | |
{ | |
/// Constants | |
private const int ALL_ON = int.MaxValue; // Maximum value of int, used to turn on all the bits. | |
private const int ALL_OFF = 0; // Convenience to turn off all the bits. | |
private const int INT_MASK = 32 - 1; // Mask used to get the modulo of index values. | |
private const int DIVISABLE = 5; // How many bits make up 31? Used to "divide" the remainder into a slot value. | |
/// Bools contained in ints. | |
[SerializeField] | |
private int[] _boolPool = null; | |
/// Retain the size of the pool incase someone needs it. | |
[SerializeField] | |
private int _size = 0; | |
/// Size of the pool. (Ceiled to the nearest 32) | |
public int size { | |
get { return _size; } | |
private set { _size = value; } | |
} | |
/// Overload the index operator for convenience. | |
public bool this[int index] { | |
get { return Get(index); } | |
set { Set( index, value ); } | |
} | |
/// Constructor to initialize the array. | |
public BoolPool( int count ) | |
{ | |
/// May as well not restrict when there are values to be used, so include any extra in the last slot. | |
/// Also plus 1 because 0 indexing! | |
this.size = ( count | INT_MASK ) + 1; | |
/// Cheaty division via power two madness. This is _technically_ count / 32 plus 1. | |
count = ( count >> DIVISABLE ) + 1; | |
_boolPool = new int[count]; | |
} | |
/// Set a bit and specify a bool. | |
public void Set( int index, bool on ) | |
{ | |
if( on ) | |
{ | |
EnableBit( index ); | |
} | |
else | |
{ | |
DisableBit( index ); | |
} | |
} | |
/// Get a specific bool. | |
public bool Get( int index ) | |
{ | |
/// Fake divide the index to get the slot we need. | |
int slot = index >> DIVISABLE; | |
/// Get the remainder value within the 32 bits | |
int modo = ( index & ( INT_MASK ) ); | |
/// Shift 1 along because that's the bit we want. Also invert it because we're only after 1 bit. | |
int bit = ~( 1 << modo ); | |
/// Mask the bits and if it's greater than 0, the specified bit is enabled. | |
return (_boolPool[slot] & bit) > 0; | |
} | |
/// Set all bits based on bool. | |
public void SetAll( bool on ) | |
{ | |
/// Cache the one we want. | |
int value = ( on ) ? ALL_ON : ALL_OFF; | |
for( int i = 0; i < _boolPool.Length; ++i ) | |
{ | |
_boolPool[i] = value; | |
} | |
} | |
/// Set all bits to 0. | |
public void Clear() | |
{ | |
SetAll( false ); | |
} | |
/// Enable a specific bit. | |
public void EnableBit( int index ) | |
{ | |
int slot = index >> DIVISABLE; | |
int modo = ( index & ( INT_MASK ) ); | |
int bit = ( 1 << modo ); | |
_boolPool[slot] |= bit; | |
} | |
/// Disable a specific bit. | |
public void DisableBit( int index ) | |
{ | |
int slot = index >> DIVISABLE; | |
int modo = ( index & ( INT_MASK ) ); | |
int bit = ~( 1 << modo ); | |
_boolPool[slot] &= bit; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Create a pool, specify how many bool elements wanted. (Ceiled to the nearest 32) | |
BoolPool boolPool = new BoolPool( 128 ); | |
// Can use array indexing to set or get bit values. | |
boolPool[4] = true; | |
// Clearing will reset all bits back to 0. | |
boolPool.Clear(); | |
// Alternatively, you can manually set all the bools. | |
boolPool.SetAll( true ); | |
// You don't have to use indexing either. | |
boolPool.EnableBit( 84 ); | |
boolPool.DisableBit( 37 ); | |
boolPool.Set( 50, true ); | |
// Get the total size of the pool (rounded) | |
int s = boolPool.size; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment