internal object GetManagedObject(ManagedComponentStore managedComponentStore, int typeIndexInQuery, int entityInChunkIndex)
        {
            var indexInArchetype      = CurrentMatchingArchetype->IndexInArchetype[typeIndexInQuery];
            var managedComponentArray = (int *)ChunkDataUtility.GetComponentDataRW(CurrentChunk, 0, indexInArchetype, CurrentArchetype->EntityComponentStore->GlobalSystemVersion);

            return(managedComponentStore.GetManagedComponent(managedComponentArray[entityInChunkIndex]));
        }
        /// <summary>
        /// This method will handle the cloning of Hybrid Components (if any) during the batched instantiation of an Entity
        /// </summary>
        /// <param name="srcArray">Array of source managed component indices. One per <paramref name="componentCount"/></param>
        /// <param name="componentCount">Number of component being instantiated</param>
        /// <param name="dstEntities">Array of destination entities. One per <paramref name="instanceCount"/></param>
        /// <param name="dstCompanionLinkIndices">Array of destination CompanionLink indices, can be null if the hybrid components are not owned</param>
        /// <param name="dstArray">Array of destination managed component indices. One per <paramref name="componentCount"/>*<paramref name="instanceCount"/>. All indices for the first component stored first etc.</param>
        /// <param name="instanceCount">Number of instances being created</param>
        /// <param name="managedComponentStore">Managed Store that owns the instances we create</param>
        static void InstantiateHybridComponentDelegate(int *srcArray, int componentCount, Entity *dstEntities, int *dstCompanionLinkIndices, int *dstArray, int instanceCount, ManagedComponentStore managedComponentStore)
        {
            if (dstCompanionLinkIndices != null)
            {
                var dstCompanionGameObjects = new GameObject[instanceCount];
                for (int i = 0; i < instanceCount; ++i)
                {
                    var companionLink = (CompanionLink)managedComponentStore.GetManagedComponent(dstCompanionLinkIndices[i]);
                    dstCompanionGameObjects[i] = companionLink.Companion;
                    CompanionLink.SetCompanionName(dstEntities[i], dstCompanionGameObjects[i]);
                }

                for (int src = 0; src < componentCount; ++src)
                {
                    var componentType = managedComponentStore.GetManagedComponent(srcArray[src]).GetType();

                    for (int i = 0; i < instanceCount; i++)
                    {
                        var componentInInstance = dstCompanionGameObjects[i].GetComponent(componentType);
                        var dstIndex            = src * instanceCount + i;
                        managedComponentStore.SetManagedComponentValue(dstArray[dstIndex], componentInInstance);
                    }
                }
            }
            else
            {
                for (int src = 0; src < componentCount; ++src)
                {
                    var component = managedComponentStore.GetManagedComponent(srcArray[src]);

                    for (int i = 0; i < instanceCount; i++)
                    {
                        var dstIndex = src * instanceCount + i;
                        managedComponentStore.SetManagedComponentValue(dstArray[dstIndex], component);
                    }
                }
            }
        }
        /// <summary>
        /// This method will handle the cloning of Hybrid Components (if any) during the batched instantiation of an Entity
        /// </summary>
        /// <param name="srcArray">Array of source managed component indices. One per <paramref name="componentCount"/></param>
        /// <param name="componentCount">Number of component being instantiated</param>
        /// <param name="dstEntities">Array of destination entities. One per <paramref name="instanceCount"/></param>
        /// <param name="dstArray">Array of destination managed component indices. One per <paramref name="componentCount"/>*<paramref name="instanceCount"/>. All indices for the first component stored first etc.</param>
        /// <param name="instanceCount">Number of instances being created</param>
        /// <param name="managedComponentStore">Managed Store that owns the instances we create</param>
        static void InstantiateHybridComponentDelegate(int *srcArray, int componentCount, Entity *dstEntities, int *dstArray, int instanceCount, ManagedComponentStore managedComponentStore)
        {
            object[] gameObjectInstances = null;

            for (int src = 0; src < componentCount; ++src)
            {
                object sourceComponent = managedComponentStore.GetManagedComponent(srcArray[src]);
                if ((sourceComponent as UnityEngine.Component)?.gameObject.GetComponent <CompanionLink>() == null)
                {
                    for (int i = 0; i < instanceCount; ++i)
                    {
                        managedComponentStore.SetManagedComponentValue(dstArray[i], sourceComponent);
                    }
                }
                else
                {
                    var unityComponent = (UnityEngine.Component)sourceComponent;

                    if (gameObjectInstances == null)
                    {
                        gameObjectInstances = new object[instanceCount];

                        for (int i = 0; i < instanceCount; ++i)
                        {
                            var instance = GameObject.Instantiate(unityComponent.gameObject);
                            instance.name          = CompanionLink.GenerateCompanionName(dstEntities[i]);
                            gameObjectInstances[i] = instance;
                            instance.hideFlags    |= HideFlags.HideInHierarchy;
                        }
                    }

                    for (int i = 0; i < instanceCount; i++)
                    {
                        var componentInInstance = ((GameObject)gameObjectInstances[i]).GetComponent(unityComponent.GetType());
                        managedComponentStore.SetManagedComponentValue(dstArray[i], componentInInstance);
                    }
                }

                dstArray += instanceCount;
            }
        }
        internal static BlobAssetsWithDistinctHash GetBlobAssetsWithDistinctHash(
            ManagedComponentStore managedComponentStore,
            NativeArray <ArchetypeChunk> chunks,
            Allocator allocator)
        {
            s_GetBlobAssetsWithDistinctHash.Begin();
            var blobAssetsWithDistinctHash = new BlobAssetsWithDistinctHash(allocator);

            var typeInfoPtr           = TypeManager.GetTypeInfoPointer();
            var blobAssetRefOffsetPtr = TypeManager.GetBlobAssetRefOffsetsPointer();

            var managedObjectBlobs         = new ManagedObjectBlobs();
            var managedObjectBlobAssets    = new NativeList <BlobAssetPtr>(16, Allocator.Temp);
            var managedObjectBlobAssetsMap = new NativeHashMap <BlobAssetPtr, int>(16, Allocator.Temp);

            for (var chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++)
            {
                var chunk     = chunks[chunkIndex].m_Chunk;
                var archetype = chunk->Archetype;

                // skip this chunk only if we are _certain_ there are no blob asset refs.
                if (!archetype->HasBlobAssetRefs)
                {
                    continue;
                }

                var typesCount  = archetype->TypesCount;
                var entityCount = chunks[chunkIndex].Count;

                for (var unorderedTypeIndexInArchetype = 0; unorderedTypeIndexInArchetype < typesCount; unorderedTypeIndexInArchetype++)
                {
                    var typeIndexInArchetype     = archetype->TypeMemoryOrder[unorderedTypeIndexInArchetype];
                    var componentTypeInArchetype = archetype->Types[typeIndexInArchetype];
                    if (componentTypeInArchetype.IsZeroSized)
                    {
                        continue;
                    }

                    ref var typeInfo = ref typeInfoPtr[componentTypeInArchetype.TypeIndex & TypeManager.ClearFlagsMask];
                    if (!typeInfo.HasBlobAssetRefs)
                    {
                        continue;
                    }

                    var chunkBuffer         = chunk->Buffer;
                    var subArrayOffset      = archetype->Offsets[typeIndexInArchetype];
                    var componentArrayStart = chunkBuffer + subArrayOffset;

                    if (componentTypeInArchetype.IsManagedComponent)
                    {
                        var componentSize = archetype->SizeOfs[typeIndexInArchetype];
                        var end           = componentArrayStart + componentSize * entityCount;

                        for (var componentData = componentArrayStart; componentData < end; componentData += componentSize)
                        {
                            var managedComponentIndex = *(int *)componentData;
                            var managedComponentValue = managedComponentStore.GetManagedComponent(managedComponentIndex);

                            if (null != managedComponentValue)
                            {
                                managedObjectBlobs.GatherBlobAssetReferences(managedComponentValue, managedObjectBlobAssets, managedObjectBlobAssetsMap);
                            }
                        }
                    }
                    else
                    {
                        var blobAssetRefCount = typeInfo.BlobAssetRefOffsetCount;

                        var blobAssetRefOffsets = blobAssetRefOffsetPtr + typeInfo.BlobAssetRefOffsetStartIndex;

                        if (componentTypeInArchetype.IsBuffer)
                        {
                            var header      = (BufferHeader *)componentArrayStart;
                            var strideSize  = archetype->SizeOfs[typeIndexInArchetype];
                            var elementSize = typeInfo.ElementSize;

                            for (var entityIndex = 0; entityIndex < entityCount; entityIndex++)
                            {
                                var bufferStart = BufferHeader.GetElementPointer(header);
                                var bufferEnd   = bufferStart + header->Length * elementSize;

                                for (var componentData = bufferStart; componentData < bufferEnd; componentData += elementSize)
                                {
                                    AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash);
                                }

                                header = (BufferHeader *)(((byte *)header) + strideSize);
                            }
                        }
                        else
                        {
                            var componentSize = archetype->SizeOfs[typeIndexInArchetype];
                            var end           = componentArrayStart + componentSize * entityCount;

                            for (var componentData = componentArrayStart; componentData < end; componentData += componentSize)
                            {
                                AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash);
                            }
                        }
                    }
                }
            }
