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

133 行
4.9 KiB

using System.Collections.Generic;
using UnityEngine;
using NetworkCompression;
using Unity.Sample.Core;
public delegate void NetworkEventGenerator(ref NetworkWriter data);
public delegate void NetworkEventProcessor(ushort typeId, ref NetworkReader data);
public class NetworkEventType
{
public ushort typeId;
public NetworkSchema schema;
}
public class NetworkEvent
{
public int sequence;
public bool reliable;
public NetworkEventType type;
public uint[] data = new uint[NetworkConfig.maxEventDataSize];
public void AddRef()
{
++m_RefCount;
}
public void Release()
{
GameDebug.Assert(m_RefCount > 0, "Trying to release an event that has refcount 0 (seq: {0})", sequence);
if (--m_RefCount == 0)
{
if (NetworkConfig.netDebug.IntValue > 0)
GameDebug.Log("Releasing event " + ((GameNetworkEvents.EventType) this.type.typeId) + ":" + this.sequence);
s_Pool.Release(this);
}
}
public static NetworkEvent Create(NetworkEventType type, bool reliable = false)
{
var result = s_Pool.Allocate();
GameDebug.Assert(result.m_RefCount == 0);
result.m_RefCount = 1;
result.sequence = 0;
result.reliable = reliable;
result.type = type;
return result;
}
public unsafe static NetworkEvent Serialize(ushort typeId, bool reliable, Dictionary<ushort, NetworkEventType> eventTypes, NetworkEventGenerator generator)
{
bool generateSchema = false;
NetworkEventType type;
if (!eventTypes.TryGetValue(typeId, out type))
{
generateSchema = true;
type = new NetworkEventType() { typeId = typeId, schema = new NetworkSchema(NetworkConfig.firstEventTypeSchemaId + typeId) };
eventTypes.Add(typeId, type);
}
var result = Create(type, reliable);
result.sequence = ++s_Sequence;
if (NetworkConfig.netDebug.IntValue > 0)
GameDebug.Log("Serializing event " + ((GameNetworkEvents.EventType)result.type.typeId) + " in seq no: " + result.sequence);
fixed(uint* data = result.data)
{
NetworkWriter writer = new NetworkWriter(data, result.data.Length, type.schema, generateSchema);
generator(ref writer);
writer.Flush();
}
return result;
}
public static int ReadEvents<TInputStream>(Dictionary<ushort, NetworkEventType> eventTypesIn, int connectionId, ref TInputStream input, INetworkCallbacks networkConsumer) where TInputStream : NetworkCompression.IInputStream
{
var eventCount = input.ReadPackedUInt(NetworkConfig.eventCountContext);
for (var eventCounter = 0; eventCounter < eventCount; ++eventCounter)
{
var typeId = (ushort)input.ReadPackedUInt(NetworkConfig.eventTypeIdContext);
var schemaIncluded = input.ReadRawBits(1) != 0;
if (schemaIncluded)
{
var eventType = new NetworkEventType() { typeId = typeId };
eventType.schema = NetworkSchema.ReadSchema(ref input);
if (!eventTypesIn.ContainsKey(typeId))
eventTypesIn.Add(typeId, eventType);
}
// TODO (petera) do we need to Create an info (as we are just releasing it right after?)
var type = eventTypesIn[typeId];
var info = Create(type);
NetworkSchema.CopyFieldsToBuffer(type.schema, ref input, info.data);
if (NetworkConfig.netDebug.IntValue > 0)
GameDebug.Log("Received event " + ((GameNetworkEvents.EventType)info.type.typeId + ":" + info.sequence));
networkConsumer.OnEvent(connectionId, info);
info.Release();
}
return (int)eventCount;
}
unsafe public static void WriteEvents<TOutputStream>(List<NetworkEvent> events, List<NetworkEventType> knownEventTypes, ref TOutputStream output) where TOutputStream : NetworkCompression.IOutputStream
{
output.WritePackedUInt((uint)events.Count, NetworkConfig.eventCountContext);
foreach (var info in events)
{
// Write event schema if the client haven't acked this event type
output.WritePackedUInt(info.type.typeId, NetworkConfig.eventCountContext);
if (!knownEventTypes.Contains(info.type))
{
output.WriteRawBits(1, 1);
NetworkSchema.WriteSchema(info.type.schema, ref output);
}
else
output.WriteRawBits(0, 1);
// Write event data
fixed(uint* data = info.data)
{
NetworkSchema.CopyFieldsFromBuffer(info.type.schema, data, ref output);
}
}
}
int m_RefCount;
static int s_Sequence;
static NetworkObjectPool<NetworkEvent> s_Pool = new NetworkObjectPool<NetworkEvent>(100);
}