You've already forked lidgren-network-gen3
mirror of
https://github.com/lidgren/lidgren-network-gen3.git
synced 2026-05-18 16:16:35 +09:00
NetBitVector enhanced
This commit is contained in:
@@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,36 @@ namespace UnitTests
|
|||||||
if (f != i)
|
if (f != i)
|
||||||
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user