You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
3.8 KiB
177 lines
3.8 KiB
using System;
|
|
using UnityEngine;
|
|
|
|
[Serializable]
|
|
public struct BitSet8
|
|
{
|
|
[SerializeField] byte m_set;
|
|
|
|
public int bitCount => 8;
|
|
|
|
public void SetBit(int index, bool value)
|
|
{
|
|
if (index < 0 || index >= 8) return;
|
|
|
|
byte mask = (byte)(1 << index);
|
|
|
|
if (!value)
|
|
m_set &= (byte)~mask;
|
|
else
|
|
m_set |= mask;
|
|
}
|
|
|
|
public bool GetBit(int index)
|
|
{
|
|
if (index < 0 || index >= 8) return false;
|
|
return (m_set & (byte)(1 << index)) != 0;
|
|
}
|
|
|
|
public bool GetBitsAll(int count)
|
|
{
|
|
count = Math.Min(count, bitCount);
|
|
byte mask = (byte)(byte.MaxValue >> (bitCount - count));
|
|
return (m_set & mask) == mask;
|
|
}
|
|
|
|
public bool GetBitsAny(int count)
|
|
{
|
|
count = Math.Min(count, bitCount);
|
|
byte mask = (byte)(byte.MaxValue >> (bitCount - count));
|
|
return (m_set & mask) != 0;
|
|
}
|
|
|
|
public void Reset() => m_set = 0;
|
|
|
|
static public implicit operator BitSet8(byte value) => new BitSet8 { m_set = value };
|
|
}
|
|
|
|
[Serializable]
|
|
public class BitSet16
|
|
{
|
|
[SerializeField] ushort m_set;
|
|
|
|
public int bitCount => 16;
|
|
|
|
public void setBit(int index, bool value)
|
|
{
|
|
if (index < 0 || index >= 16) return;
|
|
|
|
ushort mask = (ushort)(1 << index);
|
|
|
|
if (!value)
|
|
m_set &= (ushort)~mask;
|
|
else
|
|
m_set |= mask;
|
|
}
|
|
|
|
public bool getBit(int index)
|
|
{
|
|
if (index < 0 || index >= 16) return false;
|
|
return (m_set & (ushort)(1 << index)) != 0;
|
|
}
|
|
|
|
public void reset() => m_set = 0;
|
|
|
|
static public implicit operator BitSet16(ushort value) => new BitSet16 { m_set = value };
|
|
}
|
|
|
|
[Serializable]
|
|
public class BitSet32
|
|
{
|
|
[SerializeField] uint m_set;
|
|
|
|
public int bitCount => 32;
|
|
|
|
public void setBit(int index, bool value)
|
|
{
|
|
if (index < 0 || index >= 32) return;
|
|
|
|
uint mask = (uint)1 << index;
|
|
|
|
if (!value)
|
|
m_set &= ~mask;
|
|
else
|
|
m_set |= mask;
|
|
}
|
|
|
|
public bool getBit(int index)
|
|
{
|
|
if (index < 0 || index >= bitCount) return false;
|
|
return (m_set & ((uint)1 << index)) != 0;
|
|
}
|
|
|
|
public bool getBitsAny(int count)
|
|
{
|
|
count = Math.Min(count, bitCount);
|
|
uint mask = uint.MaxValue >> (bitCount - count);
|
|
return (m_set & mask) != 0;
|
|
}
|
|
|
|
public void reset() => m_set = 0;
|
|
|
|
static public implicit operator BitSet32(uint value) => new BitSet32 { m_set = value };
|
|
}
|
|
|
|
[Serializable]
|
|
public class BitSetArray
|
|
{
|
|
[SerializeField] byte[] m_set = new byte[] { 0 };
|
|
|
|
public int bitCount => m_set.Length * 8;
|
|
|
|
public void setBit(int index, bool value)
|
|
{
|
|
int arrayIndex = index / 8;
|
|
int bitIndex = index % 8;
|
|
|
|
if (arrayIndex >= m_set.Length)
|
|
Array.Resize(ref m_set, arrayIndex + 1);
|
|
|
|
byte mask = (byte)(1 << bitIndex);
|
|
|
|
if (!value)
|
|
m_set[arrayIndex] &= (byte)~mask;
|
|
else
|
|
m_set[arrayIndex] |= mask;
|
|
}
|
|
|
|
public bool getBit(int index)
|
|
{
|
|
if (index >= bitCount) return false;
|
|
|
|
int arrayIndex = index / 8;
|
|
int bitIndex = index % 8;
|
|
|
|
return (m_set[arrayIndex] & (byte)(1 << bitIndex)) != 0;
|
|
}
|
|
|
|
public bool getBitsAny(int count)
|
|
{
|
|
count = Math.Min(count, bitCount);
|
|
|
|
int targetByteIndex = 0;
|
|
while (count > 0)
|
|
{
|
|
if ((m_set[targetByteIndex] & byte.MaxValue >> (8 - Math.Min(count, 8))) != 0)
|
|
return true;
|
|
|
|
count -= 8;
|
|
++targetByteIndex;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public void reset() => m_set = new byte[] { new byte() };
|
|
|
|
public void shrinkToFit()
|
|
{
|
|
int i;
|
|
for (i = m_set.Length - 1; i >= 0; i--)
|
|
{
|
|
if (m_set[i] != 0)
|
|
break;
|
|
}
|
|
|
|
Array.Resize(ref m_set, i + 1);
|
|
}
|
|
}
|