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.
 
 
 
 
 
 

218 lines
4.9 KiB

using System;
using System.Collections.Generic;
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
{
public struct Mask
{
public readonly uint v;
public Mask(uint value) => v = value;
}
[SerializeField] uint bitSet;
public int bitCount => 32;
public void SetBit(int index, bool value)
{
if (index < 0 || index >= 32) return;
uint mask = (uint)1 << index;
if (!value)
bitSet &= ~mask;
else
bitSet |= mask;
}
public bool GetBit(int index)
{
if (index < 0 || index >= bitCount) return false;
return (bitSet & ((uint)1 << index)) != 0;
}
public bool MatchAll(Bitset32 other) => (bitSet & other.bitSet) == other.bitSet;
public bool MatchAll(Mask mask) => (bitSet & mask.v) == mask.v;
public bool MatchAny(Bitset32 other) => (bitSet & other.bitSet) != 0;
public bool MatchAny(Mask mask) => (bitSet & mask.v) != 0;
public void Reset() => bitSet = 0;
public static Mask GetMask(params int[] indices)
{
uint mask = 0;
foreach (var index in indices)
{
if (index < 0 || index >= 32) continue;
mask |= (uint)1 << index;
}
return new Mask(mask);
}
public static Mask GetMask(params Enum[] indices)
{
uint mask = 0;
foreach (var index in indices)
{
int i = Convert.ToInt32(index);
if (i < 0 || i >= 32) continue;
mask |= (uint)1 << i;
}
return new Mask(mask);
}
public static Mask GetMask(IReadOnlyList<Enum> indices)
{
uint mask = 0;
foreach (var index in indices)
{
int i = Convert.ToInt32(index);
if (i < 0 || i >= 32) continue;
mask |= (uint)1 << i;
}
return new Mask(mask);
}
public static implicit operator Bitset32(uint value) => new Bitset32 { bitSet = 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);
}
}