Editor/Layers/ArchLayerGate.cs

A small static utility that tracks the currently active ArchLayerTree during a scoped operation. It provides Begin to set the active tree within a IDisposable scope, and predicates On, Owned and Enabled<T> that check whether payloads or owner IDs are enabled by the active tree.

using System;
using System.Collections.Generic;
using System.Linq;

namespace Sunless.Architecture;

// The one answer to "does this authored layer generate?", ambient for the length of a build because a
// disabled opening has to stop cutting inside the wall generator, four calls below anything holding a tree.
// Nothing here writes the plan: a disabled layer keeps its record and the effects it owns, they just
// stop being read, so re-enabling gives back the identical hole.
public static class ArchLayerGate
{
	static ArchLayerTree standing;

	public static IDisposable Begin( ArchLayerTree tree ) => new Scope( tree );

	// No tree means nothing could have been disabled - a designer stage generates everything.
	public static bool On( object payload ) => standing is null || standing.IsEnabled( payload );

	// An effect - a stairwell, a walkway mouth - stands only while the layer that OWNS it does. An
	// unowned one was authored by hand and answers to nobody.
	public static bool Owned( int ownerId ) => ownerId == 0 || standing is null || standing.IsEnabled( ownerId );

	public static IEnumerable<T> Enabled<T>( IEnumerable<T> parts ) where T : class => parts.Where( On );

	sealed class Scope : IDisposable
	{
		readonly ArchLayerTree restored;

		public Scope( ArchLayerTree tree )
		{
			restored = standing;
			standing = tree;
		}

		public void Dispose() => standing = restored;
	}
}