From b47a71e40bbbfab701851847568942cd24d58c5d Mon Sep 17 00:00:00 2001 From: alexiscatnip Date: Sat, 9 Jul 2022 01:44:13 +0800 Subject: [PATCH] make file writer API pseudo-async --- .../Bootstrap/RaindropBootstrapper.cs | 2 +- Assets/UnityScripts/Disk/DirectoryHelpers.cs | 27 ++++++ Assets/UnityScripts/Disk/StaticFilesCopier.cs | 93 ++++++++++--------- 3 files changed, 77 insertions(+), 45 deletions(-) diff --git a/Assets/Raindrop/Bootstrap/RaindropBootstrapper.cs b/Assets/Raindrop/Bootstrap/RaindropBootstrapper.cs index 93e0f75..e6a5faa 100644 --- a/Assets/Raindrop/Bootstrap/RaindropBootstrapper.cs +++ b/Assets/Raindrop/Bootstrap/RaindropBootstrapper.cs @@ -29,7 +29,7 @@ namespace Raindrop.Services.Bootstrap SceneManager.LoadScene("Raindrop/Bootstrap/MainScene"); } - //perform check-copy operation. + // prep user file system for LMV's usage, by copying static files. private static void CheckAndUpdate_StaticFileSystem() { var copier = StaticFilesCopier.GetInstance(); diff --git a/Assets/UnityScripts/Disk/DirectoryHelpers.cs b/Assets/UnityScripts/Disk/DirectoryHelpers.cs index 5c9ebbf..92e2671 100644 --- a/Assets/UnityScripts/Disk/DirectoryHelpers.cs +++ b/Assets/UnityScripts/Disk/DirectoryHelpers.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Threading.Tasks; using OpenMetaverse; using UnityEngine; @@ -87,6 +88,32 @@ namespace Disk Debug.Log($"write: {filePath} "); } + //easily write to a file + //filePath = fully-specified file path + public static async Task WriteToFileAsync(byte[] outbytes, string filePath) + { + //create parent subfolders + var parentDir = Path.GetDirectoryName(filePath); + System.IO.Directory.CreateDirectory(parentDir); + + await Task.Run(() => + { + //write file + try + { + System.IO.File.WriteAllBytes(filePath, outbytes); + } + catch (IOException e) + { + OpenMetaverse.Logger.Log( + "error writing bytes to filepath : " + filePath + " " + + e.ToString(), Helpers.LogLevel.Error); + } + }); + + Debug.Log($"write: {filePath} "); + } + //easily write to a file //filePath = fully-specified file path public static void WriteToFile(string toWrite, string filePath) diff --git a/Assets/UnityScripts/Disk/StaticFilesCopier.cs b/Assets/UnityScripts/Disk/StaticFilesCopier.cs index 7c515a7..61cf570 100644 --- a/Assets/UnityScripts/Disk/StaticFilesCopier.cs +++ b/Assets/UnityScripts/Disk/StaticFilesCopier.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; using Disk; using OpenMetaverse; using SearchOption = System.IO.SearchOption; @@ -41,10 +42,11 @@ namespace UnityScripts.Disk //returns -1 if failed. private int CheckOmvDataFolderAndUpdateItIfNecessary() { - List updatedFiles = null; + + Task> updatedFilesTask = null; try { - updatedFiles = CopyIfRequired_StreamingAssetsFolder( + updatedFilesTask = Copy_StreamingAssetsFolder_To_UserDataRoot_Async( DirectoryHelpers.GetInternalStorageDir() ); } @@ -52,8 +54,9 @@ namespace UnityScripts.Disk { return -1; } - - if (updatedFiles.Count > 0) + + var updatedFiles = updatedFilesTask.Result; //blocking call. + if (updatedFiles.Count > 0) { var printString = String.Join(Environment.NewLine, updatedFiles); OpenMetaverse.Logger.Log( @@ -63,21 +66,16 @@ namespace UnityScripts.Disk Helpers.LogLevel.Info ); } - else - { - OpenMetaverse.Logger.Log( - "staticAssets are already latest version in : " - + DirectoryHelpers.GetInternalStorageDir(), - Helpers.LogLevel.Info - ); - } return 0; } - // scan all files in streamingAssets folder, and copy any changed/missing files into userDataRoot. - // return some files that were updated. - private List CopyIfRequired_StreamingAssetsFolder(string appRootPath) + // scan all files in streamingAssets folder, + // and copy any changed/missing files into userDataRoot. + // return the list of files that were updated. + private async Task> + Copy_StreamingAssetsFolder_To_UserDataRoot_Async( + string appRootPath) { List updatedFiles = new List(); @@ -88,49 +86,39 @@ namespace UnityScripts.Disk throw new Exception( "StreamingAssets root not accessible."); } - string[] paths = - BetterStreamingAssets.GetFiles( - slash, - "*", - SearchOption.AllDirectories); + string[] fromPaths = BetterStreamingAssets.GetFiles( + slash, + "*", + SearchOption.AllDirectories); - if (paths.Length == 0) + if (fromPaths.Length == 0) { throw new Exception( "StreamingAssets has no files in it."); } - foreach (var sourcePath in paths) - { - string relativePath = ""; - //find the equivalent path in appRootPath - string root = Directory.GetDirectoryRoot(sourcePath); - if (root != null/*todo: check for failed get root.*/) - { - // gotta remove that root slash character '\' - relativePath = sourcePath.Substring(root.Length - 1); - } - - //1. check for missing file + foreach (var fromPath in fromPaths) + { + var relativePath = RemoveRootFolderFromPath(fromPath); string targetPath = Path.Combine(appRootPath, relativePath); - if (!File.Exists(targetPath)) + + //1. check for missing file + bool fileIsMissing = !File.Exists(targetPath); + if (fileIsMissing) { updatedFiles.Add(targetPath); - DirectoryHelpers.WriteToFile( - BetterStreamingAssets.ReadAllBytes(sourcePath), + DirectoryHelpers.WriteToFileAsync( + BetterStreamingAssets.ReadAllBytes(fromPath), targetPath); + continue; } //2. check for diffs in the file. bool fileIsDifferent = false; using (Stream fs1 = File.OpenRead(targetPath)) - using (Stream fs2 = BetterStreamingAssets.OpenRead(sourcePath)) + using (Stream fs2 = BetterStreamingAssets.OpenRead(fromPath)) { - if (FileHelpers.FileStreamsAreEqual(fs1, fs2)) - { - //do nothing - } - else + if (!FileHelpers.FileStreamsAreEqual(fs1, fs2)) { fileIsDifferent = true; } @@ -138,12 +126,29 @@ namespace UnityScripts.Disk if (fileIsDifferent) { updatedFiles.Add(targetPath); - DirectoryHelpers.WriteToFile( - BetterStreamingAssets.ReadAllBytes(sourcePath), + DirectoryHelpers.WriteToFileAsync( + BetterStreamingAssets.ReadAllBytes(fromPath), targetPath); } } return updatedFiles; + + // remove root folder: + // ie: /streamingAssets/a/b/ -> /a/b/ + string RemoveRootFolderFromPath(string fullPath) + { + string relativePath = ""; + + //find the equivalent path in appRootPath + string fromPath_Root = Directory.GetDirectoryRoot(fullPath); + if (fromPath_Root != null /*todo: check for failed get root.*/) + { + // gotta remove that root slash character '\' + relativePath = fullPath.Substring(fromPath_Root.Length - 1); + } + + return relativePath; + } } } }