示例#1
0
        public ReadHandle ReadAsync()
        {
            if (EndOfStream)
            {
                return(new ReadHandle());              // returns void handle
            }
            // check file termination
            _info.Target->dataLength = Math.Min(_info.Target->blockSize, (int)(_info.Target->fileSize - ((long)_info.Target->blockSize) * _info.Target->blockPos));

            _readCommands[0] = new ReadCommand
            {
                Offset = _info.Target->blockPos * _info.Target->blockSize,
                Size   = _info.Target->dataLength,
                Buffer = _byteBuffer.GetUnsafePtr(),
            };

            ReadHandle read_handle = AsyncReadManager.Read(_path.Target, (ReadCommand *)(_readCommands.GetUnsafePtr()), 1);

            if (!read_handle.IsValid())
            {
                throw new InvalidOperationException("failure to open file.");
            }

            _info.Target->blockPos++;
            return(read_handle);
        }
        public JobHandle ReadFileAsync(string path, int i_block)
        {
            this.CheckPreviousJob();

            var fileInfo = new System.IO.FileInfo(path);

            if (!fileInfo.Exists)
            {
                throw new ArgumentException($"the file '{path}'is not found.");
            }

            long bufferSize = _info.Target->bufferSize;
            long offset     = i_block * bufferSize;
            long size       = Math.Min(bufferSize, fileInfo.Length - offset);

            if (offset >= fileInfo.Length || i_block < 0)
            {
                int max_index = (int)(fileInfo.Length / bufferSize);
                throw new ArgumentOutOfRangeException($"invalid i_block. i_block must be in range of [0, {max_index}].");
            }

            *_readCmd.Target = new ReadCommand
            {
                Offset = offset,
                Size   = size,
                Buffer = _byteBuffer.GetUnsafePtr(),
            };

            _info.Target->dataSize   = (int)size;
            _info.Target->ReadHandle = AsyncReadManager.Read(path, _readCmd.Target, 1);
            return(_info.Target->ReadHandle.JobHandle);
        }
示例#3
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);
            }
        }
 private static void StartReadMagicBytes(string path, JobMetaLoaderInternal *answer)
 {
     answer->ReadCommandReference = new ReadCommand
     {
         Buffer = (void *)answer->MagicBytePtr,
         Offset = 0L,
         Size   = 20L,
     };
     answer->ReadHandleReference = AsyncReadManager.Read(path, (ReadCommand *)answer->ReadCommandPtr, 1);
 }
        public ReadHandle Read(ReadCommand *readCmds, uint cmdCount, ReadMode mode = ReadMode.Async)
        {
            var handle = AsyncReadManager.Read(FilePath, readCmds, cmdCount);

            if (mode == ReadMode.Blocking)
            {
                handle.JobHandle.Complete();
            }

            return(handle);
        }
示例#6
0
        public static bool FileExists(string path)
        {
            var readHandle = AsyncReadManager.Read(path, null, 0);

            readHandle.JobHandle.Complete();
            if (readHandle.Status == ReadStatus.Failed)
            {
                return(false);
            }

            return(true);
        }
        public unsafe void Start()
        {
            string path = Path.Combine(Application.streamingAssetsPath, relativePathToStreamingData);

            cmd = new NativeArray <ReadCommand>(1, Allocator.Persistent);
            var command = new ReadCommand {
                Offset = 0,
                Size   = 1024,
                Buffer = (byte *)UnsafeUtility.Malloc(1024, 16, Allocator.Persistent)
            };

            cmd[0]     = command;
            readHandle = AsyncReadManager.Read(path, (ReadCommand *)cmd.GetUnsafePtr(), 1);
        }
示例#8
0
 public void StartLoad(FileInfo[] infos, string[] fullPaths)
 {
     _currentStage = Stage.ReadAsync;
     for (int i = 0; i < Length; i++)
     {
         RawFiles[i]     = new RawTextFile(i, infos[i].Length - _isUtf16);
         ReadCommands[i] = new ReadCommand
         {
             Size   = RawFiles[i].Length,
             Buffer = RawFiles[i].Contents,
             Offset = _isUtf16,
         };
         ReadHandles[i] = AsyncReadManager.Read(fullPaths[i], ReadCommands + i, 1);
     }
 }
