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

210 行
6.9 KiB

using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
using Unity.Sample.Core;
using UnityEngine;
unsafe public struct NetworkReader
{
public NetworkReader(uint* buffer, NetworkSchema schema)
{
m_Input = buffer;
m_Position = 0;
m_Schema = schema;
m_CurrentField = null;
m_NextFieldIndex = 0;
}
public bool ReadBoolean()
{
ValidateSchema(NetworkSchema.FieldType.Bool, 1, false);
return m_Input[m_Position++] == 1;
}
public byte ReadByte()
{
ValidateSchema(NetworkSchema.FieldType.UInt, 8, true);
return (byte)m_Input[m_Position++];
}
public short ReadInt16()
{
ValidateSchema(NetworkSchema.FieldType.Int, 16, true);
return (short)m_Input[m_Position++];
}
public ushort ReadUInt16()
{
ValidateSchema(NetworkSchema.FieldType.UInt, 16, true);
return (ushort)m_Input[m_Position++];
}
public int ReadInt32()
{
ValidateSchema(NetworkSchema.FieldType.Int, 32, true);
return (int)m_Input[m_Position++];
}
public uint ReadUInt32()
{
ValidateSchema(NetworkSchema.FieldType.UInt, 32, true);
return m_Input[m_Position++];
}
public float ReadFloat()
{
ValidateSchema(NetworkSchema.FieldType.Float, 32, false);
return NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
}
public float ReadFloatQ()
{
GameDebug.Assert(m_Schema != null, "Schema required for reading quantizied values");
ValidateSchema(NetworkSchema.FieldType.Float, 32, true);
return (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
}
public string ReadString(int maxLength = 64)
{
ValidateSchema(NetworkSchema.FieldType.String, 0, false, maxLength);
uint count = m_Input[m_Position++];
GameDebug.Assert(count <= maxLength);
byte* data = (byte*)(m_Input + m_Position);
m_Position += maxLength / 4;
if (count == 0)
return "";
fixed(char* dest = s_CharBuffer)
{
var numChars = NetworkConfig.encoding.GetChars(data, (int)count, dest, s_CharBuffer.Length);
return new string(s_CharBuffer, 0, numChars);
}
}
public void ReadNativeString(ref NativeString64 nativeString, int maxLength = 64)
{
ValidateSchema(NetworkSchema.FieldType.String, 0, false, maxLength);
uint count = m_Input[m_Position++];
GameDebug.Assert(count <= maxLength);
byte* data = (byte*)(m_Input + m_Position);
m_Position += maxLength / 4;
nativeString.LengthInBytes = 0;
if (count == 0)
return;
fixed (char* dest = s_CharBuffer)
{
var numChars = NetworkConfig.encoding.GetChars(data, (int)count, dest, s_CharBuffer.Length);
nativeString.CopyFrom(dest, (ushort)numChars);
}
}
public Vector2 ReadVector2()
{
ValidateSchema(NetworkSchema.FieldType.Vector2, 32, false);
Vector2 result;
result.x = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
result.y = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
return result;
}
public Vector2 ReadVector2Q()
{
GameDebug.Assert(m_Schema != null, "Schema required for reading quantizied values");
ValidateSchema(NetworkSchema.FieldType.Vector2, 32, true);
Vector2 result;
result.x = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
result.y = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
return result;
}
public Vector3 ReadVector3()
{
ValidateSchema(NetworkSchema.FieldType.Vector3, 32, false);
Vector3 result;
result.x = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
result.y = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
result.z = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
return result;
}
public Vector3 ReadVector3Q()
{
GameDebug.Assert(m_Schema != null, "Schema required for reading quantizied values");
ValidateSchema(NetworkSchema.FieldType.Vector3, 32, true);
Vector3 result;
result.x = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
result.y = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
result.z = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
return result;
}
public Quaternion ReadQuaternion()
{
ValidateSchema(NetworkSchema.FieldType.Quaternion, 32, false);
Quaternion result;
result.x = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
result.y = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
result.z = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
result.w = NetworkUtils.UInt32ToFloat(m_Input[m_Position++]);
return result;
}
public Quaternion ReadQuaternionQ()
{
GameDebug.Assert(m_Schema != null, "Schema required for reading quantizied values");
ValidateSchema(NetworkSchema.FieldType.Quaternion, 32, true);
Quaternion result;
result.x = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
result.y = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
result.z = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
result.w = (int)m_Input[m_Position++] * NetworkConfig.decoderPrecisionScales[m_CurrentField.precision];
return result;
}
unsafe public int ReadBytes(byte[] value, int dstIndex, int maxLength)
{
ValidateSchema(NetworkSchema.FieldType.ByteArray, 0, false, maxLength);
uint count = m_Input[m_Position++];
byte* src = (byte*)(m_Input + m_Position);
for (int i = 0; i < count; ++i)
value[i] = *src++;
m_Position += maxLength / 4;
return (int)count;
}
void ValidateSchema(NetworkSchema.FieldType type, int bits, bool delta, int arraySize = 0)
{
if (m_Schema == null)
return;
m_CurrentField = m_Schema.fields[m_NextFieldIndex];
GameDebug.Assert(type == m_CurrentField.fieldType, "Property:{0} has unexpected field type:{1} Expected:{2}", m_CurrentField.name, type, m_CurrentField.fieldType);
GameDebug.Assert(bits == m_CurrentField.bits);
GameDebug.Assert(arraySize == m_CurrentField.arraySize);
++m_NextFieldIndex;
}
uint* m_Input;
int m_Position;
NetworkSchema m_Schema;
NetworkSchema.FieldInfo m_CurrentField;
int m_NextFieldIndex;
static char[] s_CharBuffer = new char[1024 * 32];
}