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;
}
}