Last active
April 1, 2020 14:39
-
-
Save jeffvella/8ac73ba00552998b66140a886646a234 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Linq; | |
using System.Runtime.CompilerServices; | |
using System.Runtime.InteropServices; | |
using Unity.Burst; | |
using Unity.Collections; | |
using Unity.Collections.LowLevel.Unsafe; | |
using Unity.Entities; | |
using UnityEngine; | |
using UnityEngine.Profiling; | |
public unsafe class NativeTypeManager | |
{ | |
public static readonly SharedStatic<Container> StaticData; | |
static NativeTypeManager() | |
{ | |
StaticData = SharedStatic<Container>.GetOrCreate<NativeTypeManager, Container>(); | |
} | |
[RuntimeInitializeOnLoadMethod] | |
private static void Allocate() | |
{ | |
Debug.Log("NativeTypeManager RuntimeInitializeOnLoadMethod"); | |
if (!StaticData.Data.Map.IsCreated) | |
{ | |
Debug.Log("Allocating NativeTypeManager"); | |
var map = new NativeHashMap<int, int>(TypeManager.MaximumTypesCount, Allocator.Persistent); | |
StaticData.Data.Map = map; | |
var types = TypeManager.AllTypes.ToList(); | |
for (var i = 0; i < types.Count; i++) | |
{ | |
var typeInfo = types[i]; | |
if (typeInfo.Type != null) | |
{ | |
StaticData.Data.Map[BurstRuntime.GetHashCode32(typeInfo.Type)] = typeInfo.TypeIndex; | |
} | |
} | |
#if ENABLE_UNITY_COLLECTIONS_CHECKS | |
var sentinelField = map.GetType().GetField("m_DisposeSentinel", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); | |
var sentinel = (DisposeSentinel)sentinelField.GetValue(map); | |
DisposeSentinel.Clear(ref sentinel); | |
#endif | |
} | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static int GetTypeIndex<T>() | |
{ | |
return (*(SlimNativeHashMap**)StaticData.UnsafeDataPointer)->GetIntValue(BurstRuntime.GetHashCode32<T>()); | |
} | |
public struct Container | |
{ | |
public NativeHashMap<int, int> Map; | |
} | |
[StructLayout(LayoutKind.Explicit)] | |
public unsafe struct SlimNativeHashMap | |
{ | |
[FieldOffset(0)] public byte* values; | |
[FieldOffset(8)] public byte* keys; | |
[FieldOffset(16)] public byte* next; | |
[FieldOffset(24)] public byte* buckets; | |
[FieldOffset(32)] public int keyCapacity; | |
[FieldOffset(36)] public int bucketCapacityMask; | |
[FieldOffset(40)] public int allocatedIndexLength; | |
public int GetIntValue(int key) | |
{ | |
int entryIdx = ((int*)buckets)[key & bucketCapacityMask]; | |
if (entryIdx < 0 || entryIdx >= keyCapacity) | |
return -1; | |
while (*(int*)(keys + entryIdx * sizeof(int)) != key) | |
{ | |
entryIdx = ((int*)next)[entryIdx]; | |
if (entryIdx < 0 || entryIdx >= keyCapacity) | |
return -1; | |
} | |
return *(int*)(values + entryIdx * sizeof(int)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment