using System.Threading; namespace Sandbox.Resources; public abstract class TextureGenerator : ResourceGenerator { /// /// Find an existing texture for this /// protected virtual ValueTask CreateTexture( Options options, CancellationToken ct ) { return default; } /// /// Create a texture. Will replace a placeholder texture, which will turn into the generated texture later, if it's not immediately available. /// public sealed override Texture Create( Options options ) { var tex = CreateTexture( options, default ); Texture output = default; if ( !tex.IsCompletedSuccessfully ) { // loading async output = Texture.Create( 1, 1 ).WithData( new byte[4] { 0, 0, 0, 0 } ).Finish(); _ = output.ReplacementAsync( tex.AsTask() ); } else { // finished immediately output = tex.Result; } if ( output is null ) return default; output.EmbeddedResource = CreateEmbeddedResource(); return output; } /// /// Create a texture. Will wait until the texture is fully loaded and return when done. /// public sealed override async ValueTask CreateAsync( Options options, CancellationToken token ) { // Call it completely in a new thread var output = await Task.Run( async () => await CreateTexture( options, token ) ); if ( output is null ) return default; token.ThrowIfCancellationRequested(); output.EmbeddedResource = CreateEmbeddedResource(); return output; } public virtual EmbeddedResource? CreateEmbeddedResource() { return new EmbeddedResource { ResourceCompiler = "texture", ResourceGenerator = DisplayInfo.For( this ).ClassName ?? GetType().FullName, Data = Json.SerializeAsObject( this ) }; } }