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); } }
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); } }