Fix race conditions with slide textures loading (#382)

## Bug fixes
- This fixes race conditions when incrementing `displaySlidesLoaded`
becaise `++` isn't thread safe. In the case of `MakeSlideReel`, another
issue was fixed that happens even without parallelism: `if
(displaySlidesLoaded >= textures.Length)` would always be true after
some point and multiple reel textures would be created. But with
parallelism, it's possible for `displaySlidesLoaded` to never reach
`textures.Length` and in this case the texture wouldn't be created (or
the vision torch enabled). Sadly this doesn't change behavior for vision
targets, so this is unrelated to #381
This commit is contained in:
Nick 2022-09-13 20:14:57 -04:00 committed by GitHub
commit 6bc5ca24a7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,9 +5,9 @@ using OWML.Common;
using OWML.Common.Menus;
using System;
using System.Collections.Generic;
using System.Threading;
using System.IO;
using UnityEngine;
using static NewHorizons.External.Modules.PropModule;
using Logger = NewHorizons.Utility.Logger;
namespace NewHorizons.Builder.Props
{
@ -104,24 +104,22 @@ namespace NewHorizons.Builder.Props
slideCollection.slides[index]._image = ImageUtilities.Invert(tex);
// Track the first 15 to put on the slide reel object
if (index < 15)
if (index < textures.Length)
{
textures[index] = tex;
displaySlidesLoaded++; // threading moment
}
if (Interlocked.Increment(ref 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<MeshRenderer>();
var slidesFront = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Front").GetComponent<MeshRenderer>();
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<MeshRenderer>();
var slidesFront = slideReelObj.transform.Find("Props_IP_SlideReel_7/Slides_Front").GetComponent<MeshRenderer>();
// 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);
// 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);
}
}
}
);
@ -309,9 +307,8 @@ namespace NewHorizons.Builder.Props
(Texture2D tex, int index) =>
{
slideCollection.slides[index]._image = tex;
displaySlidesLoaded++; // threading moment
if (displaySlidesLoaded >= slides.Length)
if (Interlocked.Increment(ref displaySlidesLoaded) == slides.Length)
{
mindSlideProjector.enabled = true;
visionBeamEffect.SetActive(true);