该项目的目的是同时测试和演示来自 Unity DOTS 技术堆栈的多个新包。
您最多选择25个主题 主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

127 行
4.2 KiB

using UnityEngine;
namespace NetworkCompression
{
public struct HuffmanOutputStream : IOutputStream
{
public HuffmanOutputStream(NetworkCompressionModel model, byte[] buffer, int bufferOffset, NetworkCompressionCapture capture)
{
m_Model = model;
m_Buffer = buffer;
m_BufferOffset = bufferOffset;
m_CurrentBitIndex = 0;
m_CurrentByteIndex = bufferOffset;
m_BitBuffer = 0;
m_Capture = capture;
}
public void Initialize(NetworkCompressionModel model, byte[] buffer, int bufferOffset, NetworkCompressionCapture capture)
{
this = new HuffmanOutputStream(model, buffer, bufferOffset, capture);
}
public void WriteRawBits(uint value, int numbits)
{
WriteRawBitsInternal(value, numbits);
FlushBits();
}
unsafe public void WriteRawBytes(byte* value, int count)
{
for (int i = 0; i < count; i++)
WriteRawBits(value[i], 8); //TODO: only flush every n bytes
}
public void WritePackedNibble(uint value, int context)
{
if (value >= 16)
Debug.Assert(false, "Nibble bigger than 15");
if (m_Capture != null)
m_Capture.AddNibble(context, value);
ushort encodeEntry = m_Model.encodeTable[context, value];
WriteRawBitsInternal((uint)(encodeEntry >> 8), encodeEntry & 0xFF);
FlushBits();
}
public void WritePackedUInt(uint value, int context)
{
if (m_Capture != null)
m_Capture.AddUInt(context, value);
//int bucket = NetworkCompressionUtils.CalculateBucket(value); // Manually inlined
int bucket = 0;
while (bucket + 1 < NetworkCompressionConstants.k_NumBuckets && value >= NetworkCompressionConstants.k_BucketOffsets[bucket + 1])
bucket++;
uint offset = NetworkCompressionConstants.k_BucketOffsets[bucket];
int bits = NetworkCompressionConstants.k_BucketSizes[bucket];
ushort encodeEntry = m_Model.encodeTable[context, bucket];
WriteRawBitsInternal((uint)(encodeEntry >> 8), encodeEntry & 0xFF);
WriteRawBitsInternal(value - offset, bits);
FlushBits();
}
public void WritePackedIntDelta(int value, int baseline, int context)
{
WritePackedUIntDelta((uint)value, (uint)baseline, context);
}
public void WritePackedUIntDelta(uint value, uint baseline, int context)
{
int diff = (int)(baseline - value);
uint interleaved = (uint)((diff >> 31) ^ (diff << 1)); // interleave negative values between positive values: 0, -1, 1, -2, 2
WritePackedUInt(interleaved, context);
}
public int GetBitPosition2()
{
return (m_CurrentByteIndex - m_BufferOffset) * 8 - m_CurrentBitIndex;
}
public NetworkCompressionModel GetModel()
{
return m_Model;
}
public int Flush()
{
while (m_CurrentBitIndex > 0)
{
m_Buffer[m_CurrentByteIndex++] = (byte)m_BitBuffer;
m_CurrentBitIndex -= 8;
m_BitBuffer >>= 8;
}
m_CurrentBitIndex = 0;
return m_CurrentByteIndex - m_BufferOffset;
}
void WriteRawBitsInternal(uint value, int numbits)
{
#if UNITY_EDITOR
Debug.Assert(numbits >= 0 && numbits <= 32);
Debug.Assert(value < (1UL << numbits));
#endif
m_BitBuffer |= ((ulong)value << m_CurrentBitIndex);
m_CurrentBitIndex += numbits;
}
void FlushBits()
{
while (m_CurrentBitIndex >= 8)
{
m_Buffer[m_CurrentByteIndex++] = (byte)m_BitBuffer;
m_CurrentBitIndex -= 8;
m_BitBuffer >>= 8;
}
}
NetworkCompressionCapture m_Capture;
NetworkCompressionModel m_Model;
byte[] m_Buffer;
int m_BufferOffset;
ulong m_BitBuffer;
int m_CurrentBitIndex;
int m_CurrentByteIndex;
}
}