using System; using GameCore.LowLevel; using Unity.Collections; using Unity.Collections.LowLevel.Unsafe; namespace GameCore.Network { public partial struct NetDatabase { public struct Snapshot : IDisposable { private NativeDataContainer entries; private NativeArray dataContainers; private NativeList frameHistoryList; private NativeList> childrenList; private readonly int maxHistoryCount; public Snapshot(TypeMetaDatabase typeMetaDatabase, int maxHistoryCount, AllocatorManager.AllocatorHandle allocator) { entries = new(allocator); var typeCount = typeMetaDatabase.GetTotalTypeCount(); dataContainers = new NativeArray(typeCount, allocator.ToAllocator); for (var i = 0; i < typeCount; i++) { if (typeMetaDatabase.IsValid(i)) { dataContainers[i] = new UnsafeDataContainer(typeMetaDatabase.GetTypeSize(i), allocator); } } frameHistoryList = new NativeList(allocator); childrenList = new NativeList>(allocator); this.maxHistoryCount = maxHistoryCount; } public void Dispose() { entries.Dispose(); var typeCount = dataContainers.Length; for (var i = 0; i < typeCount; i++) { if (dataContainers[i].IsCreated) dataContainers[i].Dispose(); } dataContainers.Dispose(); frameHistoryList.Dispose(); for (int i = 0, len = childrenList.Length; i < len; i++) { childrenList[i].Dispose(); } childrenList.Dispose(); } public void GatherNetDataIndex(NativeList list) { for (int i = 1, len = entries.Length; i < len; ++i) { if (entries.HasValue(i)) list.Add(i); } } public void CopyFrom(NetDatabase database) { entries.CopyFrom(database.entries); var typeCount = dataContainers.Length; for (var i = 0; i < typeCount; i++) { ref var dataContainer = ref dataContainers.GetRef(i); if (dataContainer.IsCreated) dataContainer.CopyFrom(database.dataContainers[i]); } frameHistoryList.CopyFrom(database.frameHistoryList); var newLength = database.childrenList.Length; var oldLength = childrenList.Length; if (oldLength < newLength) { childrenList.Resize(newLength, NativeArrayOptions.UninitializedMemory); for (var i = oldLength; i < newLength; ++i) { childrenList.ElementAt(i) = new UnsafeList(0, database.allocator); } } for (int i = 0, len = database.childrenList.Length; i < len; ++i) { childrenList.ElementAt(i).CopyFrom(database.childrenList[i]); } } } } }