DiamondPanel.WallMasks.cs
using System;
using Sandbox;

namespace Diamonds;

public sealed partial class DiamondPanel
{
	bool drawingReferenceWalls = false;
	static WallStrokeMasks sharedWallMasks;
	WallStrokeMasks wallMasks;

	sealed class WallStrokeMasks : IDisposable
	{
		public readonly Texture[] Textures = new Texture[4];
		public int Users;
		Color[] palette;

		public void Ensure()
		{
			if ( palette == Palette && Array.TrueForAll( Textures, t => t?.IsValid == true ) ) return;
			Dispose();
			try
			{
				for ( int corner = 0; corner < 2; corner++ )
				for ( int layer = 0; layer < 2; layer++ )
				{
					int width = corner == 0 ? 40 : 68;
					using var target = Texture.CreateRenderTarget().WithSize( width * 4, 100 * 4 ).WithFormat( ImageFormat.RGBA8888 ).Create();
					using ( var p = Painter.Begin( target ) )
					{
						p.Clear( Color.Transparent ); p.Scale( 4 ); p.Translate( new Vector2( 6, 50 ) );
						p.Fill = Fill.None; p.Stroke = Stroke.Solid( Color.White, layer == 0 ? 9 : 2 );
						p.Line( [new( 0, -44 ), new( 28, 0 ), new( corner == 0 ? 0 : 56, 44 )] );
					}
					using var bitmap = target.GetBitmap();
					Textures[corner * 2 + layer] = bitmap.ToTexture( false );
				}
				palette = Palette;
			}
			catch { Dispose(); throw; }
		}

		public void Dispose()
		{
			for ( int i = 0; i < Textures.Length; i++ ) { Textures[i]?.Dispose(); Textures[i] = null; }
			palette = null;
		}
	}

	bool DrawWallStrokeMask( Painter p, Vector2 center, float inward, bool corner )
	{
		if ( drawingReferenceWalls ) return false;
		var transform = p.Transform;
		if ( MathF.Max( new Vector2( transform.M11, transform.M12 ).Length, new Vector2( transform.M21, transform.M22 ).Length ) > 4 ) return false;
		if ( wallMasks is null ) { wallMasks = sharedWallMasks ??= new(); wallMasks.Users++; }
		wallMasks.Ensure();
		using var scope = p.Scope();
		p.Translate( center ); p.Scale( new Vector2( inward, 1 ) );
		var bounds = new Rect( -6, -50, corner ? 68 : 40, 100 );
		int index = corner ? 2 : 0;
		p.Texture( wallMasks.Textures[index], bounds, SpikeInk.WithAlpha( 0.08f + Board.LockFlash * 0.18f ) );
		p.Texture( wallMasks.Textures[index + 1], bounds, SpikeInk );
		return true;
	}

	void ReleaseWallMasks()
	{
		if ( wallMasks is null ) return;
		if ( --wallMasks.Users == 0 )
		{
			wallMasks.Dispose();
			if ( ReferenceEquals( sharedWallMasks, wallMasks ) ) sharedWallMasks = null;
		}
		wallMasks = null;
	}
}