diff --git a/LocalPackages/com.nimin.lowlevel/Runtime/TypedBuffer.cs b/LocalPackages/com.nimin.lowlevel/Runtime/TypedBuffer.cs new file mode 100644 index 0000000..7245f93 --- /dev/null +++ b/LocalPackages/com.nimin.lowlevel/Runtime/TypedBuffer.cs @@ -0,0 +1,51 @@ +using System; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; + +namespace GameCore.LowLevel +{ + public ref struct TypedBuffer where T : unmanaged + { + public NativeList buffer; + + public int Length => buffer.Length / UnsafeUtility.SizeOf(); + + public TypedBuffer(NativeList buffer) + { + this.buffer = buffer; + } + + public unsafe void Add(T data) + { + var oldLength = buffer.Length; + buffer.Resize(oldLength + sizeof(T), NativeArrayOptions.UninitializedMemory); + UnsafeUtility.CopyStructureToPtr(ref data, (byte*)buffer.GetUnsafePtr() + oldLength); + } + + public unsafe T this[int index] + { + get + { + if (index < 0 || index >= Length) + throw new IndexOutOfRangeException(nameof(index)); + var p = (T*)buffer.GetUnsafeReadOnlyPtr(); + return p[index]; + } + } + } + + public static class TypedBufferExtensions + { + public static TypedBuffer ToTypedBuffer(this NativeList buffer) + where T : unmanaged + => new(buffer); + + public static unsafe void Sort(this TypedBuffer typedBuffer) + where T : unmanaged, IComparable + { + var p = (T*)typedBuffer.buffer.GetUnsafePtr(); + var l = typedBuffer.buffer.Length / sizeof(T); + NativeSortExtension.Sort(p, l); + } + } +} \ No newline at end of file diff --git a/LocalPackages/com.nimin.lowlevel/Runtime/TypedBuffer.cs.meta b/LocalPackages/com.nimin.lowlevel/Runtime/TypedBuffer.cs.meta new file mode 100644 index 0000000..2641b98 --- /dev/null +++ b/LocalPackages/com.nimin.lowlevel/Runtime/TypedBuffer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: edfdc737cb64451ebdd0dc178e8c07af +timeCreated: 1767469202 \ No newline at end of file diff --git a/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs b/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs index a3aa415..2c3c348 100644 --- a/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs +++ b/LocalPackages/com.nimin.network/Runtime/ClientAgent.cs @@ -5,16 +5,87 @@ namespace GameCore.Network { public struct ClientAgent : IDisposable { - private NativeList dirtySet; - + private struct Entry + { + public int srcIndex; + public int generation; + public int confirmedFrameId; + public int deleteFrameId; + public bool inView; + } + + private NativeList entryList; + private NativeHashMap entryIndexMap; + private NativeList dirtyList; + private NativeList tempBuffer; + + public ClientAgent(AllocatorManager.AllocatorHandle allocator) + { + entryList = new NativeList(allocator) { default }; + entryIndexMap = new NativeHashMap(16, allocator); + + dirtyList = new NativeList(allocator); + tempBuffer = new NativeList(allocator); + } + public void Dispose() { - //TODO + entryList.Dispose(); + entryIndexMap.Dispose(); + dirtyList.Dispose(); + tempBuffer.Dispose(); } public void UpdateDirtySet(NetDatabase.Snapshot netDatabase, int frameId) { + // clear inView flag + for (int i = 1, l = entryList.Length; i < l; ++i) + { + entryList.ElementAt(i).inView = false; + } + + var tempIntList = dirtyList; + tempIntList.Clear(); + + // 收集旧视野中的东西,包括等待删除的 entity + for (int i = 1, l = entryList.Length; i < l; ++i) + { + ref readonly var entry = ref entryList.ElementAt(i); + + if (entry.srcIndex == 0) + { + //TODO + } + else + { + tempIntList.Add(i); + } + } + + var oldInViewCount = tempIntList.Length; + netDatabase.GatherNetDataIndex(tempIntList); + + // 遍历 tempIntList 中新视野部分 (oldInViewCount 之后) + { + var j = oldInViewCount; + for (int i = oldInViewCount, l = tempIntList.Length; i < l; ++i) + { + var srcIndex = tempIntList[i]; + if (entryIndexMap.TryGetValue(srcIndex, out var index)) + { + entryList.ElementAt(index).inView = true; + } + else + { + tempIntList[j++] = srcIndex; + } + } + tempIntList.Resize(j, NativeArrayOptions.UninitializedMemory); + } + + //TODO + } } } \ No newline at end of file