private JobHandle SchedulePersistJobs(JobHandle inputDeps, PersistentDataContainer dataContainer, ComponentTypeHandle <PersistenceState> persistenceStateTypeHandle)
        {
            var returnJobHandle = inputDeps;

            for (int persistenceArchetypeIndex = 0; persistenceArchetypeIndex < dataContainer.DataLayoutCount; persistenceArchetypeIndex++)
            {
                PersistencyArchetypeDataLayout dataLayout = dataContainer.GetDataLayoutAtIndex(persistenceArchetypeIndex);
                ref BlobArray <PersistencyArchetypeDataLayout.TypeInfo> typeInfoArray = ref dataLayout.PersistedTypeInfoArrayRef.Value;

                PersistencyContainerTag containerTag = new PersistencyContainerTag {
                    DataIdentifier = dataContainer.DataIdentifier
                };
                PersistableTypeCombinationHash persistableTypeCombinationHash = new PersistableTypeCombinationHash {
                    Value = dataLayout.PersistableTypeHandleCombinationHash
                };

                for (int typeInfoIndex = 0; typeInfoIndex < typeInfoArray.Length; typeInfoIndex++)
                {
                    // type info
                    PersistencyArchetypeDataLayout.TypeInfo typeInfo = typeInfoArray[typeInfoIndex];
                    ComponentType runtimeType = ComponentType.ReadOnly(PersistencySettings.GetTypeIndex(typeInfo.PersistableTypeHandle));
                    int           stride      = typeInfo.ElementSize * typeInfo.MaxElements + PersistenceMetaData.SizeOfStruct;
                    int           byteSize    = dataLayout.Amount * stride;

                    // query
                    var query = PersistableEntitiesQuery;
                    query.SetSharedComponentFilter(containerTag, persistableTypeCombinationHash);

                    JobHandle jobHandle;
                    if (typeInfo.IsBuffer)
                    {
                        jobHandle = new CopyBufferElementsToByteArray
                        {
                            BufferTypeHandle     = GetDynamicComponentTypeHandle(runtimeType),
                            MaxElements          = typeInfo.MaxElements,
                            PersistenceStateType = persistenceStateTypeHandle,
                            RawContainerData     = dataContainer.GetRawData(),
                            SubArrayOffset       = dataLayout.Offset + typeInfo.Offset,
                            SubArrayByteSize     = byteSize,
                            ElementSize          = typeInfo.ElementSize
                        }.Schedule(query, inputDeps);
                    }
                    else
                    {
                        jobHandle = new CopyComponentDataToByteArray()
                        {
                            ComponentTypeHandle  = GetDynamicComponentTypeHandle(runtimeType),
                            TypeSize             = typeInfo.ElementSize,
                            PersistenceStateType = persistenceStateTypeHandle,
                            RawContainerData     = dataContainer.GetRawData(),
                            SubArrayOffset       = dataLayout.Offset + typeInfo.Offset,
                            SubArrayByteSize     = byteSize
                        }.Schedule(query, inputDeps);
                    }

                    query.ResetFilter();
                    returnJobHandle = JobHandle.CombineDependencies(returnJobHandle, jobHandle);
                }
            }
Exemplo n.º 2
0
        private unsafe void InitSceneSection(SceneSection sceneSection)
        {
            Hash128 containerIdentifier          = sceneSection.SceneGUID;
            PersistencyContainerTag containerTag = new PersistencyContainerTag()
            {
                DataIdentifier = containerIdentifier
            };

            if (PersistentDataStorage.IsInitialized(containerIdentifier))
            {
                PersistentDataContainer latestState = PersistentDataStorage.GetReadContainerForLatestWriteIndex(containerIdentifier, out bool isInitial);
                _beginFrameSystem.RequestApply(latestState);
            }
            else
            {
                _scenePersistencyInfoQuery.SetSharedComponentFilter(containerTag);
                if (_scenePersistencyInfoQuery.CalculateEntityCount() != 1)
                {
                    return;
                }
                var scenePersistencyInfoRef        = _scenePersistencyInfoQuery.GetSingleton <ScenePersistencyInfoRef>();
                ref ScenePersistencyInfo sceneInfo = ref scenePersistencyInfoRef.InfoRef.Value;

                int offset      = 0;
                var dataLayouts = new NativeArray <PersistencyArchetypeDataLayout>(sceneInfo.PersistencyArchetypes.Length, Allocator.Persistent);
                for (var i = 0; i < sceneInfo.PersistencyArchetypes.Length; i++)
                {
                    ref PersistencyArchetype persistencyArchetype = ref sceneInfo.PersistencyArchetypes[i];

                    var hashFilter = new PersistableTypeCombinationHash
                    {
                        Value = persistencyArchetype.PersistableTypeHandleCombinationHash
                    };

                    var dataLayout = new PersistencyArchetypeDataLayout()
                    {
                        Amount = persistencyArchetype.AmountEntities,
                        ArchetypeIndexInContainer = (ushort)i,
                        PersistedTypeInfoArrayRef = persistencyArchetype.BuildTypeInfoBlobAsset(PersistencySettings, persistencyArchetype.AmountEntities, out int sizePerEntity),
                        SizePerEntity             = sizePerEntity,
                        Offset = offset,
                        PersistableTypeHandleCombinationHash = hashFilter.Value
                    };
                    offset += persistencyArchetype.AmountEntities * sizePerEntity;

                    dataLayouts[i] = dataLayout;
                }

                // BlobData is disposed if the owning entity is destroyed, we need this data even if the scene is unloaded
                NativeArray <PersistableTypeHandle> allUniqueTypeHandles = new NativeArray <PersistableTypeHandle>(sceneInfo.AllUniqueTypeHandles.Length, Allocator.Persistent);
                UnsafeUtility.MemCpy(allUniqueTypeHandles.GetUnsafePtr(), sceneInfo.AllUniqueTypeHandles.GetUnsafePtr(), allUniqueTypeHandles.Length * sizeof(PersistableTypeHandle));

                // this function takes ownership over the dataLayouts array & allUniqueTypeHandles array
                PersistentDataStorage.InitializeSceneContainer(containerIdentifier, dataLayouts, allUniqueTypeHandles,
                                                               out PersistentDataContainer initialStateContainer, out PersistentDataContainer containerToApply);
                _beginFrameSystem.RequestInitialStatePersist(initialStateContainer);
                if (containerToApply.IsCreated)
                {
                    // containerToApply only exists if it was already added as uninitialized raw data beforehand (e.g. read from disk)
                    _beginFrameSystem.RequestApply(containerToApply);
                }
            }