/// <summary> /// /// </summary> /// <param name="chunkComponentType"></param> /// <returns></returns> public bool Has(ArchetypeChunkComponentTypeDynamic chunkComponentType) { int cache = chunkComponentType.m_TypeLookupCache; ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype, chunkComponentType.m_TypeIndex, ref cache); chunkComponentType.m_TypeLookupCache = (short)cache; return(cache != -1); }
/// <summary> /// /// </summary> /// <param name="chunkComponentType"></param> /// <param name="expectedTypeSize"></param> /// <typeparam name="T"></typeparam> /// <returns></returns> /// <exception cref="ArgumentException"></exception> /// <exception cref="InvalidOperationException"></exception> public NativeArray <T> GetDynamicComponentDataArrayReinterpret <T>(ArchetypeChunkComponentTypeDynamic chunkComponentType, int expectedTypeSize) where T : struct { #if ENABLE_UNITY_COLLECTIONS_CHECKS if (chunkComponentType.m_IsZeroSized) { throw new ArgumentException($"ArchetypeChunk.GetDynamicComponentDataArrayReinterpret<{typeof(T)}> cannot be called on zero-sized IComponentData"); } AtomicSafetyHandle.CheckReadAndThrow(chunkComponentType.m_Safety); #endif var archetype = m_Chunk->Archetype; int typeIndexInArchetype = chunkComponentType.m_TypeLookupCache; ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype, chunkComponentType.m_TypeIndex, ref typeIndexInArchetype); chunkComponentType.m_TypeLookupCache = (short)typeIndexInArchetype; if (typeIndexInArchetype == -1) { var emptyResult = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(null, 0, 0); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref emptyResult, chunkComponentType.m_Safety); #endif return(emptyResult); } var typeSize = archetype->SizeOfs[typeIndexInArchetype]; var length = m_Chunk->Count; var byteLen = length * typeSize; var outTypeSize = UnsafeUtility.SizeOf <T>(); var outLength = byteLen / outTypeSize; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (typeSize != expectedTypeSize) { throw new InvalidOperationException($"Dynamic chunk component type {TypeManager.GetType(chunkComponentType.m_TypeIndex)} (size = {typeSize}) size does not equal {expectedTypeSize}. Component size must match with expectedTypeSize."); } if (outTypeSize * outLength != byteLen) { throw new InvalidOperationException($"Dynamic chunk component type {TypeManager.GetType(chunkComponentType.m_TypeIndex)} (array length {length}) and {typeof(T)} cannot be aliased due to size constraints. The size of the types and lengths involved must line up."); } #endif var buffer = m_Chunk->Buffer; var startOffset = archetype->Offsets[typeIndexInArchetype]; var result = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <T>(buffer + startOffset, outLength, Allocator.None); #if ENABLE_UNITY_COLLECTIONS_CHECKS NativeArrayUnsafeUtility.SetAtomicSafetyHandle(ref result, chunkComponentType.m_Safety); #endif if (!chunkComponentType.IsReadOnly) { m_Chunk->SetChangeVersion(typeIndexInArchetype, chunkComponentType.GlobalSystemVersion); } return(result); }
/// <summary> /// Returns a version number that increases whenever read-write access to the given /// component is requested from this chunk, or 0 if the component doesn't exist in the chunk. /// </summary> /// <param name="chunkComponentType"></param> /// <typeparam name="ArchetypeChunkComponentTypeDynamic"></typeparam> /// <returns>Current version number of the given component</returns> public uint GetChangeVersion(ArchetypeChunkComponentTypeDynamic chunkComponentType) { int cache = chunkComponentType.m_TypeLookupCache; ChunkDataUtility.GetIndexInTypeArray(m_Chunk->Archetype, chunkComponentType.m_TypeIndex, ref cache); chunkComponentType.m_TypeLookupCache = (short)cache; int typeIndexInArchetype = cache; if (typeIndexInArchetype == -1) { return(0); } return(m_Chunk->GetChangeVersion(typeIndexInArchetype)); }
/// <summary> /// Reports whether any of IComponentData components in the chunk, of the type identified by /// <paramref name="chunkComponentType"/>, could have changed. /// </summary> /// <remarks> /// Note that for efficiency, the change version applies to whole chunks not individual entities. The change /// version is incremented even when another job or system that has declared write access to a component does /// not actually change the component value.</remarks> /// <param name="chunkComponentType">An object containing type and job safety information. Create this /// object by calling <see cref="Unity.Entities.JobComponentSystem.GetArchetypeChunkComponentTypeDynamic"/> immediately /// before scheduling a job. Pass the object to a job using a public field you define as part of the job struct. /// </param> /// <param name="version">The version to compare. In a system, this parameter should be set to the /// current <see cref="Unity.Entities.ComponentSystemBase.LastSystemVersion"/> at the time the job is run or /// scheduled.</param> /// <typeparam name="T">The component type.</typeparam> /// <returns>True, if the version number stored in the chunk for this component is more recent than the version /// passed to the <paramref name="version"/> parameter.</returns> public bool DidChange(ArchetypeChunkComponentTypeDynamic chunkComponentType, uint version) { return(ChangeVersionUtility.DidChange(GetChangeVersion(chunkComponentType), version)); }