void *ChunkAllocate <T>(int count = 1, void *source = null) where T : struct
        {
            var bytes = count * UnsafeUtility.SizeOf <T>();

            if (bytes == 0)
            {
                return(null);
            }
            var pointer = m_GroupDataChunkAllocator.Allocate(bytes, UnsafeUtility.AlignOf <T>());

            if (source != null)
            {
                UnsafeUtility.MemCpy(pointer, source, bytes);
            }
            return(pointer);
        }
Beispiel #2
0
        ArchetypeQuery *CreateQuery(ComponentType *requiredTypes, int count)
        {
            var filter = (ArchetypeQuery *)m_GroupDataChunkAllocator.Allocate(sizeof(ArchetypeQuery), UnsafeUtility.AlignOf <ArchetypeQuery>());

            int noneCount = 0;
            int allCount  = 0;

            for (int i = 0; i != count; i++)
            {
                if (requiredTypes[i].AccessModeType == ComponentType.AccessMode.Subtractive)
                {
                    noneCount++;
                }
                else
                {
                    allCount++;
                }
            }

            filter->All      = (int *)m_GroupDataChunkAllocator.Allocate(sizeof(int) * allCount, UnsafeUtility.AlignOf <int>());
            filter->AllCount = allCount;

            filter->None      = (int *)m_GroupDataChunkAllocator.Allocate(sizeof(int) * noneCount, UnsafeUtility.AlignOf <int>());
            filter->NoneCount = noneCount;

            filter->Any      = null;
            filter->AnyCount = 0;

            noneCount = 0;
            allCount  = 0;
            for (int i = 0; i != count; i++)
            {
                if (requiredTypes[i].AccessModeType == ComponentType.AccessMode.Subtractive)
                {
                    filter->None[noneCount++] = requiredTypes[i].TypeIndex;
                }
                else
                {
                    filter->All[allCount++] = requiredTypes[i].TypeIndex;
                }
            }

            return(filter);
        }
        public ArchetypeManager(SharedComponentDataManager sharedComponentManager)
        {
            m_SharedComponentManager = sharedComponentManager;
            m_TypeLookup             = new NativeMultiHashMap <uint, IntPtr>(256, Allocator.Persistent);

            m_EmptyChunkPool = (UnsafeLinkedListNode *)m_ArchetypeChunkAllocator.Allocate(sizeof(UnsafeLinkedListNode),
                                                                                          UnsafeUtility.AlignOf <UnsafeLinkedListNode>());
            UnsafeLinkedListNode.InitializeList(m_EmptyChunkPool);

#if UNITY_ASSERTIONS
            // Buffer should be 16 byte aligned to ensure component data layout itself can gurantee being aligned
            var offset = UnsafeUtility.GetFieldOffset(typeof(Chunk).GetField("Buffer"));
            Assert.IsTrue(offset % 16 == 0, "Chunk buffer must be 16 byte aligned");
#endif
        }
Beispiel #4
0
        public ComponentGroup CreateEntityGroup(ArchetypeManager typeMan, EntityDataManager *entityDataManager,
                                                ComponentType *requiredTypes, int requiredCount)
        {
            var hash = HashUtility.Fletcher32((ushort *)requiredTypes,
                                              requiredCount * sizeof(ComponentType) / sizeof(short));
            var grp = GetCachedGroupData(hash, requiredTypes, requiredCount);

            if (grp != null)
            {
                return(new ComponentGroup(grp, m_JobSafetyManager, typeMan, entityDataManager));
            }

            m_JobSafetyManager.CompleteAllJobsAndInvalidateArrays();

            grp             = (EntityGroupData *)m_GroupDataChunkAllocator.Allocate(sizeof(EntityGroupData), 8);
            grp->PrevGroup  = m_LastGroupData;
            m_LastGroupData = grp;
            grp->RequiredComponentsCount = requiredCount;
            grp->RequiredComponents      =
                (ComponentType *)m_GroupDataChunkAllocator.Construct(sizeof(ComponentType) * requiredCount, 4,
                                                                     requiredTypes);

            grp->ReaderTypesCount = 0;
            grp->WriterTypesCount = 0;

            grp->SubtractiveComponentsCount = 0;

            for (var i = 0; i != requiredCount; i++)
            {
                if (requiredTypes[i].AccessModeType == ComponentType.AccessMode.Subtractive)
                {
                    grp->SubtractiveComponentsCount++;
                }
                if (!requiredTypes[i].RequiresJobDependency)
                {
                    continue;
                }
                switch (requiredTypes[i].AccessModeType)
                {
                case ComponentType.AccessMode.ReadOnly:
                    grp->ReaderTypesCount++;
                    break;

                default:
                    grp->WriterTypesCount++;
                    break;
                }
            }

            grp->ReaderTypes = (int *)m_GroupDataChunkAllocator.Allocate(sizeof(int) * grp->ReaderTypesCount, 4);
            grp->WriterTypes = (int *)m_GroupDataChunkAllocator.Allocate(sizeof(int) * grp->WriterTypesCount, 4);

            var curReader = 0;
            var curWriter = 0;

            for (var i = 0; i != requiredCount; i++)
            {
                if (!requiredTypes[i].RequiresJobDependency)
                {
                    continue;
                }
                switch (requiredTypes[i].AccessModeType)
                {
                case ComponentType.AccessMode.ReadOnly:
                    grp->ReaderTypes[curReader++] = requiredTypes[i].TypeIndex;
                    break;

                default:
                    grp->WriterTypes[curWriter++] = requiredTypes[i].TypeIndex;
                    break;
                }
            }

            grp->RequiredComponents =
                (ComponentType *)m_GroupDataChunkAllocator.Construct(sizeof(ComponentType) * requiredCount, 4,
                                                                     requiredTypes);

            grp->FirstMatchingArchetype = null;
            grp->LastMatchingArchetype  = null;
            for (var type = typeMan.m_LastArchetype; type != null; type = type->PrevArchetype)
            {
                AddArchetypeIfMatching(type, grp);
            }
            m_GroupLookup.Add(hash, (IntPtr)grp);
            return(new ComponentGroup(grp, m_JobSafetyManager, typeMan, entityDataManager));
        }