From 3f4b2fbe885138ecc84a9f76310d179dd4a71ecd Mon Sep 17 00:00:00 2001 From: FreezeDriedMangoes Date: Wed, 25 May 2022 11:04:53 -0400 Subject: [PATCH] added async texture loading to autoprojectors and slide reels, also removed some dead code and uneeded comments --- .../Builder/Props/ProjectionBuilder.cs | 75 +++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/NewHorizons/Builder/Props/ProjectionBuilder.cs b/NewHorizons/Builder/Props/ProjectionBuilder.cs index b1228f90..10963bac 100644 --- a/NewHorizons/Builder/Props/ProjectionBuilder.cs +++ b/NewHorizons/Builder/Props/ProjectionBuilder.cs @@ -62,21 +62,51 @@ namespace NewHorizons.Builder.Props // The base game ones only have 15 slides max var textures = new Texture2D[slidesCount >= 15 ? 15 : slidesCount]; + var imageLoader = slideReelObj.AddComponent(); for (int i = 0; i < slidesCount; i++) { var slide = new Slide(); var slideInfo = info.slides[i]; - var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); - slide.textureOverride = ImageUtilities.Invert(texture); - - // Track the first 15 to put on the slide reel object - if (i < 15) textures[i] = texture; + imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide); slideCollection.slides[i] = slide; - } + } + + // 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) => + { + slideCollection.slides[index].textureOverride = ImageUtilities.Invert(tex); + + // Track the first 15 to put on the slide reel object + if (index < 15) + { + textures[index] = tex; + displaySlidesLoaded++; // threading moment + } + + if (displaySlidesLoaded >= textures.Length) + { + // all textures required to build the reel's textures have been loaded + var slidesBack = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Back").GetComponent(); + var slidesFront = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Front").GetComponent(); + + // Now put together the textures into a 4x4 thing for the materials + var reelTexture = ImageUtilities.MakeReelTexture(textures); + slidesBack.material.mainTexture = reelTexture; + slidesBack.material.SetTexture(EmissionMap, reelTexture); + slidesFront.material.mainTexture = reelTexture; + slidesFront.material.SetTexture(EmissionMap, reelTexture); + } + } + ); // Else when you put them down you can't pick them back up slideReelObj.GetComponent()._physicsRemoved = false; @@ -89,16 +119,6 @@ namespace NewHorizons.Builder.Props OWAssetHandler.LoadObject(slideReelObj); sector.OnOccupantEnterSector.AddListener((x) => OWAssetHandler.LoadObject(slideReelObj)); - var slidesBack = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Back").GetComponent(); - var slidesFront = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Front").GetComponent(); - - // Now put together the textures into a 4x4 thing for the materials - var reelTexture = ImageUtilities.MakeReelTexture(textures); - slidesBack.material.mainTexture = reelTexture; - slidesBack.material.SetTexture(EmissionMap, reelTexture); - slidesFront.material.mainTexture = reelTexture; - slidesFront.material.SetTexture(EmissionMap, reelTexture); - slideReelObj.SetActive(true); } @@ -130,19 +150,20 @@ namespace NewHorizons.Builder.Props // Now we replace the slides int slidesCount = info.slides.Length; var slideCollection = new SlideCollection(slidesCount); - + + var imageLoader = projectorObj.AddComponent(); for (int i = 0; i < slidesCount; i++) { var slide = new Slide(); var slideInfo = info.slides[i]; - var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); - slide.textureOverride = ImageUtilities.Invert(texture); + imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide); slideCollection.slides[i] = slide; } + imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index].textureOverride = ImageUtilities.Invert(tex); }); slideCollectionContainer.slideCollection = slideCollection; @@ -177,23 +198,20 @@ namespace NewHorizons.Builder.Props var slidesCount = slides.Length; var slideCollection = new SlideCollection(slidesCount); - + var imageLoader = g.AddComponent(); for (int i = 0; i < slidesCount; i++) { var slide = new Slide(); var slideInfo = slides[i]; - // TODO: do this part asynchronously so that you can load all the slides you want without stalling the game out for 5 days - //var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); - //slide.textureOverride = texture; //ImageUtilities.Invert(texture); imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide); slideCollection.slides[i] = slide; - } - imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index].textureOverride = tex; }); + } + imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index].textureOverride = tex; }); // attatch a component to store all the data for the slides that play when a vision torch scans this target @@ -240,22 +258,19 @@ namespace NewHorizons.Builder.Props var slides = info.slides; var slidesCount = slides.Length; var slideCollection = new SlideCollection(slidesCount); - + var imageLoader = standingTorch.AddComponent(); for (int i = 0; i < slidesCount; i++) { var slide = new Slide(); var slideInfo = slides[i]; - // TODO: do this part asynchronously so that you can load all the slides you want without stalling the game out for 5 days - //var texture = ImageUtilities.GetTexture(mod, slideInfo.imagePath); - //slide.textureOverride = texture; //ImageUtilities.Invert(texture); imageLoader.pathsToLoad.Add(mod.ModHelper.Manifest.ModFolderPath + slideInfo.imagePath); AddModules(slideInfo, ref slide); slideCollection.slides[i] = slide; - } + } imageLoader.imageLoadedEvent.AddListener((Texture2D tex, int index) => { slideCollection.slides[index].textureOverride = tex; }); // set up the containers for the slides