示例#9
0
        public void ReadBytes(void *data, int bytes)
        {
            var readCmd = new ReadCommand
            {
                Size = bytes, Offset = bytesRead, Buffer = data
            };
            var readHandle = AsyncReadManager.Read(filePath, &readCmd, 1);

            readHandle.JobHandle.Complete();

            if (readHandle.Status != ReadStatus.Complete)
            {
                throw new IOException($"Failed to read from {filePath}!");
            }
            bytesRead += bytes;
        }
示例#10
0
        public void SeekFrame(int frameIndex)
        {
            ASSERT_BUFFERS();

#if VERBOSE
            Debug.Log("SEEK " + frameIndex);
#endif

            // sanitize user input
            frameIndex = Mathf.Clamp(frameIndex, 0, frameCount - 1);

            // expand range within bounds
            int readIndexLo = Mathf.Max(frameIndex - seekRadius, 0);
            int readIndexHi = Mathf.Min(frameIndex + seekRadius, frameCount - 1);

            // schedule each read individually
            var ringDataPtr = (byte *)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(ringData);
            for (int readIndex = readIndexLo; readIndex <= readIndexHi; readIndex++)
            {
                // map frame to index in ring
                int ringIndex = (readIndex & (ringCapacityPow2 - 1));

                // if frame is not already in ring
                if (ringDataTag[ringIndex] != readIndex)
                {
                    ringDataTag[ringIndex] = readIndex;

                    // wait for pending element operation
                    var dataHnd = ringDataHnd[ringIndex];
                    if (dataHnd.IsValid() && dataHnd.Status == ReadStatus.InProgress)
                    {
                        dataHnd.JobHandle.Complete();
                    }

                    // schedule the read
                    ReadCommand cmd;
                    cmd.Buffer             = frameSize * ringIndex + ringDataPtr;
                    cmd.Offset             = frameSize * (long)readIndex + frameOffset;
                    cmd.Size               = frameSize;
                    ringDataHnd[ringIndex] = AsyncReadManager.Read(filename, &cmd, 1);

#if VERBOSE
                    Debug.Log("schedule " + frameIndex + " -> ringIndex " + ringIndex);
#endif
                }
            }
        }
示例#11
0
    public unsafe void Load(string path)
    {
        FileInfo info = new FileInfo(path);

        _fileSize = info.Length;

        _readCommands    = new NativeArray <ReadCommand>(1, Allocator.Persistent);
        _readCommands[0] = new ReadCommand
        {
            Offset = 0,
            Size   = _fileSize,
            Buffer = (byte *)UnsafeUtility.Malloc(_fileSize, UnsafeUtility.AlignOf <byte>(), Allocator.Persistent),
        };

        _readHandle = AsyncReadManager.Read(path, (ReadCommand *)_readCommands.GetUnsafePtr(), 1);

        CheckLoop();
    }
示例#12
0
        private void Next()
        {
            Task task = this.tasks.Dequeue();

            FileInfo fileInfo = new FileInfo(task.textureData.filePath);

            task.fileSize = fileInfo.Length;

            task.readCommands    = new NativeArray <ReadCommand>(1, Allocator.Persistent);
            task.readCommands[0] = new ReadCommand {
                Offset = 0,
                Size   = task.fileSize,
                Buffer = UnsafeUtility.Malloc(task.fileSize, UnsafeUtility.AlignOf <byte>(), Allocator.Persistent)
            };
            task.readHandle = AsyncReadManager.Read(task.textureData.filePath, (ReadCommand *)task.readCommands.GetUnsafePtr(), 1);

            this.currentTask = task;
        }
        /// <summary>
        /// 読み込み開始
        /// </summary>
        public void ReadData()
        {
            // コマンド発行用にファイルサイズを取得
            var  fileInfo = new System.IO.FileInfo(Constants.SampleDataPath);
            long fileSize = fileInfo.Length;

            // コマンド生成
            this._readCommand    = new NativeArray <ReadCommand>(1, Allocator.Persistent);
            this._readCommand[0] = new ReadCommand
            {
                Offset = 0,
                Size   = fileSize,
                Buffer = (byte *)UnsafeUtility.Malloc(fileSize, UnsafeUtility.AlignOf <byte>(), Allocator.Persistent),
            };

            // 読み込み開始
            this._readHandle = AsyncReadManager.Read(Constants.SampleDataPath, (ReadCommand *)this._readCommand.GetUnsafePtr(), 1);
        }
        private void UpdateBlocking()
        {
            if (_LoadingStatus == LoadingStatus.Completed)
            {
                return;
            }
            if (_SceneSize == 0)
            {
                return;
            }

            try
            {
                _StartTime = Time.realtimeSinceStartup;

                _FileContent = (byte *)UnsafeUtility.Malloc(_SceneSize, 16, Allocator.Persistent);

                ReadCommand cmd;
                cmd.Buffer  = _FileContent;
                cmd.Offset  = 0;
                cmd.Size    = _SceneSize;
                _ReadHandle = AsyncReadManager.Read(_ScenePath, &cmd, 1);

                if (_ExpectedObjectReferenceCount != 0)
                {
#if UNITY_EDITOR
                    var resourceRequests = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(_ResourcesPathObjRefs);
                    _ResourceObjRefs = (ReferencedUnityObjects)resourceRequests[0];
#else
                    _SceneBundleHandle = SceneBundleHandle.CreateOrRetainBundle(_ResourcesPathObjRefs);
                    _ResourceObjRefs   = _SceneBundleHandle.AssetBundle.LoadAsset <ReferencedUnityObjects>(Path.GetFileName(_ResourcesPathObjRefs));
#endif
                }

                ScheduleSceneRead(_ResourceObjRefs);
                _EntityManager.ExclusiveEntityTransactionDependency.Complete();
            }
            catch (Exception e)
            {
                _LoadingFailure = e.Message;
            }
            _LoadingStatus = LoadingStatus.Completed;
        }
