Editor-side role interfaces and static facades for architectural fixture tools. Defines interfaces for ladders, balconies, and wall modifications, and provides static helper classes that locate a single role implementation via ArchRoles.One<T>() which constructs concrete role types.
using System.Collections.Generic;
namespace Sunless.Architecture;
// What the fixture tool authors that it does not own. Each role previews its own draft and places it, because the
// shape a preview draws belongs to the role and the fixture tool has no business resolving one. An unanswered role
// is a fixture that simply cannot be stood, rather than an error.
public interface IArchLadders
{
bool Preview( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchLadderPart draft );
ArchLadderPart Place( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchLadderPart draft, out ArchBuilding host );
// Handed the buildings, because a recipe hangs a ladder on a building not yet filed in the plan.
ArchLadderPart Place( IEnumerable<ArchBuilding> buildings, ArchPlan plan, ArchKit kit, Vector2 point, ArchLadderPart draft, out ArchBuilding host );
}
public interface IArchBalconies
{
bool Preview( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchBalconyPart draft );
ArchBalconyPart Place( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchBalconyPart draft, out ArchBuilding host );
void Remove( ArchPlan plan, ArchBuilding building, ArchBalconyPart balcony );
}
// What a recess or a proud pier takes out of a wall, drawn by the module that cuts it - a block is a stack of slabs
// on either face, not a box, so the role draws its own ghost rather than handing back an envelope.
public interface IArchWallMods
{
bool Preview( ArchWallModPart part, ArchWall wall, ArchKit kit, float wallHeight, float floor );
}
public static class ArchLadders
{
static IArchLadders Load() => ArchRoles.One<IArchLadders>();
public static bool Preview( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchLadderPart draft )
{
return Load()?.Preview( plan, kit, at, draft ) == true;
}
public static ArchLadderPart Place( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchLadderPart draft, out ArchBuilding host )
{
if ( Load() is not { } ladders )
{
host = null;
return null;
}
return ladders.Place( plan, kit, at, draft, out host );
}
public static ArchLadderPart Place( IEnumerable<ArchBuilding> buildings, ArchPlan plan, ArchKit kit, Vector2 point, ArchLadderPart draft, out ArchBuilding host )
{
if ( Load() is not { } ladders )
{
host = null;
return null;
}
return ladders.Place( buildings, plan, kit, point, draft, out host );
}
}
public static class ArchBalconies
{
static IArchBalconies Load() => ArchRoles.One<IArchBalconies>();
public static bool Preview( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchBalconyPart draft )
{
return Load()?.Preview( plan, kit, at, draft ) == true;
}
public static ArchBalconyPart Place( ArchPlan plan, ArchKit kit, ArchFixtureStation? at, ArchBalconyPart draft, out ArchBuilding host )
{
if ( Load() is not { } balconies )
{
host = null;
return null;
}
return balconies.Place( plan, kit, at, draft, out host );
}
public static void Remove( ArchPlan plan, ArchBuilding building, ArchBalconyPart balcony )
{
Load()?.Remove( plan, building, balcony );
}
}
public static class ArchWallModBlocks
{
public static bool Preview( ArchWallModPart part, ArchWall wall, ArchKit kit, float wallHeight, float floor )
{
return ArchRoles.One<IArchWallMods>() is { } mods && mods.Preview( part, wall, kit, wallHeight, floor );
}
}
// The single-implementation half of ArchAnswers, for roles a caller reaches with no table of its own. A role
// nothing answers hands back null, which every caller falls back from rather than erroring.
public static class ArchRoles
{
public static T One<T>() where T : class => Answering( typeof( T ) ) as T;
static object Answering( Type role )
{
if ( role == typeof( IArchWallForms ) ) return new ArchWallFormsRole();
if ( role == typeof( IArchWallMods ) ) return new ArchWallModRole();
if ( role == typeof( IArchBalconies ) ) return new ArchBalconyRole();
if ( role == typeof( IArchLadders ) ) return new ArchLadderRole();
if ( role == typeof( IArchFlightBuilder ) ) return new ArchFlightBuilder();
if ( role == typeof( IArchWellEdges ) ) return new ArchStairWellEdges();
if ( role == typeof( IArchPiercer ) ) return new ArchStairPiercer();
if ( role == typeof( IArchHostCarving ) ) return new ArchStairHostCarving();
if ( role == typeof( IArchExteriorStairs ) ) return new ArchExteriorStairAuthoring();
return null;
}
}