From 827bf243396597ca20e0fd789436524619e79cc0 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 14 Jun 2024 21:43:00 -0400 Subject: [PATCH 01/10] Non sequential --- .../Builder/Props/ProjectionBuilder.cs | 226 +++++++++++------- .../Files/SlideReelAsyncImageLoader.cs | 5 + 2 files changed, 145 insertions(+), 86 deletions(-) diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index 3ba8e91d..08e2b88c 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -149,24 +149,53 @@ namespace NewHorizons.Builder.Props // We can fit 16 slides max into an atlas var textures = new Texture2D[slidesCount > 16 ? 16 : slidesCount]; - var imageLoader = StartAsyncLoader(mod, info.slides, ref slideCollection); + var (invImageLoader, atlasImageLoader, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection); var key = GetUniqueSlideReelID(mod, info.slides); - // this variable just lets us track how many of the first 15 slides have been loaded. - // this way as soon as the last one is loaded (due to async loading, this may be - // slide 7, or slide 3, or whatever), we can build the slide reel texture. This allows us - // to avoid doing a "is every element in the array `textures` not null" check every time a texture finishes loading - int displaySlidesLoaded = 0; - imageLoader.imageLoadedEvent.AddListener( - (Texture2D tex, int index, string originalPath) => + if (invImageLoader != null && atlasImageLoader != null) + { + // Loading directly from cache + invImageLoader.imageLoadedEvent.AddListener( + (Texture2D tex, int index, string originalPath) => + { + slideCollection.slides[index]._image = tex; + } + ); + atlasImageLoader.imageLoadedEvent.AddListener( + (Texture2D tex, int _, string originalPath) => + { + // all textures required to build the reel's textures have been loaded + var slidesBack = slideReelObj.GetComponentInChildren().transform.Find("Slides_Back").GetComponent(); + var slidesFront = slideReelObj.GetComponentInChildren().transform.Find("Slides_Front").GetComponent(); + + // Now put together the textures into a 4x4 thing for the materials + var reelTexture = tex; + slidesBack.material.mainTexture = reelTexture; + slidesBack.material.SetTexture(EmissionMap, reelTexture); + slidesBack.material.name = reelTexture.name; + slidesFront.material.mainTexture = reelTexture; + slidesFront.material.SetTexture(EmissionMap, reelTexture); + slidesFront.material.name = reelTexture.name; + } + ); + } + else + { + // this variable just lets us track how many of the first 15 slides have been loaded. + // this way as soon as the last one is loaded (due to async loading, this may be + // slide 7, or slide 3, or whatever), we can build the slide reel texture. This allows us + // to avoid doing a "is every element in the array `textures` not null" check every time a texture finishes loading + int displaySlidesLoaded = 0; + imageLoader.imageLoadedEvent.AddListener( + (Texture2D tex, int index, string originalPath) => { var time = DateTime.Now; slideCollection.slides[index]._image = ImageUtilities.InvertSlideReel(mod, tex, originalPath); NHLogger.LogVerbose($"Slide reel make reel invert texture {(DateTime.Now - time).TotalMilliseconds}ms"); // Track the first 16 to put on the slide reel object - if (index < textures.Length) + if (index < textures.Length) { textures[index] = tex; displaySlidesLoaded++; @@ -188,8 +217,9 @@ namespace NewHorizons.Builder.Props } NHLogger.LogVerbose($"Slide reel make reel texture {(DateTime.Now - time).TotalMilliseconds}ms"); - } - ); + }); + } + // Else when you put them down you can't pick them back up slideReelObj.GetComponent()._physicsRemoved = false; @@ -210,58 +240,58 @@ namespace NewHorizons.Builder.Props switch (model) { case ProjectionInfo.SlideReelType.SixSlides: - { - switch (condition) { - case ProjectionInfo.SlideReelCondition.Antique: - default: - return SlideReel6Prefab; - case ProjectionInfo.SlideReelCondition.Pristine: - return SlideReel6PristinePrefab; - case ProjectionInfo.SlideReelCondition.Rusted: - return SlideReel6RustedPrefab; + switch (condition) + { + case ProjectionInfo.SlideReelCondition.Antique: + default: + return SlideReel6Prefab; + case ProjectionInfo.SlideReelCondition.Pristine: + return SlideReel6PristinePrefab; + case ProjectionInfo.SlideReelCondition.Rusted: + return SlideReel6RustedPrefab; + } } - } case ProjectionInfo.SlideReelType.SevenSlides: default: - { - switch (condition) { - case ProjectionInfo.SlideReelCondition.Antique: - default: - return SlideReel7Prefab; - case ProjectionInfo.SlideReelCondition.Pristine: - return SlideReel7PristinePrefab; - case ProjectionInfo.SlideReelCondition.Rusted: - return SlideReel7RustedPrefab; + switch (condition) + { + case ProjectionInfo.SlideReelCondition.Antique: + default: + return SlideReel7Prefab; + case ProjectionInfo.SlideReelCondition.Pristine: + return SlideReel7PristinePrefab; + case ProjectionInfo.SlideReelCondition.Rusted: + return SlideReel7RustedPrefab; + } } - } case ProjectionInfo.SlideReelType.EightSlides: - { - switch (condition) { - case ProjectionInfo.SlideReelCondition.Antique: - default: - return SlideReel8Prefab; - case ProjectionInfo.SlideReelCondition.Pristine: - return SlideReel8PristinePrefab; - case ProjectionInfo.SlideReelCondition.Rusted: - return SlideReel8RustedPrefab; + switch (condition) + { + case ProjectionInfo.SlideReelCondition.Antique: + default: + return SlideReel8Prefab; + case ProjectionInfo.SlideReelCondition.Pristine: + return SlideReel8PristinePrefab; + case ProjectionInfo.SlideReelCondition.Rusted: + return SlideReel8RustedPrefab; + } } - } case ProjectionInfo.SlideReelType.Whole: - { - switch (condition) { - case ProjectionInfo.SlideReelCondition.Antique: - default: - return SlideReelWholePrefab; - case ProjectionInfo.SlideReelCondition.Pristine: - return SlideReelWholePristinePrefab; - case ProjectionInfo.SlideReelCondition.Rusted: - return SlideReelWholeRustedPrefab; + switch (condition) + { + case ProjectionInfo.SlideReelCondition.Antique: + default: + return SlideReelWholePrefab; + case ProjectionInfo.SlideReelCondition.Pristine: + return SlideReelWholePristinePrefab; + case ProjectionInfo.SlideReelCondition.Rusted: + return SlideReelWholeRustedPrefab; + } } - } } } @@ -314,13 +344,25 @@ namespace NewHorizons.Builder.Props var slideCollection = new SlideCollection(slidesCount); slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null - var imageLoader = StartAsyncLoader(mod, info.slides, ref slideCollection); - imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) => + var (invImageLoader, _, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection); + if (invImageLoader != null) { - var time = DateTime.Now; - slideCollection.slides[index]._image = ImageUtilities.InvertSlideReel(mod, tex, originalPath); - NHLogger.LogVerbose($"Slide reel invert time {(DateTime.Now - time).TotalMilliseconds}ms"); - }); + // Loaded directly from cache + invImageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) => + { + slideCollection.slides[index]._image = tex; + }); + } + else + { + // Create the inverted cache from existing images + imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) => + { + var time = DateTime.Now; + slideCollection.slides[index]._image = ImageUtilities.InvertSlideReel(mod, tex, originalPath); + NHLogger.LogVerbose($"Slide reel invert time {(DateTime.Now - time).TotalMilliseconds}ms"); + }); + } slideCollectionContainer.slideCollection = slideCollection; @@ -358,9 +400,9 @@ namespace NewHorizons.Builder.Props var slideCollection = new SlideCollection(slidesCount); // TODO: uh I think that info.slides[i].playTimeDuration is not being read here... note to self for when I implement support for that: 0.7 is what to default to if playTimeDuration turns out to be 0 slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null - var imageLoader = StartAsyncLoader(mod, info.slides, ref slideCollection); - imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) => - { + var (_, _, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection); + imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) => + { var time = DateTime.Now; slideCollection.slides[index]._image = tex; NHLogger.LogVerbose($"Slide reel set time {(DateTime.Now - time).TotalMilliseconds}ms"); @@ -398,9 +440,9 @@ namespace NewHorizons.Builder.Props // Set some required properties on the torch var mindSlideProjector = standingTorch.GetComponent(); mindSlideProjector._mindProjectorImageEffect = SearchUtilities.Find("Player_Body/PlayerCamera").GetComponent(); - + // Setup for visually supporting async texture loading - mindSlideProjector.enabled = false; + mindSlideProjector.enabled = false; var visionBeamEffect = standingTorch.FindChild("VisionBeam"); visionBeamEffect.SetActive(false); @@ -411,7 +453,7 @@ namespace NewHorizons.Builder.Props var slideCollection = new SlideCollection(slidesCount); slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null - var imageLoader = StartAsyncLoader(mod, slides, ref slideCollection); + var (_, _, imageLoader) = StartAsyncLoader(mod, slides, ref slideCollection); // This variable just lets us track how many of the slides have been loaded. // This way as soon as the last one is loaded (due to async loading, this may be @@ -419,7 +461,7 @@ namespace NewHorizons.Builder.Props // to avoid doing a "is every element in the array `slideCollection.slides` not null" check every time a texture finishes loading int displaySlidesLoaded = 0; imageLoader.imageLoadedEvent.AddListener( - (Texture2D tex, int index, string originalPath) => + (Texture2D tex, int index, string originalPath) => { var time = DateTime.Now; slideCollection.slides[index]._image = tex; @@ -454,7 +496,8 @@ namespace NewHorizons.Builder.Props return standingTorch; } - private static SlideReelAsyncImageLoader StartAsyncLoader(IModBehaviour mod, SlideInfo[] slides, ref SlideCollection slideCollection) + private static (SlideReelAsyncImageLoader inverted, SlideReelAsyncImageLoader atlas, SlideReelAsyncImageLoader slides) + StartAsyncLoader(IModBehaviour mod, SlideInfo[] slides, ref SlideCollection slideCollection) { var invertedImageLoader = new SlideReelAsyncImageLoader(); var atlasImageLoader = new SlideReelAsyncImageLoader(); @@ -462,19 +505,15 @@ namespace NewHorizons.Builder.Props var atlasKey = GetUniqueSlideReelID(mod, slides); - // attempt to load atlas guy from disk and precache so theres a cache hit when using ImageUtilities - atlasImageLoader.PathsToLoad.Add((0, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ATLAS_SLIDE_CACHE_FOLDER, $"{atlasKey}.png"))); - atlasImageLoader.imageLoadedEvent.AddListener((Texture2D t, int i, string s) => + var cacheExists = Directory.Exists(Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ATLAS_SLIDE_CACHE_FOLDER)); + + NHLogger.Log($"Does cache exist for slide reels? {cacheExists}"); + + if (cacheExists) { - NHLogger.Log($"SLIDE REEL ATLAS from {slides.First().imagePath}: {s}"); - ImageUtilities.TrackCachedTexture(atlasKey, t); - }); - invertedImageLoader.imageLoadedEvent.AddListener((Texture2D t, int i, string s) => - { - var path = Path.Combine(mod.ModHelper.Manifest.ModFolderPath, slides[i].imagePath); - var key = $"{ImageUtilities.GetKey(path)} > invert"; - ImageUtilities.TrackCachedTexture(key, t); - }); + // Load the atlas texture used to draw onto the physical slide reel object + atlasImageLoader.PathsToLoad.Add((0, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ATLAS_SLIDE_CACHE_FOLDER, $"{atlasKey}.png"))); + } for (int i = 0; i < slides.Length; i++) { @@ -488,8 +527,11 @@ namespace NewHorizons.Builder.Props } else { - // attempt to load inverted guy from disk and precache so theres a cache hit when using ImageUtilities - invertedImageLoader.PathsToLoad.Add((i, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, INVERTED_SLIDE_CACHE_FOLDER, slideInfo.imagePath))); + if (cacheExists) + { + // Load the inverted images used when displaying slide reels to a screen + invertedImageLoader.PathsToLoad.Add((i, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, INVERTED_SLIDE_CACHE_FOLDER, slideInfo.imagePath))); + } imageLoader.PathsToLoad.Add((i, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, slideInfo.imagePath))); } @@ -497,13 +539,25 @@ namespace NewHorizons.Builder.Props slideCollection.slides[i] = slide; } - // Loaders go sequentually - Load the inverted textures to the cache so that ImageUtilities will reuse them later - invertedImageLoader.Start(true); - // Atlas texture next so that the normal iamgeLoader knows not to regenerate them unless they were missing - atlasImageLoader.Start(false); - imageLoader.Start(true); - return imageLoader; + if (cacheExists) + { + // This code will execute in order to create the cache + // Loaders go sequentually - Load the inverted textures to the cache so that ImageUtilities will reuse them later + invertedImageLoader.Start(true); + // Atlas texture next so that the normal iamgeLoader knows not to regenerate them unless they were missing + atlasImageLoader.Start(false); + imageLoader.Start(true); + + return (invertedImageLoader, atlasImageLoader, imageLoader); + } + else + { + // Will be slow and create the cache + imageLoader.Start(true); + + return (null, null, imageLoader); + } } private static void AddModules(SlideInfo slideInfo, ref Slide slide, IModBehaviour mod) @@ -569,7 +623,7 @@ namespace NewHorizons.Builder.Props Slide.WriteModules(modules, ref slide._modulesList, ref slide._modulesData, ref slide.lengths); } - + private static void LinkShipLogFacts(ProjectionInfo info, SlideCollectionContainer slideCollectionContainer) { // Idk why but it wants reveals to be comma delimited not a list diff --git a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs index 36e8a8f9..cf0b4139 100644 --- a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs +++ b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs @@ -143,6 +143,11 @@ public class SlideReelAsyncImageLoader public void Load(SlideReelAsyncImageLoader loader) { + StartCoroutine(loader.DownloadTextures()); + + return; + + // Sequential _loaders.Enqueue(loader); if (!_isLoading) { From 879b98bf2ebf71dd2c87b29c884bca10bf366b68 Mon Sep 17 00:00:00 2001 From: Nick Date: Fri, 14 Jun 2024 21:54:07 -0400 Subject: [PATCH 02/10] Remove unused sequential loading --- .../Files/SlideReelAsyncImageLoader.cs | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs index cf0b4139..b9a8c152 100644 --- a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs +++ b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs @@ -124,10 +124,6 @@ public class SlideReelAsyncImageLoader { public static SingletonSlideReelAsyncImageLoader Instance { get; private set; } - private Queue _loaders = new(); - - private bool _isLoading; - public void Awake() { Instance = this; @@ -137,36 +133,11 @@ public class SlideReelAsyncImageLoader private void OnSceneUnloaded(Scene _) { StopAllCoroutines(); - _loaders.Clear(); - _isLoading = false; } public void Load(SlideReelAsyncImageLoader loader) { StartCoroutine(loader.DownloadTextures()); - - return; - - // Sequential - _loaders.Enqueue(loader); - if (!_isLoading) - { - StartCoroutine(Run()); - } - } - - private IEnumerator Run() - { - NHLogger.Log("Loading slide reels"); - _isLoading = true; - while (_loaders.Count > 0) - { - var loader = _loaders.Dequeue(); - yield return loader.DownloadTextures(); - NHLogger.Log($"Finished a slide reel, {_loaders.Count} left"); - } - _isLoading = false; - NHLogger.Log("Done loading slide reels"); } } } \ No newline at end of file From 396adcdbc6b5a770ffb3a69a8a8991368e8a305a Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Fri, 14 Jun 2024 23:02:03 -0700 Subject: [PATCH 03/10] PathToUrl --- NewHorizons/Utility/Files/AudioUtilities.cs | 4 ++-- .../Utility/Files/SlideReelAsyncImageLoader.cs | 2 +- NewHorizons/Utility/NewHorizonExtensions.cs | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/NewHorizons/Utility/Files/AudioUtilities.cs b/NewHorizons/Utility/Files/AudioUtilities.cs index ca01b44a..008145a6 100644 --- a/NewHorizons/Utility/Files/AudioUtilities.cs +++ b/NewHorizons/Utility/Files/AudioUtilities.cs @@ -108,7 +108,7 @@ namespace NewHorizons.Utility.Files { DownloadHandlerAudioClip dh = new DownloadHandlerAudioClip(path, UnityEngine.AudioType.MPEG); dh.compressed = true; - using (UnityWebRequest www = new UnityWebRequest(path, "GET", dh, null)) + using (UnityWebRequest www = new UnityWebRequest(path.PathToUrl(), "GET", dh, null)) { var result = www.SendWebRequest(); @@ -127,7 +127,7 @@ namespace NewHorizons.Utility.Files } else { - using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path, audioType)) + using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path.PathToUrl(), audioType)) { var result = www.SendWebRequest(); diff --git a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs index b9a8c152..acf5d92e 100644 --- a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs +++ b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs @@ -83,7 +83,7 @@ public class SlideReelAsyncImageLoader yield break; } - using UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url); + using UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url.PathToUrl()); yield return uwr.SendWebRequest(); diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index e11609f3..c3faf81c 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -1,3 +1,4 @@ +using HarmonyLib; using NewHorizons.External.Configs; using NewHorizons.External.Modules.VariableSize; using NewHorizons.External.SerializableData; @@ -15,6 +16,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Xml; using UnityEngine; +using UnityEngine.Networking; using static NewHorizons.External.Modules.ParticleFieldModule; using NomaiCoordinates = NewHorizons.External.Configs.StarSystemConfig.NomaiCoordinates; @@ -425,5 +427,17 @@ namespace NewHorizons.Utility playerCameraEffectController._owCamera.postProcessingSettings.bloom.threshold = 0f; playerCameraEffectController._owCamera.postProcessingSettings.eyeMaskEnabled = true; } + + /// + /// unity is STUPID and makes us use UnityWebRequest stuff. + /// so we have to do this to let it work with special characters. + /// + public static string PathToUrl(this string url) => + $"file:///{url + .Replace('\\', '/') + .Split('/') + .Select(UnityWebRequest.EscapeURL) + .Join(delimiter: "/") + }"; } } From 95116061f38eb0ba3f303a65b6273ecab3e62058 Mon Sep 17 00:00:00 2001 From: Noah Pilarski Date: Sat, 15 Jun 2024 02:48:13 -0400 Subject: [PATCH 04/10] Move further up --- NewHorizons/Utility/Files/AudioUtilities.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NewHorizons/Utility/Files/AudioUtilities.cs b/NewHorizons/Utility/Files/AudioUtilities.cs index 008145a6..71936221 100644 --- a/NewHorizons/Utility/Files/AudioUtilities.cs +++ b/NewHorizons/Utility/Files/AudioUtilities.cs @@ -103,12 +103,12 @@ namespace NewHorizons.Utility.Files return null; } - path = $"file:///{path.Replace("+", "%2B")}"; + path = path.PathToUrl(); if (audioType == UnityEngine.AudioType.MPEG) { DownloadHandlerAudioClip dh = new DownloadHandlerAudioClip(path, UnityEngine.AudioType.MPEG); dh.compressed = true; - using (UnityWebRequest www = new UnityWebRequest(path.PathToUrl(), "GET", dh, null)) + using (UnityWebRequest www = new UnityWebRequest(path, "GET", dh, null)) { var result = www.SendWebRequest(); @@ -127,7 +127,7 @@ namespace NewHorizons.Utility.Files } else { - using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path.PathToUrl(), audioType)) + using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path, audioType)) { var result = www.SendWebRequest(); From e12d357c1d3f0d7e2144b9366f22c2784a304f0e Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 17 Jun 2024 13:32:11 -0700 Subject: [PATCH 05/10] Revert "Move further up" This reverts commit 95116061f38eb0ba3f303a65b6273ecab3e62058. --- NewHorizons/Utility/Files/AudioUtilities.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NewHorizons/Utility/Files/AudioUtilities.cs b/NewHorizons/Utility/Files/AudioUtilities.cs index 71936221..008145a6 100644 --- a/NewHorizons/Utility/Files/AudioUtilities.cs +++ b/NewHorizons/Utility/Files/AudioUtilities.cs @@ -103,12 +103,12 @@ namespace NewHorizons.Utility.Files return null; } - path = path.PathToUrl(); + path = $"file:///{path.Replace("+", "%2B")}"; if (audioType == UnityEngine.AudioType.MPEG) { DownloadHandlerAudioClip dh = new DownloadHandlerAudioClip(path, UnityEngine.AudioType.MPEG); dh.compressed = true; - using (UnityWebRequest www = new UnityWebRequest(path, "GET", dh, null)) + using (UnityWebRequest www = new UnityWebRequest(path.PathToUrl(), "GET", dh, null)) { var result = www.SendWebRequest(); @@ -127,7 +127,7 @@ namespace NewHorizons.Utility.Files } else { - using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path, audioType)) + using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path.PathToUrl(), audioType)) { var result = www.SendWebRequest(); From 6eed6642f4b2bdb255b3536d8189e4774fe48bd6 Mon Sep 17 00:00:00 2001 From: JohnCorby Date: Mon, 17 Jun 2024 13:32:11 -0700 Subject: [PATCH 06/10] Revert "PathToUrl" This reverts commit 396adcdbc6b5a770ffb3a69a8a8991368e8a305a. --- NewHorizons/Utility/Files/AudioUtilities.cs | 4 ++-- .../Utility/Files/SlideReelAsyncImageLoader.cs | 2 +- NewHorizons/Utility/NewHorizonExtensions.cs | 14 -------------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/NewHorizons/Utility/Files/AudioUtilities.cs b/NewHorizons/Utility/Files/AudioUtilities.cs index 008145a6..ca01b44a 100644 --- a/NewHorizons/Utility/Files/AudioUtilities.cs +++ b/NewHorizons/Utility/Files/AudioUtilities.cs @@ -108,7 +108,7 @@ namespace NewHorizons.Utility.Files { DownloadHandlerAudioClip dh = new DownloadHandlerAudioClip(path, UnityEngine.AudioType.MPEG); dh.compressed = true; - using (UnityWebRequest www = new UnityWebRequest(path.PathToUrl(), "GET", dh, null)) + using (UnityWebRequest www = new UnityWebRequest(path, "GET", dh, null)) { var result = www.SendWebRequest(); @@ -127,7 +127,7 @@ namespace NewHorizons.Utility.Files } else { - using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path.PathToUrl(), audioType)) + using (UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip(path, audioType)) { var result = www.SendWebRequest(); diff --git a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs index acf5d92e..b9a8c152 100644 --- a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs +++ b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs @@ -83,7 +83,7 @@ public class SlideReelAsyncImageLoader yield break; } - using UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url.PathToUrl()); + using UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(url); yield return uwr.SendWebRequest(); diff --git a/NewHorizons/Utility/NewHorizonExtensions.cs b/NewHorizons/Utility/NewHorizonExtensions.cs index c3faf81c..e11609f3 100644 --- a/NewHorizons/Utility/NewHorizonExtensions.cs +++ b/NewHorizons/Utility/NewHorizonExtensions.cs @@ -1,4 +1,3 @@ -using HarmonyLib; using NewHorizons.External.Configs; using NewHorizons.External.Modules.VariableSize; using NewHorizons.External.SerializableData; @@ -16,7 +15,6 @@ using System.Text; using System.Text.RegularExpressions; using System.Xml; using UnityEngine; -using UnityEngine.Networking; using static NewHorizons.External.Modules.ParticleFieldModule; using NomaiCoordinates = NewHorizons.External.Configs.StarSystemConfig.NomaiCoordinates; @@ -427,17 +425,5 @@ namespace NewHorizons.Utility playerCameraEffectController._owCamera.postProcessingSettings.bloom.threshold = 0f; playerCameraEffectController._owCamera.postProcessingSettings.eyeMaskEnabled = true; } - - /// - /// unity is STUPID and makes us use UnityWebRequest stuff. - /// so we have to do this to let it work with special characters. - /// - public static string PathToUrl(this string url) => - $"file:///{url - .Replace('\\', '/') - .Split('/') - .Select(UnityWebRequest.EscapeURL) - .Join(delimiter: "/") - }"; } } From 0f433fc6d3fbe1d6826b454ef9c78bbdd830b843 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 17 Jun 2024 17:35:51 -0400 Subject: [PATCH 07/10] Fixed slide reels not working after first loop --- NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs index b9a8c152..83a93361 100644 --- a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs +++ b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs @@ -78,7 +78,7 @@ public class SlideReelAsyncImageLoader var key = ImageUtilities.GetKey(url); if (ImageUtilities.CheckCachedTexture(key, out var existingTexture)) { - NHLogger.LogVerbose($"Already loaded image {index}:{url}"); + NHLogger.LogVerbose($"Already loaded image {index}:{url} with key {key}"); imageLoadedEvent?.Invoke((Texture2D)existingTexture, index, url); yield break; } @@ -137,7 +137,10 @@ public class SlideReelAsyncImageLoader public void Load(SlideReelAsyncImageLoader loader) { - StartCoroutine(loader.DownloadTextures()); + Delay.FireOnNextUpdate(() => + { + StartCoroutine(loader.DownloadTextures()); + }); } } } \ No newline at end of file From a946d87cdcbbd1020e3f8c6eba7c4a3126f02bb7 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 17 Jun 2024 17:37:21 -0400 Subject: [PATCH 08/10] Update SlideReelAsyncImageLoader.cs --- NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs index 83a93361..297660f1 100644 --- a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs +++ b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs @@ -137,6 +137,7 @@ public class SlideReelAsyncImageLoader public void Load(SlideReelAsyncImageLoader loader) { + // Delay at least one frame to let things subscribe to the event before it fires Delay.FireOnNextUpdate(() => { StartCoroutine(loader.DownloadTextures()); From 50db88ecbe0282ed44f8d31514c9394991bfbae7 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 17 Jun 2024 17:58:03 -0400 Subject: [PATCH 09/10] Load all slides async --- .../Utility/Files/SlideReelAsyncImageLoader.cs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs index 297660f1..840255c4 100644 --- a/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs +++ b/NewHorizons/Utility/Files/SlideReelAsyncImageLoader.cs @@ -63,16 +63,6 @@ public class SlideReelAsyncImageLoader } } - private IEnumerator DownloadTextures() - { - foreach (var (index, path) in PathsToLoad) - { - NHLogger.LogVerbose($"Loaded slide reel {index} of {PathsToLoad.Count}"); - - yield return DownloadTexture(path, index); - } - } - private IEnumerator DownloadTexture(string url, int index) { var key = ImageUtilities.GetKey(url); @@ -140,7 +130,12 @@ public class SlideReelAsyncImageLoader // Delay at least one frame to let things subscribe to the event before it fires Delay.FireOnNextUpdate(() => { - StartCoroutine(loader.DownloadTextures()); + foreach (var (index, path) in loader.PathsToLoad) + { + NHLogger.LogVerbose($"Loaded slide reel {index} of {loader.PathsToLoad.Count}"); + + StartCoroutine(loader.DownloadTexture(path, index)); + } }); } } From dd05a79b1cb3bf62324500459085ad8d39c22226 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 17 Jun 2024 18:06:25 -0400 Subject: [PATCH 10/10] Don't try to load cache for vision reels --- NewHorizons/Builder/Props/ProjectionBuilder.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index 08e2b88c..37ee118c 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -149,7 +149,7 @@ namespace NewHorizons.Builder.Props // We can fit 16 slides max into an atlas var textures = new Texture2D[slidesCount > 16 ? 16 : slidesCount]; - var (invImageLoader, atlasImageLoader, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection); + var (invImageLoader, atlasImageLoader, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection, true); var key = GetUniqueSlideReelID(mod, info.slides); @@ -344,7 +344,7 @@ namespace NewHorizons.Builder.Props var slideCollection = new SlideCollection(slidesCount); slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null - var (invImageLoader, _, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection); + var (invImageLoader, _, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection, true); if (invImageLoader != null) { // Loaded directly from cache @@ -400,7 +400,7 @@ namespace NewHorizons.Builder.Props var slideCollection = new SlideCollection(slidesCount); // TODO: uh I think that info.slides[i].playTimeDuration is not being read here... note to self for when I implement support for that: 0.7 is what to default to if playTimeDuration turns out to be 0 slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null - var (_, _, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection); + var (_, _, imageLoader) = StartAsyncLoader(mod, info.slides, ref slideCollection, false); imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index, string originalPath) => { var time = DateTime.Now; @@ -453,7 +453,7 @@ namespace NewHorizons.Builder.Props var slideCollection = new SlideCollection(slidesCount); slideCollection.streamingAssetIdentifier = string.Empty; // NREs if null - var (_, _, imageLoader) = StartAsyncLoader(mod, slides, ref slideCollection); + var (_, _, imageLoader) = StartAsyncLoader(mod, slides, ref slideCollection, false); // This variable just lets us track how many of the slides have been loaded. // This way as soon as the last one is loaded (due to async loading, this may be @@ -497,7 +497,7 @@ namespace NewHorizons.Builder.Props } private static (SlideReelAsyncImageLoader inverted, SlideReelAsyncImageLoader atlas, SlideReelAsyncImageLoader slides) - StartAsyncLoader(IModBehaviour mod, SlideInfo[] slides, ref SlideCollection slideCollection) + StartAsyncLoader(IModBehaviour mod, SlideInfo[] slides, ref SlideCollection slideCollection, bool useCache) { var invertedImageLoader = new SlideReelAsyncImageLoader(); var atlasImageLoader = new SlideReelAsyncImageLoader(); @@ -509,7 +509,7 @@ namespace NewHorizons.Builder.Props NHLogger.Log($"Does cache exist for slide reels? {cacheExists}"); - if (cacheExists) + if (useCache && cacheExists) { // Load the atlas texture used to draw onto the physical slide reel object atlasImageLoader.PathsToLoad.Add((0, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, ATLAS_SLIDE_CACHE_FOLDER, $"{atlasKey}.png"))); @@ -527,7 +527,7 @@ namespace NewHorizons.Builder.Props } else { - if (cacheExists) + if (useCache && cacheExists) { // Load the inverted images used when displaying slide reels to a screen invertedImageLoader.PathsToLoad.Add((i, Path.Combine(mod.ModHelper.Manifest.ModFolderPath, INVERTED_SLIDE_CACHE_FOLDER, slideInfo.imagePath))); @@ -540,7 +540,7 @@ namespace NewHorizons.Builder.Props slideCollection.slides[i] = slide; } - if (cacheExists) + if (useCache && cacheExists) { // This code will execute in order to create the cache // Loaders go sequentually - Load the inverted textures to the cache so that ImageUtilities will reuse them later @@ -553,7 +553,7 @@ namespace NewHorizons.Builder.Props } else { - // Will be slow and create the cache + // Will be slow and create the cache if needed imageLoader.Start(true); return (null, null, imageLoader);