diff --git a/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs b/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs index 2c3c348..a2e120f 100644 --- a/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs +++ b/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs @@ -1,4 +1,5 @@ using System; +using GameCore.LowLevel; using Unity.Collections; namespace GameCore.Network @@ -15,6 +16,7 @@ namespace GameCore.Network } private NativeList entryList; + private NativeList freeEntryIndexStack; private NativeHashMap entryIndexMap; private NativeList dirtyList; private NativeList tempBuffer; @@ -22,20 +24,50 @@ namespace GameCore.Network public ClientAgent(AllocatorManager.AllocatorHandle allocator) { entryList = new NativeList(allocator) { default }; + freeEntryIndexStack = new NativeList(allocator); entryIndexMap = new NativeHashMap(16, allocator); dirtyList = new NativeList(allocator); - tempBuffer = new NativeList(allocator); + tempBuffer = new NativeList(allocator); } public void Dispose() { entryList.Dispose(); + freeEntryIndexStack.Dispose(); entryIndexMap.Dispose(); dirtyList.Dispose(); tempBuffer.Dispose(); } + private int AddEntry(int srcIndex) + { + var index = 0; + if (freeEntryIndexStack.Length > 0) + { + index = freeEntryIndexStack[^1]; + freeEntryIndexStack.RemoveAt(freeEntryIndexStack.Length - 1); + } + else + { + index = entryList.Length; + entryList.Add(default); + } + + entryIndexMap.Add(srcIndex, index); + ref var entry = ref entryList.ElementAt(index); + entry.srcIndex = srcIndex; + entry.generation = 0; + entry.inView = true; + return index; + } + + private void ReleaseEntry(int index, int srcIndex) + { + freeEntryIndexStack.Add(index); + entryIndexMap.Remove(srcIndex); + } + public void UpdateDirtySet(NetDatabase.Snapshot netDatabase, int frameId) { // clear inView flag @@ -47,7 +79,7 @@ namespace GameCore.Network var tempIntList = dirtyList; tempIntList.Clear(); - // 收集旧视野中的东西,包括等待删除的 entity + // 收集旧视野中的东西,包括等待删除的 for (int i = 1, l = entryList.Length; i < l; ++i) { ref readonly var entry = ref entryList.ElementAt(i); @@ -63,9 +95,9 @@ namespace GameCore.Network } var oldInViewCount = tempIntList.Length; - + netDatabase.GatherNetDataIndex(tempIntList); - + // 遍历 tempIntList 中新视野部分 (oldInViewCount 之后) { var j = oldInViewCount; @@ -78,14 +110,53 @@ namespace GameCore.Network } else { - tempIntList[j++] = srcIndex; + tempIntList[j++] = srcIndex; // 新添加的 } } + tempIntList.Resize(j, NativeArrayOptions.UninitializedMemory); } - //TODO + tempBuffer.Clear(); + var tempDirtyList = tempBuffer.ToTypedBuffer<(int, int)>(); + + // 新添加的加入dirty list + for (int i = oldInViewCount, l = tempIntList.Length; i < l; ++i) + { + var srcIndex = tempIntList[i]; + var index = AddEntry(srcIndex); + tempDirtyList.Add((int.MinValue, index)); + } + for (var i = 0; i < oldInViewCount; ++i) + { + var index = tempIntList[i]; + ref var entry = ref entryList.ElementAt(index); + if (!entry.inView) + { + if (entry.srcIndex != 0) + { + ReleaseEntry(index, entry.srcIndex); + var srcIndex = entry.srcIndex; + entry.generation = 0; + entry.srcIndex = 0; + + //TODO parentIndex + } + + if (entry.confirmedFrameId < entry.deleteFrameId) + { + // 如果删除没有得到确认,那就标记 inView,保证发送删除操作 + entry.inView = true; + tempDirtyList.Add((0, index)); + } + + continue; + } + + //TODO + } + //TODO } } } \ No newline at end of file