|
|
|
|
@ -1,4 +1,5 @@ |
|
|
|
|
using System; |
|
|
|
|
using GameCore.LowLevel; |
|
|
|
|
using Unity.Collections; |
|
|
|
|
|
|
|
|
|
namespace GameCore.Network |
|
|
|
|
@ -15,6 +16,7 @@ namespace GameCore.Network |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private NativeList<Entry> entryList; |
|
|
|
|
private NativeList<int> freeEntryIndexStack; |
|
|
|
|
private NativeHashMap<int, int> entryIndexMap; |
|
|
|
|
private NativeList<int> dirtyList; |
|
|
|
|
private NativeList<byte> tempBuffer; |
|
|
|
|
@ -22,20 +24,50 @@ namespace GameCore.Network |
|
|
|
|
public ClientAgent(AllocatorManager.AllocatorHandle allocator) |
|
|
|
|
{ |
|
|
|
|
entryList = new NativeList<Entry>(allocator) { default }; |
|
|
|
|
freeEntryIndexStack = new NativeList<int>(allocator); |
|
|
|
|
entryIndexMap = new NativeHashMap<int, int>(16, allocator); |
|
|
|
|
|
|
|
|
|
dirtyList = new NativeList<int>(allocator); |
|
|
|
|
tempBuffer = new NativeList<byte>(allocator); |
|
|
|
|
tempBuffer = new NativeList<byte>(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 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |