internal void MoveChunksFromAll(
            NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping,
            EntityComponentStore *srcEntityComponentStore,
            ManagedComponentStore srcManagedComponentStore)
        {
            var access = GetCheckedEntityDataAccess();
            var ecs    = access->EntityComponentStore;
            var mcs    = access->ManagedComponentStore;

            var moveChunksJob = new MoveAllChunksJob
            {
                srcEntityComponentStore = srcEntityComponentStore,
                dstEntityComponentStore = ecs,
                entityRemapping         = entityRemapping
            }.Schedule();

            int managedComponentCount                       = srcEntityComponentStore->ManagedComponentIndexUsedCount;
            NativeArray <int> srcManagedIndices             = default;
            NativeArray <int> dstManagedIndices             = default;
            JobHandle         gatherManagedComponentIndices = default;

            if (managedComponentCount > 0)
            {
                srcManagedIndices = new NativeArray <int>(managedComponentCount, Allocator.TempJob);
                dstManagedIndices = new NativeArray <int>(managedComponentCount, Allocator.TempJob);
                ecs->ReserveManagedComponentIndices(managedComponentCount);
                gatherManagedComponentIndices = new
                                                GatherAllManagedComponentIndicesJob
                {
                    SrcEntityComponentStore = srcEntityComponentStore,
                    DstEntityComponentStore = ecs,
                    SrcManagedIndices       = srcManagedIndices,
                    DstManagedIndices       = dstManagedIndices
                }.Schedule();
            }

            JobHandle.ScheduleBatchedJobs();

            int chunkCount = 0;

            for (var i = 0; i < srcEntityComponentStore->m_Archetypes.Length; ++i)
            {
                var srcArchetype = srcEntityComponentStore->m_Archetypes.Ptr[i];
                chunkCount += srcArchetype->Chunks.Count;
            }

            var remapChunks     = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob);
            var remapArchetypes = new NativeArray <RemapArchetype>(srcEntityComponentStore->m_Archetypes.Length, Allocator.TempJob);

            int chunkIndex     = 0;
            int archetypeIndex = 0;

            for (var i = 0; i < srcEntityComponentStore->m_Archetypes.Length; ++i)
            {
                var srcArchetype = srcEntityComponentStore->m_Archetypes.Ptr[i];
                if (srcArchetype->Chunks.Count != 0)
                {
                    var dstArchetype = ecs->GetOrCreateArchetype(srcArchetype->Types,
                                                                 srcArchetype->TypesCount);

                    remapArchetypes[archetypeIndex] = new RemapArchetype
                    {
                        srcArchetype = srcArchetype, dstArchetype = dstArchetype
                    };

                    srcEntityComponentStore->m_ChunkListChangesTracker.TrackArchetype(srcArchetype);
                    ecs->m_ChunkListChangesTracker.TrackArchetype(srcArchetype);

                    for (var j = 0; j < srcArchetype->Chunks.Count; ++j)
                    {
                        var srcChunk = srcArchetype->Chunks[j];
                        remapChunks[chunkIndex] = new RemapChunk {
                            chunk = srcChunk, dstArchetype = dstArchetype
                        };
                        chunkIndex++;
                    }

                    archetypeIndex++;
                    ecs->IncrementComponentTypeOrderVersion(dstArchetype);
                }
            }

            moveChunksJob.Complete();

            mcs.Playback(ref ecs->ManagedChangesTracker);
            srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker);

            k_ProfileMoveSharedComponents.Begin();
            var remapShared = mcs.MoveAllSharedComponents(srcManagedComponentStore, Allocator.TempJob);

            k_ProfileMoveSharedComponents.End();

            gatherManagedComponentIndices.Complete();

            k_ProfileMoveManagedComponents.Begin();
            mcs.MoveManagedComponentsFromDifferentWorld(srcManagedIndices, dstManagedIndices, srcManagedIndices.Length, srcManagedComponentStore);
            srcEntityComponentStore->m_ManagedComponentFreeIndex.Length = 0;
            srcEntityComponentStore->m_ManagedComponentIndex            = 1;
            k_ProfileMoveManagedComponents.End();

            new ChunkPatchEntities
            {
                RemapChunks          = remapChunks,
                EntityRemapping      = entityRemapping,
                EntityComponentStore = ecs
            }.Run();

            var remapAllChunksJob = new RemapAllChunksJob
            {
                dstEntityComponentStore = ecs,
                remapChunks             = remapChunks,
                entityRemapping         = entityRemapping
            }.Schedule(remapChunks.Length, 1);

            var remapArchetypesJob = new RemapAllArchetypesJob
            {
                remapArchetypes         = remapArchetypes,
                remapShared             = remapShared,
                dstEntityComponentStore = ecs,
                chunkHeaderType         = TypeManager.GetTypeIndex <ChunkHeader>()
            }.Schedule(archetypeIndex, 1, remapAllChunksJob);

            mcs.Playback(ref ecs->ManagedChangesTracker);

            if (managedComponentCount > 0)
            {
                srcManagedIndices.Dispose();
                dstManagedIndices.Dispose();
            }

            remapArchetypesJob.Complete();
            remapShared.Dispose();
            remapChunks.Dispose();
        }
Beispiel #2
0
 public BufferFromEntity <T> GetBufferFromEntity <T>(bool isReadOnly = false)
     where T : struct, IBufferElementData
 {
     return(GetBufferFromEntity <T>(TypeManager.GetTypeIndex <T>(), isReadOnly));
 }
Beispiel #3
0
        public DynamicBuffer <T> GetBuffer <T>(Entity entity) where T : struct, IBufferElementData
        {
            var typeIndex = TypeManager.GetTypeIndex <T>();

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            Entities->AssertEntityHasComponent(entity, typeIndex);
            if (TypeManager.GetTypeInfo <T>().Category != TypeManager.TypeCategory.BufferData)
            {
                throw new ArgumentException(
                          $"GetBuffer<{typeof(T)}> may not be IComponentData or ISharedComponentData; currently {TypeManager.GetTypeInfo<T>().Category}");
            }
#endif

            ComponentJobSafetyManager.CompleteReadAndWriteDependency(typeIndex);

            BufferHeader *header = (BufferHeader *)Entities->GetComponentDataWithTypeRW(entity, typeIndex, Entities->GlobalSystemVersion);

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            return(new DynamicBuffer <T>(header, ComponentJobSafetyManager.GetSafetyHandle(typeIndex, false), ComponentJobSafetyManager.GetBufferSafetyHandle(typeIndex), false));
#else
            return(new DynamicBuffer <T>(header));
#endif
        }
        public static ComponentType ChunkComponentReadOnly <T>()
        {
            var typeIndex = TypeManager.MakeChunkComponentTypeIndex(TypeManager.GetTypeIndex <T>());

            return(ReadOnly(typeIndex));
        }
 public TypeHeapElement(int index, Type t)
 {
     unsortedIndex = index;
     typeName      = TypeManager.SystemName(t);
 }
 public Type GetManagedType()
 {
     return(TypeManager.GetType(TypeIndex));
 }
 public static ComponentType ReadWrite(Type type)
 {
     return(FromTypeIndex(TypeManager.GetTypeIndex(type)));
 }
        public int GetSharedComponentVersion <T>(T sharedData) where T : struct
        {
            var index = FindSharedComponentIndex(TypeManager.GetTypeIndex <T>(), sharedData);

            return(index == -1 ? 0 : m_SharedComponentVersion[index]);
        }
Beispiel #9
0
        internal void GetIndexFromEntity(out IndexFromEntity output)
        {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            output = new IndexFromEntity(m_ComponentGroupData, m_SafetyManager.GetSafetyHandle(TypeManager.GetTypeIndex <Entity>(), true));
#else
            output = new IndexFromEntity(m_ComponentGroupData);
#endif
        }
 public FixedArrayFromEntity <T> GetFixedArrayFromEntity <T>(bool isReadOnly = false) where T : struct
 {
     AddReaderWriter(isReadOnly ? ComponentType.ReadOnly <T>() : ComponentType.Create <T>());
     return(EntityManager.GetFixedArrayFromEntity <T>(TypeManager.GetTypeIndex <T>(), isReadOnly));
 }
        void CheckJobDependencies(int type, bool isReading, JobHandle dependency)
        {
            var h = m_SafetyManager.GetSafetyHandle(type, true);

            unsafe
            {
                if (!isReading)
                {
                    var        readerCount = AtomicSafetyHandle.GetReaderArray(h, 0, IntPtr.Zero);
                    JobHandle *readers     = stackalloc JobHandle[readerCount];
                    AtomicSafetyHandle.GetReaderArray(h, readerCount, (IntPtr)readers);

                    for (var i = 0; i < readerCount; ++i)
                    {
                        if (!JobHandle.CheckFenceIsDependencyOrDidSyncFence(readers[i], dependency))
                        {
                            throw new InvalidOperationException($"The system {GetType()} reads {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetReaderName(h, i)} but that type was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
                        }
                    }
                }

                var writer = AtomicSafetyHandle.GetWriter(h);
                if (!JobHandle.CheckFenceIsDependencyOrDidSyncFence(writer, dependency))
                {
                    throw new InvalidOperationException($"The system {GetType()} writes {TypeManager.GetType(type)} via {AtomicSafetyHandle.GetWriterName(h)} but that was not returned as a job dependency. To ensure correct behavior of other systems, the job or a dependency of it must be returned from the OnUpdate method.");
                }
            }
        }
        public static void ReplicateComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count, ref EntityComponentStore entityComponentStore)
        {
            var srcArchetype        = srcChunk->Archetype;
            var srcBuffer           = srcChunk->Buffer;
            var dstBuffer           = dstChunk->Buffer;
            var dstArchetype        = dstChunk->Archetype;
            var srcOffsets          = srcArchetype->Offsets;
            var srcSizeOfs          = srcArchetype->SizeOfs;
            var srcBufferCapacities = srcArchetype->BufferCapacities;
            var srcTypes            = srcArchetype->Types;
            var dstTypes            = dstArchetype->Types;
            var dstOffsets          = dstArchetype->Offsets;
            var dstTypeIndex        = 1;

            var nativeComponentsEnd = srcArchetype->NativeComponentsEnd;

            for (var srcTypeIndex = 1; srcTypeIndex != nativeComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                var srcSizeOf = srcSizeOfs[srcTypeIndex];
                var src       = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex);
                var dst       = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex);

                UnsafeUtility.MemCpyReplicate(dst, src, srcSizeOf, count);
                dstTypeIndex++;
            }

            dstTypeIndex = dstArchetype->FirstBufferComponent;
            var bufferComponentsEnd = srcArchetype->BufferComponentsEnd;

            for (var srcTypeIndex = srcArchetype->FirstBufferComponent; srcTypeIndex != bufferComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                var srcSizeOf = srcSizeOfs[srcTypeIndex];
                var src       = srcBuffer + (srcOffsets[srcTypeIndex] + srcSizeOf * srcIndex);
                var dst       = dstBuffer + (dstOffsets[dstTypeIndex] + srcSizeOf * dstBaseIndex);

                var srcBufferCapacity = srcBufferCapacities[srcTypeIndex];
                var alignment         = 8; // TODO: Need a way to compute proper alignment for arbitrary non-generic types in TypeManager
                var elementSize       = TypeManager.GetTypeInfo(srcType.TypeIndex).ElementSize;
                for (int i = 0; i < count; ++i)
                {
                    BufferHeader *srcHdr = (BufferHeader *)src;
                    BufferHeader *dstHdr = (BufferHeader *)dst;
                    BufferHeader.Initialize(dstHdr, srcBufferCapacity);
                    BufferHeader.Assign(dstHdr, BufferHeader.GetElementPointer(srcHdr), srcHdr->Length, elementSize, alignment, false, 0);

                    dst += srcSizeOf;
                }

                dstTypeIndex++;
            }

            if (dstArchetype->NumManagedComponents > 0)
            {
                ReplicateManagedComponents(srcChunk, srcIndex, dstChunk, dstBaseIndex, count, ref entityComponentStore);
            }
        }
        public static void ReplicateManagedComponents(Chunk *srcChunk, int srcIndex, Chunk *dstChunk, int dstBaseIndex, int count, ref EntityComponentStore entityComponentStore)
        {
            var dstArchetype   = dstChunk->Archetype;
            var srcArchetype   = srcChunk->Archetype;
            var srcTypes       = srcArchetype->Types;
            var dstTypes       = dstArchetype->Types;
            var srcOffsets     = srcArchetype->Offsets;
            var dstOffsets     = dstArchetype->Offsets;
            int componentCount = dstArchetype->NumManagedComponents;

            int nonNullManagedComponents = 0;
            int nonNullHybridComponents  = 0;
            var componentIndices         = stackalloc int[componentCount];
            var componentDstArrayStart   = stackalloc IntPtr[componentCount];

            var firstDstManagedComponent = dstArchetype->FirstManagedComponent;
            var dstTypeIndex             = firstDstManagedComponent;
            var managedComponentsEnd     = srcArchetype->ManagedComponentsEnd;
            var srcBaseAddr = srcChunk->Buffer + sizeof(int) * srcIndex;
            var dstBaseAddr = dstChunk->Buffer + sizeof(int) * dstBaseIndex;

            bool hasHybridComponents = dstArchetype->HasHybridComponents;

            for (var srcTypeIndex = srcArchetype->FirstManagedComponent; srcTypeIndex != managedComponentsEnd; srcTypeIndex++)
            {
                var srcType = srcTypes[srcTypeIndex];
                var dstType = dstTypes[dstTypeIndex];
                // Type does not exist in destination. Skip it.
                if (srcType.TypeIndex != dstType.TypeIndex)
                {
                    continue;
                }
                int srcManagedComponentIndex = *(int *)(srcBaseAddr + srcOffsets[srcTypeIndex]);
                var dstArrayStart            = dstBaseAddr + dstOffsets[dstTypeIndex];

                if (srcManagedComponentIndex == 0)
                {
                    UnsafeUtility.MemClear(dstArrayStart, sizeof(int) * count);
                }
                else
                {
                    if (hasHybridComponents && TypeManager.GetTypeInfo(srcType.TypeIndex).Category == TypeManager.TypeCategory.Class)
                    {
                        //Hybrid component, put at end of array
                        var index = componentCount - nonNullHybridComponents - 1;
                        componentIndices[index]       = srcManagedComponentIndex;
                        componentDstArrayStart[index] = (IntPtr)dstArrayStart;
                        ++nonNullHybridComponents;
                    }
                    else
                    {
                        componentIndices[nonNullManagedComponents]       = srcManagedComponentIndex;
                        componentDstArrayStart[nonNullManagedComponents] = (IntPtr)dstArrayStart;
                        ++nonNullManagedComponents;
                    }
                }

                dstTypeIndex++;
            }

            entityComponentStore.ReserveManagedComponentIndices(count * (nonNullManagedComponents + nonNullHybridComponents));
            entityComponentStore.ManagedChangesTracker.CloneManagedComponentBegin(componentIndices, nonNullManagedComponents, count);
            for (int c = 0; c < nonNullManagedComponents; ++c)
            {
                var dst = (int *)(componentDstArrayStart[c]);
                entityComponentStore.AllocateManagedComponentIndices(dst, count);
                entityComponentStore.ManagedChangesTracker.CloneManagedComponentAddDstIndices(dst, count);
            }

            if (hasHybridComponents)
            {
                var dstEntities = (Entity *)dstChunk->Buffer + dstBaseIndex;
                entityComponentStore.ManagedChangesTracker.CloneHybridComponentBegin(
                    componentIndices + componentCount - nonNullHybridComponents, nonNullHybridComponents, dstEntities, count);
                for (int c = componentCount - nonNullHybridComponents; c < componentCount; ++c)
                {
                    var dst = (int *)(componentDstArrayStart[c]);
                    entityComponentStore.AllocateManagedComponentIndices(dst, count);
                    entityComponentStore.ManagedChangesTracker.CloneHybridComponentAddDstIndices(dst, count);
                }
            }
        }
Beispiel #14
0
        public static void InitializeSystems(World world)
        {
            var allSystemTypes = TypeManager.GetSystems();
            var allSystemNames = TypeManager.SystemNames;

            if (allSystemTypes.Length == 0)
            {
                throw new InvalidOperationException("DefaultTinyWorldInitialization: No Systems found.");
            }

            // Create top level presentation system and simulation systems.
            InitializationSystemGroup initializationSystemGroup = new InitializationSystemGroup();

            world.AddManager(initializationSystemGroup);

            SimulationSystemGroup simulationSystemGroup = new SimulationSystemGroup();

            world.AddManager(simulationSystemGroup);

            PresentationSystemGroup presentationSystemGroup = new PresentationSystemGroup();

            world.AddManager(presentationSystemGroup);

            // Create the working set of systems.
            int nSystems = 0;

            Type[]            systemTypes = new Type[allSystemTypes.Length];
            ComponentSystem[] systems     = new ComponentSystem[allSystemTypes.Length];

#if WRITE_LOG
            Console.WriteLine("--- Adding systems:");
#endif

            for (int i = 0; i < allSystemTypes.Length; i++)
            {
                if (TypeManager.GetSystemAttributes(allSystemTypes[i], typeof(DisableAutoCreationAttribute)).Length > 0)
                {
                    continue;
                }
                if (allSystemTypes[i] == initializationSystemGroup.GetType() ||
                    allSystemTypes[i] == simulationSystemGroup.GetType() ||
                    allSystemTypes[i] == presentationSystemGroup.GetType())
                {
                    continue;
                }

                if (world.GetExistingManager(allSystemTypes[i]) != null)
                {
                    continue;
                }
#if WRITE_LOG
                Console.WriteLine(allSystemNames[i]);
#endif
                systemTypes[nSystems] = allSystemTypes[i];
                systems[nSystems]     = TypeManager.ConstructSystem(allSystemTypes[i]);
                world.AddManager(systems[nSystems]);
                nSystems++;
            }
#if WRITE_LOG
            Console.WriteLine("--- Adding systems Done.");
#endif

            for (int i = 0; i < nSystems; ++i)
            {
                var sysType = systemTypes[i];
                var system  = systems[i];

                var groups = TypeManager.GetSystemAttributes(sysType, typeof(UpdateInGroupAttribute));
                if (groups.Length == 0)
                {
                    simulationSystemGroup.AddSystemToUpdateList(system);
                }

                for (int g = 0; g < groups.Length; ++g)
                {
                    var groupType   = groups[g] as UpdateInGroupAttribute;
                    var groupSystem = world.GetExistingManager(groupType.GroupType) as ComponentSystemGroup;
                    if (groupSystem == null)
                    {
                        throw new Exception("DefaultTinyWorldInitialization failed to find existing SystemGroup.");
                    }

                    groupSystem.AddSystemToUpdateList(system);
                }
            }
        }
 public static ComponentType Exclude <T>()
 {
     return(Exclude(TypeManager.GetTypeIndex <T>()));
 }
Beispiel #16
0
        internal void GetEntityArray(ref ComponentChunkIterator iterator, int length, out EntityArray output)
        {
            iterator.IndexInComponentGroup = 0;
#if ENABLE_UNITY_COLLECTIONS_CHECKS
            //@TODO: Comment on why this has to be false...
            output = new EntityArray(iterator, length, m_SafetyManager.GetSafetyHandle(TypeManager.GetTypeIndex <Entity>(), false));
#else
            output = new EntityArray(iterator, length);
#endif
        }
 public ComponentType(Type type, AccessMode accessModeType = AccessMode.ReadWrite)
 {
     TypeIndex      = TypeManager.GetTypeIndex(type);
     AccessModeType = accessModeType;
 }
Beispiel #18
0
        public static unsafe TransformAccessArray GetTransformAccessArray(this EntityQuery group)
        {
            var state        = (TransformAccessArrayState?)group._CachedState ?? new TransformAccessArrayState();
            var orderVersion = group._EntityComponentStore->GetComponentTypeOrderVersion(TypeManager.GetTypeIndex <Transform>());

            if (state.Data.isCreated && orderVersion == state.OrderVersion)
            {
                return(state.Data);
            }

            state.OrderVersion = orderVersion;

            UnityEngine.Profiling.Profiler.BeginSample("DirtyTransformAccessArrayUpdate");
            var trans = group.ToComponentArray <Transform>();

            if (!state.Data.isCreated)
            {
                state.Data = new TransformAccessArray(trans);
            }
            else
            {
                state.Data.SetTransforms(trans);
            }
            UnityEngine.Profiling.Profiler.EndSample();

            group._CachedState = state;

            return(state.Data);
        }
 public static ComponentType ReadWrite <T>()
 {
     return(FromTypeIndex(TypeManager.GetTypeIndex <T>()));
 }
