public static Trait Create <T>(T value) where T : struct { if (!UnsafeUtility.IsUnmanaged <T>()) { throw new Exception($"{typeof(T).Name} must be an unmanaged type"); } var sizeOfType = UnsafeUtility.SizeOf <T>(); var result = new Trait { type = typeof(T), byteArray = sizeOfType > 0 ? new byte[sizeOfType] : null }; unsafe { fixed(void *destination = result.byteArray) { UnsafeUtility.CopyStructureToPtr(ref value, destination); } } return(result); }
static void ValidateDataPortType(FieldInfo port, Type internalPortType) { if (!UnsafeUtility.IsUnmanaged(internalPortType)) { throw new InvalidNodeDefinitionException($"Data port type {internalPortType} in {port} is not unmanaged"); } }
private static void CheckIf_T_IsUnmanagedOrThrow() { if (!UnsafeUtility.IsUnmanaged <T>()) { throw new InvalidOperationException($"The type {typeof(T)} used in SharedStatic<{typeof(T)}> must be unmanaged (contain no managed types)."); } }
private static void Allocate(int length0, int length1, Allocator allocator, out NativeArray2D <T> array) { RequireValidAllocator(allocator); if (!UnsafeUtility.IsUnmanaged <T>()) { throw new InvalidOperationException("Only unmanaged types are supported."); } int length = length0 * length1; if (length <= 0) { throw new InvalidOperationException("Total number of elements must be greater than zero."); } array = new NativeArray2D <T> { m_Buffer = UnsafeUtility.Malloc(length * UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), allocator), m_Length0 = length0, m_Length1 = length1, m_Length = length1 * length0, m_AllocatorLabel = allocator }; #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out array.m_Safety, out array.m_DisposeSentinel, 1, allocator); #endif }
internal static void IsUnmanagedAndThrow() { if (!UnsafeUtility.IsUnmanaged <T>()) { throw new InvalidOperationException( $"{typeof(T)} used in NativeArray<{typeof(T)}> must be unmanaged (contain no managed types)."); } }
[BurstDiscard] // Must use BurstDiscard because UnsafeUtility.IsUnmanaged is not burstable. public static void CheckIsUnmanaged <T>() { #if !UNITY_DOTSPLAYER if (!UnsafeUtility.IsValidNativeContainerElementType <T>()) #else if (!UnsafeUtility.IsUnmanaged <T>()) #endif { throw new ArgumentException($"{typeof(T)} used in native collection is not blittable, not primitive, or contains a type tagged as NativeContainer"); } }
/// <summary> /// Hash a struct that has been boxed. Given a struct Node : INode, this allows to hash a value of static type INode and actual type Node. The actual type of obj must be unmanaged /// </summary> /// <param name="obj"></param> /// <param name="seed"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> public static unsafe uint HashBoxedUnmanagedStruct <T>(T obj, uint seed) { const int managedObjectHeaderSize = 16; Assert.IsTrue(UnsafeUtility.IsUnmanaged(obj.GetType()), $"Type {obj.GetType().Name} is managed"); var ptr = UnsafeUtility.PinGCObjectAndGetAddress(obj, out var handle); seed = math.hash((byte *)ptr + managedObjectHeaderSize, UnsafeUtility.SizeOf(obj.GetType()), seed); UnsafeUtility.ReleaseGCObject(handle); return(seed); }
public static void CheckIsAllowedAsComponentData(Type type, string baseTypeDesc) { if (UnsafeUtility.IsUnmanaged(type)) { return; } // it can't be used -- so we expect this to find and throw ThrowOnDisallowedComponentData(type, type, baseTypeDesc); // if something went wrong adnd the above didn't throw, then throw throw new ArgumentException($"{type} cannot be used as component data for unknown reasons (BUG)"); }
private static bool TypeUsesDelegates(Type t) { // Ignore classes. Our delegates use pointers and will freak out. if (!t.IsValueType) { return(false); } // Things with managed references must use delegate comparison. if (!UnsafeUtility.IsUnmanaged(t)) { return(true); } return(typeof(IEquatable <>).MakeGenericType(t).IsAssignableFrom(t)); }
TraitType(Type type) { Assert.IsTrue(HasTraitAttribute(type)); if (!UnsafeUtility.IsUnmanaged(type) || !UnsafeUtility.IsBlittable(type)) { throw new InvalidOperationException( $"Trait type {type.FullName} must be unmanaged and blittable."); } if (ImplementsTraitInterface(type)) { // // TODO: Find a way to call Trait.Execute directly // var executeSelf = type.GetMethod(nameof(ExecuteSelf), BindingFlags.Static | BindingFlags.Public); if (executeSelf == null) { throw new InvalidOperationException( $"Trait type {type.FullName} must implement 'ExecuteSelf'."); } executeFunction = CompileFunction(type, executeSelf); Assert.IsTrue(executeFunction != IntPtr.Zero); } else { executeFunction = IntPtr.Zero; } hashCode = BurstRuntime.GetHashCode32(type); this.type = type; }
/// <summary> /// Allocate memory for the array /// </summary> /// /// <param name="length0"> /// Length of the array's first dimension. Must be positive. /// </param> /// /// <param name="length1"> /// Length of the array's second dimension. Must be positive. /// </param> /// /// <param name="allocator"> /// Allocator to allocate native memory with. Must be valid as defined /// by <see cref="UnsafeUtility.IsValidAllocator"/>. /// </param> /// /// <param name="array"> /// Array to write to once allocated /// </param> private static void Allocate( int length0, int length1, Allocator allocator, out NativeArray2D <T> array) { RequireValidAllocator(allocator); #if !CSHARP_7_3_OR_NEWER if (!UnsafeUtility.IsUnmanaged <T>()) { throw new InvalidOperationException( "Only unmanaged types are supported"); } #endif int length = length0 * length1; if (length <= 0) { throw new InvalidOperationException( "Total number of elements must be greater than zero"); } array = new NativeArray2D <T> { m_Buffer = UnsafeUtility.Malloc( length * UnsafeUtility.SizeOf <T>(), UnsafeUtility.AlignOf <T>(), allocator), m_Length0 = length0, m_Length1 = length1, m_Allocator = allocator }; DisposeSentinel.Create( out array.m_Safety, out array.m_DisposeSentinel, 1, allocator); }
private static bool TypeUsesDelegates(Type t) { #if !UNITY_DISABLE_MANAGED_COMPONENTS // We have custom delegates to allow for class IComponentData comparisons // but any other non-value type should be ignored if (t.IsClass && typeof(IComponentData).IsAssignableFrom(t)) { return(true); } #endif if (!t.IsValueType) { return(false); } // Things with managed references must use delegate comparison. if (!UnsafeUtility.IsUnmanaged(t)) { return(true); } return(typeof(IEquatable <>).MakeGenericType(t).IsAssignableFrom(t)); }
private static void Init() { SuperLog.Log("TypeManager 初始化"); _types = new HashSet <Type>(); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (var assembly in assemblies) { var assemblyTypes = assembly.GetTypes(); foreach (var type in assemblyTypes) { if (!typeof(IByteBufferData).IsAssignableFrom(type) || !UnsafeUtility.IsUnmanaged(type)) { continue; } _types.Add(type); } } _id2Type = new Dictionary <int, Type>(_types.Count); _type2id = new Dictionary <Type, int>(_types.Count); _id2size = new Dictionary <int, int>(_types.Count); foreach (var type in _types) { int id = Hash128.Compute(type.FullName).GetHashCode(); Checker.Assert(id != 0); _id2Type.Add(id, type); _type2id.Add(type, id); _id2size.Add(id, UnsafeUtility.SizeOf(type)); } }
private static bool ValidMethod(MethodInfo methodInfo) { return(UnsafeUtility.IsUnmanaged(methodInfo.ReturnType) && methodInfo.ReturnType != typeof(void) && !methodInfo.ReturnType.IsPointer && methodInfo.GetParameters().Length > 0 && methodInfo.GetParameters().All(p => ValidMethodParameter(p))); }
private static bool ValidMethodParameter(ParameterInfo parameterInfo) { return(UnsafeUtility.IsUnmanaged(parameterInfo.ParameterType) && !parameterInfo.IsIn && !parameterInfo.IsOut && !parameterInfo.ParameterType.IsPointer); }
public static bool CanWatch(ComponentType componentType) { var typeInfo = TypeManager.GetTypeInfo(componentType.TypeIndex); return(typeInfo.Category == TypeManager.TypeCategory.ComponentData && UnsafeUtility.IsUnmanaged(componentType.GetManagedType())); }
public PropertyBagDebugInfo(Type type, IPropertyBag propertyBag) { Type = type; Namespace = type.Namespace; Assembly = type.Assembly.GetName().Name; Name = TypeUtility.GetTypeDisplayName(type); FullName = $"{Namespace}.{Name}"; m_PropertyBag = propertyBag; var bagType = m_PropertyBag.GetType(); if (null != bagType.GetCustomAttribute <System.Runtime.CompilerServices.CompilerGeneratedAttribute>()) { PropertyBagType = PropertyBagType.CodeGen; } else if (null != bagType.GetCustomAttribute <ReflectedPropertyBagAttribute>()) { PropertyBagType = PropertyBagType.Reflection; } else { PropertyBagType = PropertyBagType.Manual; } TypeTraits = type.IsValueType ? TypeTraits.Struct : TypeTraits.Class; if (UnsafeUtility.IsUnmanaged(type)) { TypeTraits |= TypeTraits.Unmanaged; } if (UnsafeUtility.IsBlittable(type)) { TypeTraits |= TypeTraits.Blittable; } if (type.IsGenericType) { TypeTraits |= TypeTraits.Generic; } TypeInfo = CacheTypeInfo(); Properties = CacheProperties(); PropertyNames = new List <string>(); PropertyTypes = new List <string>(); foreach (var property in Properties) { if (!(property is PropertyTypeDescriptor typed)) { continue; } PropertyNames.Add(typed.Descriptor.Name); PropertyTypes.Add(TypeUtility.GetTypeDisplayName(typed.Value)); } Serialization = CacheSerializationInfo(); UI = CacheInspectorInfo(); CanBeConstructed = TypeConstruction.CanBeConstructed(type); if (Properties.Count > 0) { Extensions |= ExtensionType.Properties; } if (Serialization.Count > 0) { Extensions |= ExtensionType.Serialization; } if (UI.Count > 0) { Extensions |= ExtensionType.UI; } }
static void InitializeAllComponentTypes() { var componentTypeSet = new HashSet <Type>(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { if (!IsAssemblyReferencingEntities(assembly)) { continue; } foreach (var type in assembly.GetTypes()) { if (type.IsAbstract || !type.IsValueType) { continue; } if (!UnsafeUtility.IsUnmanaged(type)) { continue; } if (typeof(IComponentData).IsAssignableFrom(type) || typeof(ISharedComponentData).IsAssignableFrom(type) || typeof(IBufferElementData).IsAssignableFrom(type)) { componentTypeSet.Add(type); } } } var lockTaken = false; try { s_CreateTypeLock.Enter(ref lockTaken); var componentTypeCount = componentTypeSet.Count; var componentTypes = new Type[componentTypeCount]; componentTypeSet.CopyTo(componentTypes); var typeIndexByType = new Dictionary <Type, int>(); var writeGroupByType = new Dictionary <int, HashSet <int> >(); var startTypeIndex = s_Count; for (int i = 0; i < componentTypes.Length; i++) { typeIndexByType[componentTypes[i]] = startTypeIndex + i; } GatherWriteGroups(componentTypes, startTypeIndex, typeIndexByType, writeGroupByType); AddAllComponentTypes(componentTypes, startTypeIndex, writeGroupByType); } finally { if (lockTaken) { s_CreateTypeLock.Exit(true); } } }