public static void Initialize() { if (s_Types != null) { return; } ObjectOffset = UnsafeUtility.SizeOf <ObjectOffsetType>(); #if !UNITY_CSHARP_TINY s_CreateTypeLock = new SpinLock(); s_ManagedTypeToIndex = new Dictionary <Type, int>(1000); #endif s_Types = new TypeInfo[MaximumTypesCount]; #if !UNITY_CSHARP_TINY s_StableTypeHashToTypeIndex = new Dictionary <ulong, int>(); #endif s_Count = 0; #if !UNITY_CSHARP_TINY s_Types[s_Count++] = new TypeInfo(null, 0, 0, TypeCategory.ComponentData, FastEquality.TypeInfo.Null, null, null, 0, -1, 0, 1, 0, null, 0, int.MaxValue); // This must always be first so that Entity is always index 0 in the archetype AddTypeInfoToTables(new TypeInfo(typeof(Entity), 1, sizeof(Entity), TypeCategory.EntityData, FastEquality.CreateTypeInfo <Entity>(), EntityRemapUtility.CalculateEntityOffsets <Entity>(), null, 0, -1, sizeof(Entity), UnsafeUtility.AlignOf <Entity>(), CalculateStableTypeHash(typeof(Entity)), null, 0, int.MaxValue)); InitializeAllComponentTypes(); #else StaticTypeRegistry.StaticTypeRegistry.RegisterStaticTypes(); #endif }
private unsafe int FindNonDefaultSharedComponentIndex(int typeIndex, int hashCode, void *newData, FastEquality.TypeInfo typeInfo) { int itemIndex; NativeMultiHashMapIterator <int> iter; if (!m_HashLookup.TryGetFirstValue(hashCode, out itemIndex, out iter)) { return(-1); } do { var data = m_SharedComponentData[itemIndex]; if (data != null && m_SharedComponentType[itemIndex] == typeIndex) { ulong handle; var value = PinGCObjectAndGetAddress(data, out handle); var res = FastEquality.Equals(newData, value, typeInfo); UnsafeUtility.ReleaseGCObject(handle); if (res) { return(itemIndex); } } } while (m_HashLookup.TryGetNextValue(out itemIndex, ref iter)); return(-1); }
public static bool Equals(void *left, void *right, int typeIndex) { #if !UNITY_CSHARP_TINY var typeInfo = TypeManager.GetTypeInfo(typeIndex).FastEqualityTypeInfo; return(FastEquality.Equals(left, right, typeInfo)); #else return(StaticTypeRegistry.StaticTypeRegistry.Equals(left, right, typeIndex & ClearFlagsMask)); #endif }
public static bool Equals <T>(ref T left, ref T right) where T : struct { #if !UNITY_CSHARP_TINY var typeInfo = TypeManager.GetTypeInfo <T>().FastEqualityTypeInfo; return(FastEquality.Equals(ref left, ref right, typeInfo)); #else return(EqualityHelper <T> .Equals(left, right)); #endif }
private static bool IsDefaultObject <T>(ref T component, out int hashCode) where T : struct, ISharedComponentData { int typeIndex = TypeManager.GetTypeIndex <T>(); var layout = TypeManager.GetComponentType(typeIndex).FastEqualityLayout; var defaultValue = default(T); hashCode = FastEquality.GetHashCode(ref component, layout); return(FastEquality.Equals(ref defaultValue, ref component, layout)); }
public static int GetHashCode <T>(ref T val) where T : struct { #if !UNITY_CSHARP_TINY var typeInfo = TypeManager.GetTypeInfo <T>().FastEqualityTypeInfo; return(FastEquality.GetHashCode(ref val, typeInfo)); #else return(EqualityHelper <T> .Hash(val)); #endif }
public static int GetHashCode(void *val, int typeIndex) { #if !UNITY_CSHARP_TINY var typeInfo = TypeManager.GetTypeInfo(typeIndex).FastEqualityTypeInfo; return(FastEquality.GetHashCode(val, typeInfo)); #else return(StaticTypeRegistry.StaticTypeRegistry.GetHashCode(val, typeIndex & ClearFlagsMask)); #endif }
unsafe static int GetHashCodeFast(object target, FastEquality.Layout[] fastLayout) { ulong handle; void *ptr = PinGCObjectAndGetAddress(target, out handle); var hashCode = FastEquality.GetHashCode(ptr, fastLayout); UnsafeUtility.ReleaseGCObject(handle); return(hashCode); }
private static unsafe int GetHashCodeFast(object target, FastEquality.TypeInfo typeInfo) { ulong handle; var ptr = PinGCObjectAndGetAddress(target, out handle); var hashCode = FastEquality.GetHashCode(ptr, typeInfo); UnsafeUtility.ReleaseGCObject(handle); return(hashCode); }
private unsafe int FindSharedComponentIndex <T>(int typeIndex, T newData) where T : struct { var defaultVal = default(T); var typeInfo = TypeManager.GetTypeInfo(typeIndex).FastEqualityTypeInfo; if (FastEquality.Equals(ref defaultVal, ref newData, typeInfo)) { return(0); } return(FindNonDefaultSharedComponentIndex(typeIndex, FastEquality.GetHashCode(ref newData, typeInfo), UnsafeUtility.AddressOf(ref newData), typeInfo)); }
unsafe int FindSharedComponentIndex <T>(int typeIndex, T newData) where T : struct { var defaultVal = default(T); var fastLayout = TypeManager.GetComponentType(typeIndex).FastEqualityLayout; if (FastEquality.Equals(ref defaultVal, ref newData, fastLayout)) { return(0); } else { return(FindNonDefaultSharedComponentIndex(typeIndex, FastEquality.GetHashCode(ref newData, fastLayout), UnsafeUtility.AddressOf(ref newData), fastLayout)); } }
public static void Initialize() { if (s_Types != null) { return; } ObjectOffset = UnsafeUtility.SizeOf <ObjectOffsetType>(); s_CreateTypeLock = new SpinLock(); s_Types = new TypeInfo[MaximumTypesCount]; s_Count = 0; s_Types[s_Count++] = new TypeInfo(null, 0, TypeCategory.ComponentData, FastEquality.TypeInfo.Null, null, 0, -1, 0); // This must always be first so that Entity is always index 0 in the archetype s_Types[s_Count++] = new TypeInfo(typeof(Entity), sizeof(Entity), TypeCategory.EntityData, FastEquality.CreateTypeInfo(typeof(Entity)), EntityRemapUtility.CalculateEntityOffsets(typeof(Entity)), 0, -1, sizeof(Entity)); }
public int InsertSharedComponent <T>(T newData) where T : struct { int typeIndex = TypeManager.GetTypeIndex <T>(); int index = FindSharedComponentIndex(TypeManager.GetTypeIndex <T>(), newData); if (index == 0) { return(0); } else if (index != -1) { m_SharedComponentRefCount[index]++; return(index); } else { var fastLayout = TypeManager.GetComponentType(typeIndex).FastEqualityLayout; var hashcode = FastEquality.GetHashCode(ref newData, fastLayout); return(Add(typeIndex, hashcode, newData)); } }
public int InsertSharedComponent <T>(T newData) where T : struct { var typeIndex = TypeManager.GetTypeIndex <T>(); var index = FindSharedComponentIndex(TypeManager.GetTypeIndex <T>(), newData); if (index == 0) { return(0); } if (index != -1) { m_SharedComponentRefCount[index]++; return(index); } var typeInfo = TypeManager.GetTypeInfo(typeIndex).FastEqualityTypeInfo; var hashcode = FastEquality.GetHashCode(ref newData, typeInfo); return(Add(typeIndex, hashcode, newData)); }
public static TypeInfo BuildComponentType(Type type) { var componentSize = 0; TypeCategory category; var typeInfo = FastEquality.TypeInfo.Null; EntityOffsetInfo[] entityOffsets = null; int bufferCapacity = -1; var memoryOrdering = CalculateMemoryOrdering(type); int elementSize = 0; if (typeof(IComponentData).IsAssignableFrom(type)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!type.IsValueType) { throw new ArgumentException($"{type} is an IComponentData, and thus must be a struct."); } if (!UnsafeUtility.IsBlittable(type)) { throw new ArgumentException( $"{type} is an IComponentData, and thus must be blittable (No managed object is allowed on the struct)."); } #endif category = TypeCategory.ComponentData; if (TypeManager.IsZeroSizeStruct(type)) { componentSize = 0; } else { componentSize = UnsafeUtility.SizeOf(type); } typeInfo = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); } else if (typeof(IBufferElementData).IsAssignableFrom(type)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!type.IsValueType) { throw new ArgumentException($"{type} is an IBufferElementData, and thus must be a struct."); } if (!UnsafeUtility.IsBlittable(type)) { throw new ArgumentException( $"{type} is an IBufferElementData, and thus must be blittable (No managed object is allowed on the struct)."); } #endif category = TypeCategory.BufferData; elementSize = UnsafeUtility.SizeOf(type); var capacityAttribute = (InternalBufferCapacityAttribute)type.GetCustomAttribute(typeof(InternalBufferCapacityAttribute)); if (capacityAttribute != null) { bufferCapacity = capacityAttribute.Capacity; } else { bufferCapacity = 128 / elementSize; // Rather than 2*cachelinesize, to make it cross platform deterministic } componentSize = sizeof(BufferHeader) + bufferCapacity * elementSize; typeInfo = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); } else if (typeof(ISharedComponentData).IsAssignableFrom(type)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!type.IsValueType) { throw new ArgumentException($"{type} is an ISharedComponentData, and thus must be a struct."); } #endif category = TypeCategory.ISharedComponentData; typeInfo = FastEquality.CreateTypeInfo(type); } else if (type.IsClass) { category = TypeCategory.Class; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.FullName == "Unity.Entities.GameObjectEntity") { throw new ArgumentException( "GameObjectEntity can not be used from EntityManager. The component is ignored when creating entities for a GameObject."); } #endif } else { throw new ArgumentException($"'{type}' is not a valid component"); } #if ENABLE_UNITY_COLLECTIONS_CHECKS { int typeCount = 0; foreach (Type t in s_SingularInterfaces) { if (t.IsAssignableFrom(type)) { ++typeCount; } } if (typeCount > 1) { throw new ArgumentException($"Component {type} can only implement one of IComponentData, ISharedComponentData and IBufferElementData"); } } #endif return(new TypeInfo(type, componentSize, category, typeInfo, entityOffsets, memoryOrdering, bufferCapacity, elementSize > 0 ? elementSize : componentSize)); }
private static ComponentType BuildComponentType(Type type) { var componentSize = 0; TypeCategory category; FastEquality.Layout[] fastEqualityLayout = null; EntityOffsetInfo[] entityOffsets = null; var memoryOrdering = CalculateMemoryOrdering(type); if (typeof(IComponentData).IsAssignableFrom(type)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.IsClass) { throw new ArgumentException($"{type} is an IComponentData, and thus must be a struct."); } if (!UnsafeUtility.IsBlittable(type)) { throw new ArgumentException( $"{type} is an IComponentData, and thus must be blittable (No managed object is allowed on the struct)."); } #endif category = TypeCategory.ComponentData; componentSize = UnsafeUtility.SizeOf(type); fastEqualityLayout = FastEquality.CreateLayout(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); } else if (typeof(ISharedComponentData).IsAssignableFrom(type)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.IsClass) { throw new ArgumentException($"{type} is an ISharedComponentData, and thus must be a struct."); } #endif category = TypeCategory.ISharedComponentData; fastEqualityLayout = FastEquality.CreateLayout(type); } else if (type.IsValueType) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!UnsafeUtility.IsBlittable(type)) { throw new ArgumentException($"{type} is used for FixedArrays, and thus must be blittable."); } #endif category = TypeCategory.OtherValueType; componentSize = UnsafeUtility.SizeOf(type); } else if (type.IsClass) { category = TypeCategory.Class; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.FullName == "Unity.Entities.GameObjectEntity") { throw new ArgumentException( "GameObjectEntity can not be used from EntityManager. The component is ignored when creating entities for a GameObject."); } #endif } #if ENABLE_UNITY_COLLECTIONS_CHECKS else { throw new ArgumentException($"'{type}' is not a valid component"); }
public static void Initialize() { if (s_Types != null) { return; } ObjectOffset = UnsafeUtility.SizeOf <ObjectOffsetType>(); s_CreateTypeLock = new SpinLock(); s_Types = new ComponentType[MaximumTypesCount]; s_Count = 0; s_Types[s_Count++] = new ComponentType(null, 0, TypeCategory.ComponentData, null); // This must always be first so that Entity is always index 0 in the archetype s_Types[s_Count++] = new ComponentType(typeof(Entity), sizeof(Entity), TypeCategory.EntityData, FastEquality.CreateLayout(typeof(Entity))); }
public static TypeInfo BuildComponentType(Type type) { TypeCategory componentData; int size = 0; FastEquality.TypeInfo @null = FastEquality.TypeInfo.Null; EntityOffsetInfo[] entityOffsets = null; int bufferCapacity = -1; ulong memoryOrdering = CalculateMemoryOrdering(type); int num4 = 0; if (type.IsInterface) { throw new ArgumentException($"{type} is an interface. It must be a concrete type."); } if (typeof(IComponentData).IsAssignableFrom(type)) { if (!type.IsValueType) { throw new ArgumentException($"{type} is an IComponentData, and thus must be a struct."); } if (!UnsafeUtility.IsBlittable(type)) { throw new ArgumentException($"{type} is an IComponentData, and thus must be blittable (No managed object is allowed on the struct)."); } componentData = TypeCategory.ComponentData; if (IsZeroSizeStruct(type)) { size = 0; } else { size = UnsafeUtility.SizeOf(type); } @null = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); } else if (typeof(IBufferElementData).IsAssignableFrom(type)) { if (!type.IsValueType) { throw new ArgumentException($"{type} is an IBufferElementData, and thus must be a struct."); } if (!UnsafeUtility.IsBlittable(type)) { throw new ArgumentException($"{type} is an IBufferElementData, and thus must be blittable (No managed object is allowed on the struct)."); } componentData = TypeCategory.BufferData; num4 = UnsafeUtility.SizeOf(type); InternalBufferCapacityAttribute customAttribute = (InternalBufferCapacityAttribute)type.GetCustomAttribute(typeof(InternalBufferCapacityAttribute)); if (customAttribute != null) { bufferCapacity = customAttribute.Capacity; } else { bufferCapacity = 0x80 / num4; } size = sizeof(BufferHeader) + (bufferCapacity * num4); @null = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); } else if (typeof(ISharedComponentData).IsAssignableFrom(type)) { if (!type.IsValueType) { throw new ArgumentException($"{type} is an ISharedComponentData, and thus must be a struct."); } componentData = TypeCategory.ISharedComponentData; @null = FastEquality.CreateTypeInfo(type); } else { if (!type.IsClass) { throw new ArgumentException($"{type} is not a valid component."); } componentData = TypeCategory.Class; if (type.FullName == "Unity.Entities.GameObjectEntity") { throw new ArgumentException("GameObjectEntity cannot be used from EntityManager. The component is ignored when creating entities for a GameObject."); } if (UnityEngineComponentType == null) { throw new ArgumentException($"{type} cannot be used from EntityManager. If it inherits UnityEngine.Component, you must first register {typeof(TypeManager)}.{"UnityEngineComponentType"} or include the Unity.Entities.Hybrid assembly in your build."); } if (!UnityEngineComponentType.IsAssignableFrom(type)) { throw new ArgumentException($"{type} must inherit {UnityEngineComponentType}."); } } int num5 = 0; foreach (Type type2 in s_SingularInterfaces) { if (type2.IsAssignableFrom(type)) { num5++; } } if (num5 > 1) { throw new ArgumentException($"Component {type} can only implement one of IComponentData, ISharedComponentData and IBufferElementData"); } return(new TypeInfo(type, size, componentData, @null, entityOffsets, memoryOrdering, bufferCapacity, (num4 > 0) ? num4 : size)); }
internal static TypeInfo BuildComponentType(Type type, int *writeGroups, int writeGroupCount) { var componentSize = 0; TypeCategory category; var typeInfo = FastEquality.TypeInfo.Null; EntityOffsetInfo[] entityOffsets = null; EntityOffsetInfo[] blobAssetRefOffsets = null; int bufferCapacity = -1; var memoryOrdering = CalculateMemoryOrdering(type); var stableTypeHash = CalculateStableTypeHash(type); var maxChunkCapacity = int.MaxValue; var maxCapacityAttribute = type.GetCustomAttribute <MaximumChunkCapacityAttribute>(); if (maxCapacityAttribute != null) { maxChunkCapacity = maxCapacityAttribute.Capacity; } int elementSize = 0; int alignmentInBytes = 0; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.IsInterface) { throw new ArgumentException($"{type} is an interface. It must be a concrete type."); } #endif if (typeof(IComponentData).IsAssignableFrom(type)) { CheckIsAllowedAsComponentData(type, nameof(IComponentData)); category = TypeCategory.ComponentData; if (TypeManager.IsZeroSizeStruct(type)) { componentSize = 0; } else { componentSize = UnsafeUtility.SizeOf(type); } typeInfo = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); blobAssetRefOffsets = CalculatBlobAssetRefOffsets(type); int sizeInBytes = UnsafeUtility.SizeOf(type); // TODO: Implement UnsafeUtility.AlignOf(type) alignmentInBytes = 16; if (sizeInBytes < 16 && (sizeInBytes & (sizeInBytes - 1)) == 0) { alignmentInBytes = sizeInBytes; } } else if (typeof(IBufferElementData).IsAssignableFrom(type)) { CheckIsAllowedAsComponentData(type, nameof(IBufferElementData)); category = TypeCategory.BufferData; elementSize = UnsafeUtility.SizeOf(type); var capacityAttribute = (InternalBufferCapacityAttribute)type.GetCustomAttribute(typeof(InternalBufferCapacityAttribute)); if (capacityAttribute != null) { bufferCapacity = capacityAttribute.Capacity; } else { bufferCapacity = 128 / elementSize; // Rather than 2*cachelinesize, to make it cross platform deterministic } componentSize = sizeof(BufferHeader) + bufferCapacity * elementSize; typeInfo = FastEquality.CreateTypeInfo(type); entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); blobAssetRefOffsets = CalculatBlobAssetRefOffsets(type); int sizeInBytes = UnsafeUtility.SizeOf(type); // TODO: Implement UnsafeUtility.AlignOf(type) alignmentInBytes = 16; if (sizeInBytes < 16 && (sizeInBytes & (sizeInBytes - 1)) == 0) { alignmentInBytes = sizeInBytes; } } else if (typeof(ISharedComponentData).IsAssignableFrom(type)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (!type.IsValueType) { throw new ArgumentException($"{type} is an ISharedComponentData, and thus must be a struct."); } #endif entityOffsets = EntityRemapUtility.CalculateEntityOffsets(type); category = TypeCategory.ISharedComponentData; typeInfo = FastEquality.CreateTypeInfo(type); } else if (type.IsClass) { category = TypeCategory.Class; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (type.FullName == "Unity.Entities.GameObjectEntity") { throw new ArgumentException( "GameObjectEntity cannot be used from EntityManager. The component is ignored when creating entities for a GameObject."); } if (UnityEngineComponentType == null) { throw new ArgumentException( $"{type} cannot be used from EntityManager. If it inherits UnityEngine.Component, you must first register TypeManager.UnityEngineComponentType or include the Unity.Entities.Hybrid assembly in your build."); } if (!UnityEngineComponentType.IsAssignableFrom(type)) { throw new ArgumentException($"{type} must inherit {UnityEngineComponentType}."); } #endif } else { throw new ArgumentException($"{type} is not a valid component."); } #if ENABLE_UNITY_COLLECTIONS_CHECKS CheckComponentType(type); #endif int typeIndex = s_Count; return(new TypeInfo(type, typeIndex, componentSize, category, typeInfo, entityOffsets, blobAssetRefOffsets, memoryOrdering, bufferCapacity, elementSize > 0 ? elementSize : componentSize, alignmentInBytes, stableTypeHash, writeGroups, writeGroupCount, maxChunkCapacity)); }
public static void Initialize() { if (s_Types == null) { ObjectOffset = UnsafeUtility.SizeOf <ObjectOffsetType>(); s_CreateTypeLock = new System.Threading.SpinLock(); s_Types = new TypeInfo[0x2800]; s_Count = 0; s_Count++; s_Types[s_Count] = new TypeInfo(null, 0, TypeCategory.ComponentData, FastEquality.TypeInfo.Null, null, 0L, -1, 0); s_Count++; s_Types[s_Count] = new TypeInfo(typeof(Entity), sizeof(Entity), TypeCategory.EntityData, FastEquality.CreateTypeInfo(typeof(Entity)), EntityRemapUtility.CalculateEntityOffsets(typeof(Entity)), 0L, -1, sizeof(Entity)); } }