Beispiel #20
0
 public ComponentType(Type type, AccessMode accessModeType = AccessMode.ReadWrite)
 {
     TypeIndex           = TypeManager.GetTypeIndex(type);
     this.AccessModeType = accessModeType;
     FixedArrayLength    = -1;
 }
        public static ComponentType ChunkComponent <T>()
        {
            var typeIndex = TypeManager.MakeChunkComponentTypeIndex(TypeManager.GetTypeIndex <T>());

            return(FromTypeIndex(typeIndex));
        }
        /// <summary>
        /// Adds the collection of systems to the world by injecting them into the root level system groups
        /// (InitializationSystemGroup, SimulationSystemGroup and PresentationSystemGroup)
        /// </summary>
        public static void AddSystemsToRootLevelSystemGroups(World world, params Type[] systemTypes)
        {
            var initializationSystemGroup = world.GetOrCreateSystem <InitializationSystemGroup>();
            var simulationSystemGroup     = world.GetOrCreateSystem <SimulationSystemGroup>();
            var presentationSystemGroup   = world.GetOrCreateSystem <PresentationSystemGroup>();

            var systems = world.GetOrCreateSystemsAndLogException(systemTypes.ToArray());

            // Add systems to their groups, based on the [UpdateInGroup] attribute.
            foreach (var system in systems)
            {
                if (system == null)
                {
                    continue;
                }

                // Skip the built-in root-level system groups
                var type = system.GetType();
                if (type == typeof(InitializationSystemGroup) ||
                    type == typeof(SimulationSystemGroup) ||
                    type == typeof(PresentationSystemGroup))
                {
                    continue;
                }

                var groups = TypeManager.GetSystemAttributes(system.GetType(), typeof(UpdateInGroupAttribute));
                if (groups.Length == 0)
                {
                    simulationSystemGroup.AddSystemToUpdateList(system);
                }

                foreach (var g in groups)
                {
                    var group = g as UpdateInGroupAttribute;
                    if (group == null)
                    {
                        continue;
                    }

                    if (!TypeManager.IsSystemAGroup(group.GroupType))
                    {
                        Debug.LogError($"Invalid [UpdateInGroup] attribute for {type}: {group.GroupType} must be derived from ComponentSystemGroup.");
                        continue;
                    }

                    var groupMgr = world.GetExistingSystem(group.GroupType);
                    if (groupMgr == null)
                    {
                        // Warn against unexpected behaviour combining DisableAutoCreation and UpdateInGroup
                        var parentDisableAutoCreation = TypeManager.GetSystemAttributes(group.GroupType, typeof(DisableAutoCreationAttribute)).Length > 0;
                        if (parentDisableAutoCreation)
                        {
                            Debug.LogWarning($"A system {type} wants to execute in {group.GroupType} but this group has [DisableAutoCreation] and {type} does not. The system will not be added to any group and thus not update.");
                        }
                        else
                        {
                            Debug.LogWarning(
                                $"A system {type} could not be added to group {group.GroupType}, because the group was not created. Fix these errors before continuing. The system will not be added to any group and thus not update.");
                        }
                        continue;
                    }

                    var groupSys = groupMgr as ComponentSystemGroup;
                    if (groupSys != null)
                    {
                        groupSys.AddSystemToUpdateList(system);
                    }
                }
            }

            // Update player loop
            initializationSystemGroup.SortSystems();
            simulationSystemGroup.SortSystems();
            presentationSystemGroup.SortSystems();
        }
        public void CheckInternalConsistency()
        {
            // Iterate by archetype
            var entityCountByArchetype = 0;

            for (var i = 0; i < m_Archetypes.Length; ++i)
            {
                var archetype = m_Archetypes.Ptr[i];

                var countInArchetype = 0;
                for (var j = 0; j < archetype->Chunks.Count; ++j)
                {
                    var chunk = archetype->Chunks.p[j];
                    Assert.IsTrue(chunk->Archetype == archetype);
                    Assert.IsTrue(chunk->Capacity >= chunk->Count);
                    Assert.AreEqual(chunk->Count, archetype->Chunks.GetChunkEntityCount(j));

                    var chunkEntities = (Entity *)chunk->Buffer;
                    AssertEntitiesExist(chunkEntities, chunk->Count);

                    if (!chunk->Locked)
                    {
                        if (chunk->Count < chunk->Capacity)
                        {
                            if (archetype->NumSharedComponents == 0)
                            {
                                Assert.IsTrue(chunk->ListWithEmptySlotsIndex >= 0 && chunk->ListWithEmptySlotsIndex <
                                              archetype->ChunksWithEmptySlots.Length);
                                Assert.IsTrue(
                                    chunk == archetype->ChunksWithEmptySlots.Ptr[chunk->ListWithEmptySlotsIndex]);
                            }
                            else
                            {
                                Assert.IsTrue(archetype->FreeChunksBySharedComponents.Contains(chunk));
                            }
                        }
                    }

                    countInArchetype += chunk->Count;

                    if (chunk->Archetype->HasChunkHeader) // Chunk entities with chunk components are not supported
                    {
                        Assert.IsFalse(chunk->Archetype->HasChunkComponents);
                    }

                    Assert.AreEqual(chunk->Archetype->HasChunkComponents, chunk->metaChunkEntity != Entity.Null);
                    if (chunk->metaChunkEntity != Entity.Null)
                    {
                        var chunkHeaderTypeIndex = TypeManager.GetTypeIndex <ChunkHeader>();
                        AssertEntitiesExist(&chunk->metaChunkEntity, 1);
                        AssertEntityHasComponent(chunk->metaChunkEntity, chunkHeaderTypeIndex);
                        var chunkHeader =
                            *(ChunkHeader *)GetComponentDataWithTypeRO(chunk->metaChunkEntity,
                                                                       chunkHeaderTypeIndex);
                        Assert.IsTrue(chunk == chunkHeader.ArchetypeChunk.m_Chunk);
                        var metaChunk = GetChunk(chunk->metaChunkEntity);
                        Assert.IsTrue(metaChunk->Archetype == chunk->Archetype->MetaChunkArchetype);
                    }
                }

                Assert.AreEqual(countInArchetype, archetype->EntityCount);

                entityCountByArchetype += countInArchetype;
            }

            // Iterate by free list
            Assert.IsTrue(m_EntityInChunkByEntity[m_NextFreeEntityIndex].Chunk == null);

            var entityCountByFreeList = EntitiesCapacity;
            int freeIndex             = m_NextFreeEntityIndex;

            while (freeIndex != -1)
            {
                Assert.IsTrue(m_EntityInChunkByEntity[freeIndex].Chunk == null);
                Assert.IsTrue(freeIndex < EntitiesCapacity);

                freeIndex = m_EntityInChunkByEntity[freeIndex].IndexInChunk;

                entityCountByFreeList--;
            }

            // iterate by entities
            var entityCountByEntities = 0;
            var entityType            = TypeManager.GetTypeIndex <Entity>();

            for (var i = 0; i != EntitiesCapacity; i++)
            {
                var chunk = m_EntityInChunkByEntity[i].Chunk;
                if (chunk == null)
                {
                    continue;
                }

                entityCountByEntities++;
                var archetype = m_ArchetypeByEntity[i];
                Assert.AreEqual((IntPtr)archetype, (IntPtr)chunk->Archetype);
                Assert.AreEqual(entityType, archetype->Types[0].TypeIndex);
                Assert.IsTrue(m_EntityInChunkByEntity[i].IndexInChunk < m_EntityInChunkByEntity[i].Chunk->Count);
                var entity = *(Entity *)ChunkDataUtility.GetComponentDataRO(m_EntityInChunkByEntity[i].Chunk,
                                                                            m_EntityInChunkByEntity[i].IndexInChunk, 0);
                Assert.AreEqual(i, entity.Index);
                Assert.AreEqual(m_VersionByEntity[i], entity.Version);

                Assert.IsTrue(Exists(entity));
            }


            Assert.AreEqual(entityCountByEntities, entityCountByArchetype);

            // Enabling this fails SerializeEntitiesWorksWithBlobAssetReferences.
            // There is some special entity 0 usage in the serialization code.

            // @TODO: Review with simon looks like a potential leak?
            //Assert.AreEqual(entityCountByEntities, entityCountByFreeList);
        }
        internal void FlushPendingBuffers(bool playBack)
        {
            m_ProducerHandle.Complete();
            m_ProducerHandle = new JobHandle();

            int length;

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            length = m_PendingBuffers.Count;
#else
            length = m_PendingBuffers.Length;
#endif

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            List <string> playbackErrorLog             = null;
            bool          completeAllJobsBeforeDispose = false;
#endif
            for (int i = 0; i < length; ++i)
            {
                var buffer = m_PendingBuffers[i];
                if (!buffer.IsCreated)
                {
                    continue;
                }
                if (playBack)
                {
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    try
                    {
                        var system     = GetSystemFromSystemID(World, buffer.SystemID);
                        var systemName = system != null?TypeManager.GetSystemName(system.GetType()) : "Unknown";

                        Profiler.BeginSample(systemName);
                        buffer.Playback(EntityManager);
                        Profiler.EndSample();
                    }
                    catch (Exception e)
                    {
                        var system     = GetSystemFromSystemID(World, buffer.SystemID);
                        var systemType = system != null?system.GetType().ToString() : "Unknown";

                        var error = $"{e.Message}\nEntityCommandBuffer was recorded in {systemType} and played back in {GetType()}.\n" + e.StackTrace;
                        if (playbackErrorLog == null)
                        {
                            playbackErrorLog = new List <string>();
                        }
                        playbackErrorLog.Add(error);
                        completeAllJobsBeforeDispose = true;
                    }
#else
                    buffer.Playback(EntityManager);
#endif
                }
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                try
                {
                    if (completeAllJobsBeforeDispose)
                    {
                        // If we get here, there was an error during playback (potentially a race condition on the
                        // buffer itself), and we should wait for all jobs writing to this command buffer to complete before attempting
                        // to dispose of the command buffer to prevent a potential race condition.
                        buffer.WaitForWriterJobs();
                        completeAllJobsBeforeDispose = false;
                    }
                    buffer.Dispose();
                }
                catch (Exception e)
                {
                    var system     = GetSystemFromSystemID(World, buffer.SystemID);
                    var systemType = system != null?system.GetType().ToString() : "Unknown";

                    var error = $"{e.Message}\nEntityCommandBuffer was recorded in {systemType} and disposed in {GetType()}.\n" + e.StackTrace;
                    if (playbackErrorLog == null)
                    {
                        playbackErrorLog = new List <string>();
                    }
                    playbackErrorLog.Add(error);
                }
#else
                buffer.Dispose();
#endif
                m_PendingBuffers[i] = buffer;
            }

#if ENABLE_UNITY_COLLECTIONS_CHECKS
            if (playbackErrorLog != null)
            {
#if !NET_DOTS
                var exceptionMessage = new StringBuilder();
                foreach (var err in playbackErrorLog)
                {
                    exceptionMessage.AppendLine(err);
                }
#else
                var exceptionMessage = "";
                foreach (var err in playbackErrorLog)
                {
                    exceptionMessage += err;
                    exceptionMessage += '\n';
                }
#endif

                throw new System.ArgumentException(exceptionMessage.ToString());
            }
#endif
        }
        public virtual void SortSystemUpdateList()
        {
#if !UNITY_CSHARP_TINY
            lookupDictionary = null;
#endif
            // Populate dictionary mapping systemType to system-and-before/after-types.
            // This is clunky - it is easier to understand, and cleaner code, to
            // just use a Dictionary<Type, SysAndDep>. However, Tiny doesn't currently have
            // the ability to use Type as a key to a NativeHash, so we're stuck until that gets addressed.
            //
            // Likewise, this is important shared code. It can be done cleaner with 2 versions, but then...
            // 2 sets of bugs and slightly different behavior will creep in.
            //
            var sysAndDep = new SysAndDep[m_systemsToUpdate.Count];

            for (int i = 0; i < m_systemsToUpdate.Count; ++i)
            {
                var sys = m_systemsToUpdate[i];
                if (TypeManager.IsSystemAGroup(sys.GetType()))
                {
                    (sys as ComponentSystemGroup).SortSystemUpdateList();
                }
                sysAndDep[i] = new SysAndDep
                {
                    system       = sys,
                    updateBefore = new List <Type>(),
                    nAfter       = 0,
                };
            }
            for (int i = 0; i < m_systemsToUpdate.Count; ++i)
            {
                var sys    = m_systemsToUpdate[i];
                var before = TypeManager.GetSystemAttributes(sys.GetType(), typeof(UpdateBeforeAttribute));
                var after  = TypeManager.GetSystemAttributes(sys.GetType(), typeof(UpdateAfterAttribute));
                foreach (var attr in before)
                {
                    var dep      = attr as UpdateBeforeAttribute;
                    int depIndex = LookupSysAndDep(dep.SystemType, sysAndDep);
                    if (depIndex < 0)
                    {
#if !UNITY_CSHARP_TINY
                        Debug.LogWarning("Ignoring invalid [UpdateBefore] dependency for " + sys.GetType() + ": " + dep.SystemType + " must be a member of the same ComponentSystemGroup.");
#else
                        Debug.LogWarning("WARNING: invalid [UpdateBefore] dependency:");
                        Debug.LogWarning(TypeManager.SystemName(sys.GetType()));
                        Debug.LogWarning("  depends on a non-sibling or non-ComponentSystem.");
#endif
                        continue;
                    }

                    sysAndDep[i].updateBefore.Add(dep.SystemType);
                    sysAndDep[depIndex].nAfter++;
                }
                foreach (var attr in after)
                {
                    var dep      = attr as UpdateAfterAttribute;
                    int depIndex = LookupSysAndDep(dep.SystemType, sysAndDep);
                    if (depIndex < 0)
                    {
#if !UNITY_CSHARP_TINY
                        Debug.LogWarning("Ignoring invalid [UpdateAfter] dependency for " + sys.GetType() + ": " + dep.SystemType + " must be a member of the same ComponentSystemGroup.");
#else
                        Debug.LogWarning("WARNING: invalid [UpdateAfter] dependency:");
                        Debug.LogWarning(TypeManager.SystemName(sys.GetType()));
                        Debug.LogWarning("  depends on a non-sibling or non-ComponentSystem.");
#endif
                        continue;
                    }
                    sysAndDep[depIndex].updateBefore.Add(sys.GetType());
                    sysAndDep[i].nAfter++;
                }
            }

            // Clear the systems list and rebuild it in sorted order from the lookup table
            var readySystems = new Heap <TypeHeapElement>(m_systemsToUpdate.Count);
            m_systemsToUpdate.Clear();
            for (int i = 0; i < sysAndDep.Length; ++i)
            {
                if (sysAndDep[i].nAfter == 0)
                {
                    readySystems.Insert(new TypeHeapElement(i, sysAndDep[i].system.GetType()));
                }
            }
            while (!readySystems.Empty)
            {
                int       sysIndex = readySystems.Extract().unsortedIndex;
                SysAndDep sd       = sysAndDep[sysIndex];
                Type      sysType  = sd.system.GetType();

                sysAndDep[sysIndex] = new SysAndDep();  // "Remove()"
                m_systemsToUpdate.Add(sd.system);
                foreach (var beforeType in sd.updateBefore)
                {
                    int beforeIndex = LookupSysAndDep(beforeType, sysAndDep);
                    if (beforeIndex < 0)
                    {
                        throw new Exception("Bug in SortSystemUpdateList(), beforeIndex < 0");
                    }
                    if (sysAndDep[beforeIndex].nAfter <= 0)
                    {
                        throw new Exception("Bug in SortSystemUpdateList(), nAfter <= 0");
                    }

                    sysAndDep[beforeIndex].nAfter--;
                    if (sysAndDep[beforeIndex].nAfter == 0)
                    {
                        readySystems.Insert(new TypeHeapElement(beforeIndex, sysAndDep[beforeIndex].system.GetType()));
                    }
                }
            }

            for (int i = 0; i < sysAndDep.Length; ++i)
            {
                if (sysAndDep[i].system != null)
                {
                    // Since no System in the circular dependency would have ever been added
                    // to the heap, we should have values for everything in sysAndDep. Check,
                    // just in case.
#if ENABLE_UNITY_COLLECTIONS_CHECKS
                    var visitedSystems = new List <ComponentSystemBase>();
                    var startIndex     = i;
                    var currentIndex   = i;
                    while (true)
                    {
                        if (sysAndDep[currentIndex].system != null)
                        {
                            visitedSystems.Add(sysAndDep[currentIndex].system);
                        }

                        currentIndex = LookupSysAndDep(sysAndDep[currentIndex].updateBefore[0], sysAndDep);
                        if (currentIndex < 0 || currentIndex == startIndex || sysAndDep[currentIndex].system == null)
                        {
                            throw new CircularSystemDependencyException(visitedSystems);
                        }
                    }
#else
                    sysAndDep[i] = new SysAndDep();
#endif
                }
            }
        }
        public static ComponentType ChunkComponentExclude(Type type)
        {
            var typeIndex = TypeManager.MakeChunkComponentTypeIndex(TypeManager.GetTypeIndex(type));

            return(Exclude(typeIndex));
        }
