public unsafe int Serialize(int serializer, ArchetypeChunk chunk, int startIndex, uint currentTick, Entity *currentSnapshotEntity, void *currentSnapshotData, GhostSystemStateComponent *ghosts, NativeArray <Entity> ghostEntities, NativeArray <int> baselinePerEntity, NativeList <SnapshotBaseline> availableBaselines, DataStreamWriter dataStream, NetworkCompressionModel compressionModel) { switch (serializer) { case 0: { return(GhostSendSystem <GhostSerializerCollection> .InvokeSerialize(m_CubeGhostSerializer, serializer, chunk, startIndex, currentTick, currentSnapshotEntity, (CubeSnapshotData *)currentSnapshotData, ghosts, ghostEntities, baselinePerEntity, availableBaselines, dataStream, compressionModel)); } default: throw new ArgumentException("Invalid serializer type"); } }
public static unsafe int InvokeSerialize <TSerializer, TSnapshotData>(TSerializer serializer, int ghostType, ArchetypeChunk chunk, int startIndex, uint currentTick, Entity *currentSnapshotEntity, TSnapshotData *currentSnapshotData, GhostSystemStateComponent *ghosts, NativeArray <Entity> ghostEntities, NativeArray <int> baselinePerEntity, NativeList <SnapshotBaseline> availableBaselines, DataStreamWriter dataStream, NetworkCompressionModel compressionModel) where TSnapshotData : unmanaged, ISnapshotData <TSnapshotData> where TSerializer : struct, IGhostSerializer <TSnapshotData> { int ent; int sameBaselineCount = 0; for (ent = startIndex; ent < chunk.Count && dataStream.Length < TargetPacketSize; ++ent) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (ghosts[ent].ghostTypeIndex != ghostType) { // FIXME: what needs to happen to support this case? Should it be treated as a respawn? throw new InvalidOperationException("A ghost changed type, ghost must keep the same serializer type throughout their lifetime"); } #endif int baseline0 = baselinePerEntity[ent * 3]; int baseline1 = baselinePerEntity[ent * 3 + 1]; int baseline2 = baselinePerEntity[ent * 3 + 2]; if (sameBaselineCount == 0) { // Count how many entities will use the same baselines as this one, send baselines + count uint baselineTick0 = currentTick; uint baselineTick1 = currentTick; uint baselineTick2 = currentTick; if (baseline0 >= 0) { baselineTick0 = availableBaselines[baseline0].tick; } if (baseline1 >= 0) { baselineTick1 = availableBaselines[baseline1].tick; } if (baseline2 >= 0) { baselineTick2 = availableBaselines[baseline2].tick; } for (sameBaselineCount = 1; ent + sameBaselineCount < chunk.Count; ++sameBaselineCount) { if (baselinePerEntity[(ent + sameBaselineCount) * 3] != baseline0 || baselinePerEntity[(ent + sameBaselineCount) * 3 + 1] != baseline1 || baselinePerEntity[(ent + sameBaselineCount) * 3 + 2] != baseline2) { break; } } uint baseDiff0 = currentTick - baselineTick0; uint baseDiff1 = currentTick - baselineTick1; uint baseDiff2 = currentTick - baselineTick2; dataStream.WritePackedUInt(baseDiff0, compressionModel); dataStream.WritePackedUInt(baseDiff1, compressionModel); dataStream.WritePackedUInt(baseDiff2, compressionModel); dataStream.WritePackedUInt((uint)sameBaselineCount, compressionModel); } --sameBaselineCount; TSnapshotData *baselineSnapshotData0 = null; if (baseline0 >= 0) { baselineSnapshotData0 = ((TSnapshotData *)availableBaselines[baseline0].snapshot) + ent; } TSnapshotData *baselineSnapshotData1 = null; TSnapshotData *baselineSnapshotData2 = null; if (baseline2 >= 0) { baselineSnapshotData1 = ((TSnapshotData *)availableBaselines[baseline1].snapshot) + ent; baselineSnapshotData2 = ((TSnapshotData *)availableBaselines[baseline2].snapshot) + ent; } dataStream.WritePackedUInt((uint)ghosts[ent].ghostId, compressionModel); TSnapshotData *snapshot; var snapshotData = default(TSnapshotData); if (currentSnapshotData == null) { snapshot = &snapshotData; } else { snapshot = currentSnapshotData + ent; } serializer.CopyToSnapshot(chunk, ent, currentTick, ref *snapshot); var baselineData = default(TSnapshotData); TSnapshotData *baseline = &baselineData; if (baselineSnapshotData2 != null) { baselineData = *baselineSnapshotData0; baselineData.PredictDelta(currentTick, ref *baselineSnapshotData1, ref *baselineSnapshotData2); } else if (baselineSnapshotData0 != null) { baseline = baselineSnapshotData0; } snapshot->Serialize(ref *baseline, dataStream, compressionModel); if (currentSnapshotData != null) { currentSnapshotEntity[ent] = ghostEntities[ent]; } } return(ent); }