예제 #1
0
        // index -1 means 'use current index'
        public static void WriteContainerToDisk(this PersistentSceneSystem persistentSceneSystem, Hash128 containerIdentifier, bool initial = false, int index = -1)
        {
            Debug.Assert(initial == (index != -1), "Don't fill in an index if you want the initial container!");

            // Path
            string path       = CalculateStreamingAssetsPath(containerIdentifier);
            string folderPath = Path.GetDirectoryName(path);

            Debug.Assert(!string.IsNullOrEmpty(folderPath));
            if (!Directory.Exists(folderPath))
            {
                Directory.CreateDirectory(folderPath);
            }

            // Container
            PersistentDataStorage   dataStorage = persistentSceneSystem.PersistentDataStorage;
            PersistentDataContainer container;

            if (index == -1)
            {
                container = dataStorage.GetReadContainerForCurrentIndex(containerIdentifier);
            }
            else if (initial)
            {
                container = dataStorage.GetInitialStateReadContainer(containerIdentifier);
            }
            else
            {
                int oldIndex = dataStorage.NonWrappedIndex;
                dataStorage.ToIndex(index);
                container = dataStorage.GetReadContainerForCurrentIndex(containerIdentifier);
                dataStorage.ToIndex(oldIndex);
            }

            // Workaround for bug where AsyncReadManager.Read keeps a handle to the last 11 reads
            for (int i = 0; i < 12; i++)
            {
                string bugWorkaroundFilePath = Application.streamingAssetsPath + $"/UnityAsyncReadBugWorkaround{i.ToString()}.txt";
                unsafe
                {
                    var readCmd = new ReadCommand
                    {
                        Size = 0, Offset = 0, Buffer = null
                    };
                    var readHandle = AsyncReadManager.Read(bugWorkaroundFilePath, &readCmd, 1);
                    readHandle.JobHandle.Complete();
                    readHandle.Dispose();
                }
            }

            // Write To Disk
            using (var fileStream = new StreamBinaryWriter(path))
            {
                fileStream.Write(container.CalculateEntityCapacity());
                NativeArray <byte> rawData = container.GetRawData();
                fileStream.Write(rawData.Length);
                fileStream.WriteArray(rawData);
            }
        }
예제 #2
0
        protected override void OnCreate()
        {
            PersistencySettings = PersistencySettings.Get();
            if (PersistencySettings == null)
            {
                Enabled = false;
                Debug.Log(PersistencySettings.NotFoundMessage);
            }
            PersistentDataStorage = new PersistentDataStorage(1);

            _beginFrameSystem = World.GetOrCreateSystem <BeginFramePersistencySystem>();
            _ecbSystem        = World.GetOrCreateSystem <EndInitializationEntityCommandBufferSystem>();

            _scenePersistencyInfoQuery      = GetEntityQuery(ComponentType.ReadOnly <ScenePersistencyInfoRef>(), ComponentType.ReadOnly <PersistencyContainerTag>());
            _sceneSectionLoadedCheckQuery   = GetEntityQuery(ComponentType.ReadOnly <SceneSection>());
            _resizeContainerDependencyQuery = GetEntityQuery(ComponentType.ReadOnly <PersistenceState>());
            RequireForUpdate(GetEntityQuery(ComponentType.ReadOnly <RequestPersistentSceneSectionLoaded>(), ComponentType.ReadOnly <SceneSectionData>(), ComponentType.Exclude <PersistentSceneSectionLoadComplete>()));
        }
예제 #3
0
        // index -1 means 'use current index'
        public static int ReadContainerFromDisk(this PersistentSceneSystem persistentSceneSystem, Hash128 containerIdentifier, int index = -1)
        {
            // Path
            string path = CalculateStreamingAssetsPath(containerIdentifier);

            Debug.Assert(File.Exists(path));

            // Read From Disk
            using (var fileStream = new StreamBinaryReader(path))
            {
                PersistentDataStorage dataStorage = persistentSceneSystem.PersistentDataStorage;
                int amountEntitiesInFile          = fileStream.ReadInt();
                if (!dataStorage.IsInitialized(containerIdentifier))
                {
                    // Read before the scene has been loaded once this session
                    int amountBytesOfRawData   = fileStream.ReadInt();
                    NativeArray <byte> rawData = new NativeArray <byte>(amountBytesOfRawData, Allocator.Persistent);
                    fileStream.ReadArray(rawData, rawData.Length);
                    dataStorage.AddUninitializedSceneContainer(containerIdentifier, rawData);
                }
                else
                {
                    int currentEntityCapacity = dataStorage.GetEntityCapacity(containerIdentifier, out bool isPool);

                    if (amountEntitiesInFile != currentEntityCapacity)
                    {
                        if (isPool)
                        {
                            persistentSceneSystem.InstantChangePoolCapacity(containerIdentifier, amountEntitiesInFile);
                        }
                        else
                        {
                            throw new InvalidDataException($"The data in \"{path}\" is invalid. (.sav data only stays valid as long as the subscene doesn't change)");
                        }
                    }

                    // Container (Important that it happens after potential capacity change!)
                    PersistentDataContainer container;
                    if (index == -1)
                    {
                        container = dataStorage.GetWriteContainerForCurrentIndex(containerIdentifier);
                    }
                    else
                    {
                        int oldIndex = dataStorage.NonWrappedIndex;
                        dataStorage.ToIndex(index);
                        container = dataStorage.GetWriteContainerForCurrentIndex(containerIdentifier);
                        dataStorage.ToIndex(oldIndex);
                    }

                    // Read Data From Disk
                    NativeArray <byte> rawData = container.GetRawData();

                    int amountBytesOfRawData = fileStream.ReadInt();
                    if (amountBytesOfRawData != rawData.Length)
                    {
                        // Extra integrity Check
                        throw new InvalidDataException($"The data in \"{path}\" is invalid. (maybe component data structs changed?)");
                    }

                    fileStream.ReadArray(rawData, rawData.Length);
                }
                return(amountEntitiesInFile);
            }
        }