Beispiel #5
0
        internal static BlobAssetsWithDistinctHash GetBlobAssetsWithDistinctHash(
            ManagedComponentStore managedComponentStore,
            NativeArray <ArchetypeChunk> chunks,
            Allocator allocator)
        {
            var blobAssetsWithDistinctHash = new BlobAssetsWithDistinctHash(allocator);

            var typeInfoPtr           = TypeManager.GetTypeInfoPointer();
            var blobAssetRefOffsetPtr = TypeManager.GetBlobAssetRefOffsetsPointer();

            var managedObjectBlobs         = new ManagedObjectBlobs();
            var managedObjectBlobAssets    = new NativeList <BlobAssetPtr>(16, Allocator.Temp);
            var managedObjectBlobAssetsMap = new NativeHashMap <BlobAssetPtr, int>(16, Allocator.Temp);

            for (var chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++)
            {
                var chunk     = chunks[chunkIndex].m_Chunk;
                var archetype = chunk->Archetype;

                // skip this chunk only if we are _certain_ there are no blob asset refs.
                if (archetype->NumManagedComponents == 0 && archetype->NumSharedComponents == 0 && !archetype->ContainsBlobAssetRefs)
                {
                    continue;
                }

                var typesCount  = archetype->TypesCount;
                var entityCount = chunks[chunkIndex].Count;

                for (var unorderedTypeIndexInArchetype = 0; unorderedTypeIndexInArchetype < typesCount; unorderedTypeIndexInArchetype++)
                {
                    var typeIndexInArchetype = archetype->TypeMemoryOrder[unorderedTypeIndexInArchetype];

                    var componentTypeInArchetype = archetype->Types[typeIndexInArchetype];

                    if (componentTypeInArchetype.IsZeroSized)
                    {
                        continue;
                    }

                    var chunkBuffer         = chunk->Buffer;
                    var subArrayOffset      = archetype->Offsets[typeIndexInArchetype];
                    var componentArrayStart = chunkBuffer + subArrayOffset;

                    if (componentTypeInArchetype.IsManagedComponent)
                    {
                        var componentSize = archetype->SizeOfs[typeIndexInArchetype];
                        var end           = componentArrayStart + componentSize * entityCount;

                        for (var componentData = componentArrayStart; componentData < end; componentData += componentSize)
                        {
                            var managedComponentIndex = *(int *)componentData;
                            var managedComponentValue = managedComponentStore.GetManagedComponent(managedComponentIndex);

                            if (null != managedComponentValue)
                            {
                                managedObjectBlobs.GatherBlobAssetReferences(managedComponentValue, managedObjectBlobAssets, managedObjectBlobAssetsMap);
                            }
                        }
                    }
                    else
                    {
                        var typeInfo          = typeInfoPtr[componentTypeInArchetype.TypeIndex & TypeManager.ClearFlagsMask];
                        var blobAssetRefCount = typeInfo.BlobAssetRefOffsetCount;

                        if (blobAssetRefCount == 0)
                        {
                            continue;
                        }

                        var blobAssetRefOffsets = blobAssetRefOffsetPtr + typeInfo.BlobAssetRefOffsetStartIndex;

                        if (componentTypeInArchetype.IsBuffer)
                        {
                            var header      = (BufferHeader *)componentArrayStart;
                            var strideSize  = archetype->SizeOfs[typeIndexInArchetype];
                            var elementSize = typeInfo.ElementSize;

                            for (var entityIndex = 0; entityIndex < entityCount; entityIndex++)
                            {
                                var bufferStart = BufferHeader.GetElementPointer(header);
                                var bufferEnd   = bufferStart + header->Length * elementSize;

                                for (var componentData = bufferStart; componentData < bufferEnd; componentData += elementSize)
                                {
                                    AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash);
                                }

                                header = (BufferHeader *)(((byte *)header) + strideSize);
                            }
                        }
                        else
                        {
                            var componentSize = archetype->SizeOfs[typeIndexInArchetype];
                            var end           = componentArrayStart + componentSize * entityCount;

                            for (var componentData = componentArrayStart; componentData < end; componentData += componentSize)
                            {
                                AddBlobAssetsWithDistinctHash(componentData, blobAssetRefOffsets, blobAssetRefCount, blobAssetsWithDistinctHash);
                            }
                        }
                    }
                }
            }

            for (var chunkIndex = 0; chunkIndex < chunks.Length; chunkIndex++)
            {
                var chunk                 = chunks[chunkIndex].m_Chunk;
                var archetype             = chunk->Archetype;
                var sharedComponentValues = chunk->SharedComponentValues;

                for (var i = 0; i < archetype->NumSharedComponents; i++)
                {
                    var sharedComponentIndex = sharedComponentValues[i];

                    if (sharedComponentIndex == 0)
                    {
                        continue;
                    }

                    var sharedComponentValue = managedComponentStore.GetSharedComponentDataNonDefaultBoxed(sharedComponentIndex);
                    managedObjectBlobs.GatherBlobAssetReferences(sharedComponentValue, managedObjectBlobAssets, managedObjectBlobAssetsMap);
                }
            }

            for (var i = 0; i < managedObjectBlobAssets.Length; i++)
            {
                var blobAssetPtr = managedObjectBlobAssets[i];

                void *validationPtr = null;
                try
                {
                    // Try to read ValidationPtr, this might throw if the memory has been unmapped
                    validationPtr = blobAssetPtr.Header->ValidationPtr;
                }
                catch (Exception)
                {
                    // Ignored
                }

                if (validationPtr != blobAssetPtr.Data)
                {
                    continue;
                }

                blobAssetsWithDistinctHash.TryAdd(blobAssetPtr);
            }

            managedObjectBlobAssets.Dispose();
            managedObjectBlobAssetsMap.Dispose();

            new SortBlobAssetPtr
            {
                Array = blobAssetsWithDistinctHash.BlobAssets.AsDeferredJobArray()
            }.Run();

            return(blobAssetsWithDistinctHash);
        }