Beispiel #27
0
        internal void SetSharedComponentDataBoxed(Entity entity, int typeIndex, int hashCode, object componentData)
        {
            BeforeStructuralChange();

            Entities->AssertEntityHasComponent(entity, typeIndex);

            var newSharedComponentDataIndex = 0;

            if (componentData != null) // null means default
            {
                newSharedComponentDataIndex = m_SharedComponentManager.InsertSharedComponentAssumeNonDefault(typeIndex,
                                                                                                             hashCode, componentData, TypeManager.GetTypeInfo(typeIndex).FastEqualityTypeInfo);
            }

            Entities->SetSharedComponentDataIndex(ArchetypeManager, m_SharedComponentManager, entity, typeIndex,
                                                  newSharedComponentDataIndex);
            m_SharedComponentManager.RemoveReference(newSharedComponentDataIndex);
        }
 public static ComponentType Exclude(Type type)
 {
     return(Exclude(TypeManager.GetTypeIndex(type)));
 }
Beispiel #29
0
 public int GetComponentOrderVersion <T>()
 {
     return(Entities->GetComponentTypeOrderVersion(TypeManager.GetTypeIndex <T>()));
 }
        internal void MoveChunksFromFiltered(
            NativeArray <ArchetypeChunk> chunks,
            NativeArray <EntityRemapUtility.EntityRemapInfo> entityRemapping,
            EntityComponentStore *srcEntityComponentStore,
            ManagedComponentStore srcManagedComponentStore)
        {
            var access = GetCheckedEntityDataAccess();
            var ecs    = access->EntityComponentStore;
            var mcs    = access->ManagedComponentStore;

            new MoveChunksJob
            {
                srcEntityComponentStore = srcEntityComponentStore,
                dstEntityComponentStore = ecs,
                entityRemapping         = entityRemapping,
                chunks = chunks
            }.Run();

            int chunkCount  = chunks.Length;
            var remapChunks = new NativeArray <RemapChunk>(chunkCount, Allocator.TempJob);

            Archetype *previousSrcArchetypee = null;
            Archetype *dstArchetype          = null;
            int        managedComponentCount = 0;

            NativeList <IntPtr> managedChunks = new NativeList <IntPtr>(0, Allocator.TempJob);

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

                // Move Chunk World. ChangeVersion:Yes OrderVersion:Yes
                if (previousSrcArchetypee != archetype)
                {
                    dstArchetype = ecs->GetOrCreateArchetype(archetype->Types, archetype->TypesCount);
                }

                remapChunks[i] = new RemapChunk {
                    chunk = chunk, dstArchetype = dstArchetype
                };

                if (dstArchetype->NumManagedComponents > 0)
                {
                    managedComponentCount += chunk->Count * dstArchetype->NumManagedComponents;
                    managedChunks.Add((IntPtr)chunk);
                }

                if (archetype->MetaChunkArchetype != null)
                {
                    Entity srcEntity = chunk->metaChunkEntity;
                    Entity dstEntity;

                    ecs->CreateEntities(dstArchetype->MetaChunkArchetype, &dstEntity, 1);

                    var srcEntityInChunk = srcEntityComponentStore->GetEntityInChunk(srcEntity);
                    var dstEntityInChunk = ecs->GetEntityInChunk(dstEntity);

                    ChunkDataUtility.SwapComponents(srcEntityInChunk.Chunk, srcEntityInChunk.IndexInChunk, dstEntityInChunk.Chunk, dstEntityInChunk.IndexInChunk, 1,
                                                    srcEntityComponentStore->GlobalSystemVersion, ecs->GlobalSystemVersion);
                    EntityRemapUtility.AddEntityRemapping(ref entityRemapping, srcEntity, dstEntity);

                    srcEntityComponentStore->DestroyEntities(&srcEntity, 1);
                }
            }

            NativeArray <int> srcManagedIndices = default;
            NativeArray <int> dstManagedIndices = default;
            int nonNullManagedComponentCount    = 0;

            if (managedComponentCount > 0)
            {
                srcManagedIndices = new NativeArray <int>(managedComponentCount, Allocator.TempJob);
                dstManagedIndices = new NativeArray <int>(managedComponentCount, Allocator.TempJob);
                new
                GatherManagedComponentIndicesInChunkJob()
                {
                    SrcEntityComponentStore = srcEntityComponentStore,
                    DstEntityComponentStore = ecs,
                    SrcManagedIndices       = srcManagedIndices,
                    DstManagedIndices       = dstManagedIndices,
                    Chunks       = managedChunks,
                    NonNullCount = &nonNullManagedComponentCount
                }.Run();
            }

            mcs.Playback(ref ecs->ManagedChangesTracker);
            srcManagedComponentStore.Playback(ref srcEntityComponentStore->ManagedChangesTracker);

            k_ProfileMoveSharedComponents.Begin();
            var remapShared = mcs.MoveSharedComponents(srcManagedComponentStore, chunks, Allocator.TempJob);

            k_ProfileMoveSharedComponents.End();

            if (managedComponentCount > 0)
            {
                k_ProfileMoveManagedComponents.Begin();
                mcs.MoveManagedComponentsFromDifferentWorld(srcManagedIndices, dstManagedIndices, nonNullManagedComponentCount, srcManagedComponentStore);
                srcEntityComponentStore->m_ManagedComponentFreeIndex.Add(srcManagedIndices.GetUnsafeReadOnlyPtr(), sizeof(int) * srcManagedIndices.Length);
                k_ProfileMoveManagedComponents.End();
            }

            new ChunkPatchEntities
            {
                RemapChunks          = remapChunks,
                EntityRemapping      = entityRemapping,
                EntityComponentStore = ecs
            }.Run();

            var remapChunksJob = new RemapChunksFilteredJob
            {
                dstEntityComponentStore = ecs,
                remapChunks             = remapChunks,
                entityRemapping         = entityRemapping,
                chunkHeaderType         = TypeManager.GetTypeIndex <ChunkHeader>()
            }.Schedule(remapChunks.Length, 1);

            var moveChunksBetweenArchetypeJob = new MoveFilteredChunksBetweenArchetypexJob
            {
                RemapChunks         = remapChunks,
                RemapShared         = remapShared,
                GlobalSystemVersion = ecs->GlobalSystemVersion
            }.Schedule(remapChunksJob);

            moveChunksBetweenArchetypeJob.Complete();

            mcs.Playback(ref ecs->ManagedChangesTracker);

            if (managedComponentCount > 0)
            {
                srcManagedIndices.Dispose();
                dstManagedIndices.Dispose();
            }
            managedChunks.Dispose();
            remapShared.Dispose();
            remapChunks.Dispose();
        }