完善NetDatabase

This commit is contained in:
sunqinzhe committed 2025-12-31 18:45:01 +08:00
1 parent 098cbfb696
commit 88125fc128
28 files changed
+771 -39

No files matched your search

@@ -0,0 +1,31 @@
using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace GameCore.LowLevel
{
public static class NativeArrayExtensions
{
public static ref T GetRef<T>(this NativeArray<T> array, int index)
where T : struct
{
if (index < 0 || index >= array.Length)
throw new ArgumentOutOfRangeException(nameof(index));
unsafe
{
return ref UnsafeUtility.ArrayElementAsRef<T>(array.GetUnsafePtr(), index);
}
}
public static ref readonly T GetReadOnlyRef<T>(this NativeArray<T> array, int index)
where T : struct
{
if (index < 0 || index >= array.Length)
throw new ArgumentOutOfRangeException(nameof(index));
unsafe
{
return ref UnsafeUtility.ArrayElementAsRef<T>(array.GetUnsafeReadOnlyPtr(), index);
}
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9b8d3e5900ff43ab8d285485371094ca
timeCreated: 1767086551
@@ -0,0 +1,55 @@
using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
namespace GameCore.LowLevel
{
public unsafe struct NativeDataContainer<T> : IDisposable where T : unmanaged
{
[NativeDisableUnsafePtrRestriction]
internal UnsafeDataContainer* m_UnsafeDataPtr;
internal AllocatorManager.AllocatorHandle m_Allocator;
public bool IsCreated => m_UnsafeDataPtr != null;
public NativeDataContainer(AllocatorManager.AllocatorHandle allocator)
{
m_UnsafeDataPtr = AllocatorManager.Allocate<UnsafeDataContainer>(allocator);
*m_UnsafeDataPtr = new UnsafeDataContainer(UnsafeUtility.SizeOf<T>(), allocator);
m_Allocator = allocator;
}
public void Dispose()
{
if (!IsCreated)
{
return;
}
m_UnsafeDataPtr->Dispose();
AllocatorManager.Free(m_Allocator, m_UnsafeDataPtr);
m_UnsafeDataPtr = null;
}
public bool Free(int index)
{
return m_UnsafeDataPtr->Free(index);
}
public int Alloc(UnsafeDataContainer.AllocOptions options = UnsafeDataContainer.AllocOptions.None)
{
return m_UnsafeDataPtr->Alloc(options);
}
public ref T ElementAt(int index)
{
return ref m_UnsafeDataPtr->ElementAt<T>(index);
}
public void Clear()
{
m_UnsafeDataPtr->Clear();
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8c8c1ce9e9104a6ab8e96adc313588fe
timeCreated: 1767171335
@@ -0,0 +1,102 @@
using System;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using UnityEngine;
namespace GameCore.LowLevel
{
public unsafe struct UnsafeDataContainer : IDisposable
{
private struct FreeNode
{
public int next;
public int _padding;
}
public enum AllocOptions
{
None = 0,
ClearNew = 1,
ClearAll = 2,
}
public readonly int elementSize;
private UnsafeList<FreeNode> m_Buffer;
private readonly int m_NodeNumPerElement;
public bool IsCreated => m_Buffer.IsCreated;
public UnsafeDataContainer(int elementSize, AllocatorManager.AllocatorHandle allocator)
{
if (elementSize <= 0)
throw new ArgumentException(nameof(elementSize));
this.elementSize = elementSize;
m_NodeNumPerElement = ComputeNodeNumPerElement(elementSize);
m_Buffer = new UnsafeList<FreeNode>(0, allocator);
m_Buffer.Resize(m_NodeNumPerElement, NativeArrayOptions.ClearMemory);
}
public void Dispose()
{
m_Buffer.Dispose();
}
public bool Free(int index)
{
ref var node = ref m_Buffer.ElementAt(index * m_NodeNumPerElement);
if (node.next >= 0)
return false;
ref var head = ref m_Buffer.ElementAt(0);
node.next = head.next;
head.next = index;
return true;
}
public int Alloc(AllocOptions options = AllocOptions.None)
{
ref var head = ref m_Buffer.ElementAt(0);
var index = head.next;
if (index == 0)
{
index = m_Buffer.Length / m_NodeNumPerElement;
m_Buffer.Resize(m_Buffer.Length + m_NodeNumPerElement, options == AllocOptions.None ? NativeArrayOptions.UninitializedMemory : NativeArrayOptions.ClearMemory);
m_Buffer.ElementAt(index * m_NodeNumPerElement).next = -1;
return index;
}
ref var node = ref m_Buffer.ElementAt(index * m_NodeNumPerElement);
if (options == AllocOptions.ClearAll)
{
var ptr = m_Buffer.Ptr + index * m_NodeNumPerElement;
UnsafeUtility.MemClear(ptr, m_NodeNumPerElement * UnsafeUtility.SizeOf<FreeNode>());
}
head.next = node.next;
node.next = -1;
return index;
}
public ref T ElementAt<T>(int index) where T : unmanaged
{
ref var node = ref m_Buffer.ElementAt(index * m_NodeNumPerElement);
if (node.next >= 0)
throw new IndexOutOfRangeException();
return ref UnsafeUtility.As<FreeNode, T>(ref m_Buffer.ElementAt(index * m_NodeNumPerElement + 1));
}
public void Clear()
{
m_Buffer.Resize(m_NodeNumPerElement);
m_Buffer.ElementAt(0).next = 0;
}
internal static int ComputeNodeNumPerElement(int elementSize)
{
return (elementSize + UnsafeUtility.SizeOf<FreeNode>() - 1) / UnsafeUtility.SizeOf<FreeNode>() + 1;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 345278cb8e5e4c4cbd58ead608d3d098
timeCreated: 1766977488
@@ -5,25 +5,9 @@
"Unity.Collections",
"Unity.Mathematics"
],
"includePlatforms": [
"Android",
"Editor",
"iOS",
"LinuxStandalone64",
"Lumin",
"macOSStandalone",
"PS4",
"Stadia",
"Switch",
"tvOS",
"WSA",
"WebGL",
"WindowsStandalone32",
"WindowsStandalone64",
"XboxOne"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"allowUnsafeCode": true,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,