1
0
mirror of https://github.com/lidgren/lidgren-network-gen3.git synced 2026-05-19 00:26:30 +09:00

NetBitVector enhanced

This commit is contained in:
lidgren
2010-09-24 18:26:01 +00:00
parent a579ff8f4b
commit c485a2d02c
2 changed files with 70 additions and 13 deletions

View File

@@ -18,35 +18,57 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
using System; using System;
using System.Text;
namespace Lidgren.Network namespace Lidgren.Network
{ {
public sealed class NetBitVector public sealed class NetBitVector
{ {
private readonly int m_capacity; private readonly int m_capacity;
private readonly uint[] m_data; private readonly int[] m_data;
public int Capacity { get { return m_capacity; } } public int Capacity { get { return m_capacity; } }
public NetBitVector(int bitsCapacity) public NetBitVector(int bitsCapacity)
{ {
m_capacity = bitsCapacity; m_capacity = bitsCapacity;
m_data = new uint[(bitsCapacity + 31) / 32]; m_data = new int[(bitsCapacity + 31) / 32];
} }
public bool IsEmpty() public bool IsEmpty()
{ {
foreach (uint v in m_data) foreach (int v in m_data)
if (v != 0) if (v != 0)
return false; return false;
return true; return true;
} }
/// <summary>
/// Shift all bits one step down, cycling the first bit to the top
/// </summary>
public void RotateDown()
{
int lenMinusOne = m_data.Length - 1;
int firstBit = m_data[0] & 1;
for (int i = 0; i < lenMinusOne; i++)
m_data[i] = ((m_data[i] >> 1) & ~(1 << 31)) | m_data[i + 1] << 31;
int lastIndex = m_capacity - 1 - (32 * lenMinusOne);
// special handling of last int
int cur = m_data[lenMinusOne];
cur = cur >> 1;
cur |= firstBit << lastIndex;
m_data[lenMinusOne] = cur;
}
public int GetFirstSetIndex() public int GetFirstSetIndex()
{ {
int idx = 0; int idx = 0;
uint data = m_data[0]; int data = m_data[0];
while (data == 0) while (data == 0)
{ {
idx++; idx++;
@@ -62,24 +84,20 @@ namespace Lidgren.Network
public bool Get(int bitIndex) public bool Get(int bitIndex)
{ {
int idx = bitIndex / 32; return (m_data[bitIndex / 32] & (1 << (bitIndex % 32))) != 0;
uint data = m_data[idx];
int bitNr = bitIndex - (idx * 32);
return (data & (1 << bitNr)) != 0;
} }
public void Set(int bitIndex, bool value) public void Set(int bitIndex, bool value)
{ {
int idx = bitIndex / 32; int idx = bitIndex / 32;
int bitNr = bitIndex - (idx * 32);
if (value) if (value)
m_data[idx] |= (uint)(1 << bitNr); m_data[idx] |= (1 << (bitIndex % 32));
else else
m_data[idx] &= (uint)(~(1 << bitNr)); m_data[idx] &= (~(1 << (bitIndex % 32)));
} }
[System.Runtime.CompilerServices.IndexerName("Bit")] [System.Runtime.CompilerServices.IndexerName("Bit")]
public bool this [int index] public bool this[int index]
{ {
get { return Get(index); } get { return Get(index); }
set { Set(index, value); } set { Set(index, value); }
@@ -89,5 +107,15 @@ namespace Lidgren.Network
{ {
Array.Clear(m_data, 0, m_data.Length); Array.Clear(m_data, 0, m_data.Length);
} }
public override string ToString()
{
StringBuilder bdr = new StringBuilder(m_capacity + 2);
bdr.Append('[');
for (int i = 0; i < m_capacity; i++)
bdr.Append(Get(m_capacity - i - 1) ? '1' : '0');
bdr.Append(']');
return bdr.ToString();
}
} }
} }

View File

@@ -33,6 +33,35 @@ namespace UnitTests
throw new NetException("bit vector fail 4"); throw new NetException("bit vector fail 4");
} }
v = new NetBitVector(9);
v.Clear();
v.Set(3, true);
if (v.ToString() != "[000001000]")
throw new NetException("NetBitVector.RotateDown failed");
v.RotateDown();
if (v.Get(3) == true || v.Get(2) == false || v.Get(4) == true)
throw new NetException("NetBitVector.RotateDown failed 2");
if (v.ToString() != "[000000100]")
throw new NetException("NetBitVector.RotateDown failed 3");
v.Set(0, true);
v.RotateDown();
if (v.ToString() != "[100000010]")
throw new NetException("NetBitVector.RotateDown failed 4");
v = new NetBitVector(38);
v.Set(0, true);
v.Set(1, true);
v.Set(31, true);
if (v.ToString() != "[00000010000000000000000000000000000011]")
throw new NetException("NetBitVector.RotateDown failed 5");
v.RotateDown();
if (v.ToString() != "[10000001000000000000000000000000000001]")
throw new NetException("NetBitVector.RotateDown failed 5");
Console.WriteLine("NetBitVector tests OK"); Console.WriteLine("NetBitVector tests OK");
} }
} }