示例#15
0
        public void ReadBytes(void *data, int bytes)
        {
            #if UNITY_EDITOR
            int remaining  = bytes;
            int bufferSize = buffer.Length;

            fixed(byte *fixedBuffer = buffer)
            {
                while (remaining != 0)
                {
                    int read = stream.Read(buffer, 0, Math.Min(remaining, bufferSize));
                    remaining -= read;
                    UnsafeUtility.MemCpy(data, fixedBuffer, read);
                    data = (byte *)data + read;
                }
            }
            #else
            var readCmd = new ReadCommand
            {
                Size = bytes, Offset = bytesRead, Buffer = data
            };
            Assert.IsFalse(string.IsNullOrEmpty(filePath));
#if ENABLE_PROFILER && UNITY_2020_2_OR_NEWER
            // When AsyncReadManagerMetrics are available, mark up the file read for more informative IO metrics.
            // Metrics can be retrieved by AsyncReadManagerMetrics.GetMetrics
            var readHandle = AsyncReadManager.Read(filePath, &readCmd, 1, subsystem: AssetLoadingSubsystem.EntitiesStreamBinaryReader);
#else
            var readHandle = AsyncReadManager.Read(filePath, &readCmd, 1);
#endif
            readHandle.JobHandle.Complete();

            if (readHandle.Status != ReadStatus.Complete)
            {
                throw new IOException($"Failed to read from {filePath}!");
            }
            bytesRead += bytes;
            #endif
        }
        public void ReadBytes(void *data, int bytes)
        {
            var readCmd = new ReadCommand
            {
                Size = bytes, Offset = bytesRead, Buffer = data
            };

            Assert.IsFalse(string.IsNullOrEmpty(filePath));
#if ENABLE_PROFILER && UNITY_2020_2_OR_NEWER
            // When AsyncReadManagerMetrics are available, mark up the file read for more informative IO metrics.
            // Metrics can be retrieved by AsyncReadManagerMetrics.GetMetrics
            var readHandle = AsyncReadManager.Read(filePath, &readCmd, 1, subsystem: AssetLoadingSubsystem.EntitiesStreamBinaryReader);
#else
            var readHandle = AsyncReadManager.Read(filePath, &readCmd, 1);
#endif
            readHandle.JobHandle.Complete();

            if (readHandle.Status != ReadStatus.Complete)
            {
                throw new IOException($"Failed to read from {filePath}!");
            }
            bytesRead += bytes;
        }
        public JobHandle ReadFileAsync(string path)
        {
            this.CheckPreviousJob();

            var fileInfo = new System.IO.FileInfo(path);

            if (!fileInfo.Exists)
            {
                throw new ArgumentException($"the file '{path}'is not found.");
            }

            this.Reallocate(fileInfo.Length);

            *_readCmd.Target = new ReadCommand
            {
                Offset = 0,
                Size   = fileInfo.Length,
                Buffer = _byteBuffer.GetUnsafePtr(),
            };

            _info.Target->dataSize   = (int)fileInfo.Length;
            _info.Target->ReadHandle = AsyncReadManager.Read(path, _readCmd.Target, 1);
            return(_info.Target->ReadHandle.JobHandle);
        }
        private void UpdateAsync()
        {
            //@TODO: Try to overlap Resources load and entities scene load

            // Begin Async resource load
            if (_LoadingStatus == LoadingStatus.NotStarted)
            {
                if (_SceneSize == 0)
                {
                    return;
                }

                try
                {
                    _StartTime = Time.realtimeSinceStartup;

                    _FileContent = (byte *)UnsafeUtility.Malloc(_SceneSize, 16, Allocator.Persistent);

                    ReadCommand cmd;
                    cmd.Buffer  = _FileContent;
                    cmd.Offset  = 0;
                    cmd.Size    = _SceneSize;
                    _ReadHandle = AsyncReadManager.Read(_ScenePath, &cmd, 1);

                    if (_ExpectedObjectReferenceCount != 0)
                    {
#if UNITY_EDITOR
                        var resourceRequests = UnityEditorInternal.InternalEditorUtility.LoadSerializedFileAndForget(_ResourcesPathObjRefs);
                        _ResourceObjRefs = (ReferencedUnityObjects)resourceRequests[0];

                        _LoadingStatus = LoadingStatus.WaitingForResourcesLoad;
#else
                        _SceneBundleHandle = SceneBundleHandle.CreateOrRetainBundle(_ResourcesPathObjRefs);
                        _LoadingStatus     = LoadingStatus.WaitingForAssetBundleLoad;
#endif
                    }
                    else
                    {
                        _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad;
                    }
                }
                catch (Exception e)
                {
                    _LoadingFailure = e.Message;
                    _LoadingStatus  = LoadingStatus.Completed;
                }
            }

            // Once async asset bundle load is done, we can read the asset
            if (_LoadingStatus == LoadingStatus.WaitingForAssetBundleLoad)
            {
                if (!_SceneBundleHandle.IsReady())
                {
                    return;
                }

                if (!_SceneBundleHandle.AssetBundle)
                {
                    _LoadingFailure = $"Failed to load Asset Bundle '{_ResourcesPathObjRefs}'";
                    _LoadingStatus  = LoadingStatus.Completed;
                    return;
                }

                var fileName = Path.GetFileName(_ResourcesPathObjRefs);

                _AssetRequest  = _SceneBundleHandle.AssetBundle.LoadAssetAsync(fileName);
                _LoadingStatus = LoadingStatus.WaitingForAssetLoad;
            }

            // Once async asset bundle load is done, we can read the asset
            if (_LoadingStatus == LoadingStatus.WaitingForAssetLoad)
            {
                if (!_AssetRequest.isDone)
                {
                    return;
                }

                if (!_AssetRequest.asset)
                {
                    _LoadingFailure = $"Failed to load Asset '{Path.GetFileName(_ResourcesPathObjRefs)}'";
                    _LoadingStatus  = LoadingStatus.Completed;
                    return;
                }

                _ResourceObjRefs = _AssetRequest.asset as ReferencedUnityObjects;

                if (_ResourceObjRefs == null)
                {
                    _LoadingFailure = $"Failed to load object references resource '{_ResourcesPathObjRefs}'";
                    _LoadingStatus  = LoadingStatus.Completed;
                    return;
                }

                _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad;
            }

            // Once async resource load is done, we can async read the entity scene data
            if (_LoadingStatus == LoadingStatus.WaitingForResourcesLoad)
            {
                if (_ResourceObjRefs == null)
                {
                    _LoadingFailure = $"Failed to load object references resource '{_ResourcesPathObjRefs}'";
                    _LoadingStatus  = LoadingStatus.Completed;
                    return;
                }

                _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad;
            }

            if (_LoadingStatus == LoadingStatus.WaitingForEntitiesLoad)
            {
                try
                {
                    _LoadingStatus = LoadingStatus.WaitingForSceneDeserialization;
                    ScheduleSceneRead(_ResourceObjRefs);

                    if (_BlockUntilFullyLoaded)
                    {
                        _EntityManager.ExclusiveEntityTransactionDependency.Complete();
                    }
                }
                catch (Exception e)
                {
                    _LoadingFailure = e.Message;
                    _LoadingStatus  = LoadingStatus.Completed;
                }
            }

            // Complete Loading status
            if (_LoadingStatus == LoadingStatus.WaitingForSceneDeserialization)
            {
                if (_EntityManager.ExclusiveEntityTransactionDependency.IsCompleted)
                {
                    _EntityManager.ExclusiveEntityTransactionDependency.Complete();

                    _LoadingStatus = LoadingStatus.Completed;
                    var currentTime = Time.realtimeSinceStartup;
                    var totalTime   = currentTime - _StartTime;
                    System.Console.WriteLine($"Streamed scene with {totalTime * 1000,3:f0}ms latency from {_ScenePath}");
                }
            }
        }
        public void Update()
        {
            //@TODO: Try to overlap Resources load and entities scene load

            // Begin Async resource load
            if (_LoadingStatus == LoadingStatus.NotStarted)
            {
                if (_SceneSize == 0)
                {
                    return;
                }
                try
                {
                    _StartTime = Time.realtimeSinceStartup;
                    if (_ExpectedSharedComponentCount != 0)
                    {
                        _ResourceRequest = Resources.LoadAsync <GameObject>(_ResourcesPath);
                        _LoadingStatus   = LoadingStatus.WaitingForResourcesLoad;
                    }
                    else
                    {
                        _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad;
                    }
                    _FileContent = (byte *)UnsafeUtility.Malloc(_SceneSize, 16, Allocator.Persistent);

                    ReadCommand cmd;
                    cmd.Buffer  = _FileContent;
                    cmd.Offset  = 0;
                    cmd.Size    = _SceneSize;
                    _ReadHandle = AsyncReadManager.Read(_ScenePath, &cmd, 1);
                }
                catch (Exception e)
                {
                    _LoadingFailure = e.Message;
                    _LoadingStatus  = LoadingStatus.Completed;
                }
            }

            // Once async resource load is done, we can async read the entity scene data
            if (_LoadingStatus == LoadingStatus.WaitingForResourcesLoad)
            {
                if (!_ResourceRequest.isDone)
                {
                    return;
                }

                if (!_ResourceRequest.asset)
                {
                    _LoadingFailure = $"Failed to load Shared component resource '{_ResourcesPath}'";
                    _LoadingStatus  = LoadingStatus.Completed;
                    return;
                }

                try
                {
                    _LoadingStatus = LoadingStatus.WaitingForEntitiesLoad;
                    ScheduleSceneRead(_ResourceRequest.asset as GameObject);
                }
                catch (Exception e)
                {
                    _LoadingFailure = e.Message;
                    _LoadingStatus  = LoadingStatus.Completed;
                }
            }

            // Complete Loading status
            if (_LoadingStatus == LoadingStatus.WaitingForEntitiesLoad)
            {
                if (_EntityManager.ExclusiveEntityTransactionDependency.IsCompleted)
                {
                    _EntityManager.ExclusiveEntityTransactionDependency.Complete();

                    _LoadingStatus = LoadingStatus.Completed;
                    var currentTime = Time.realtimeSinceStartup;
                    var totalTime   = currentTime - _StartTime;
                    System.Console.WriteLine($"Streamed scene with {totalTime*1000,3:f0}ms latency from {_ScenePath}");
                }
            }
        }