refactor(battle-node): extract SwapHandler (mulligan barrier)
This commit is contained in:
@@ -39,6 +39,7 @@ public sealed class BattleSession
|
||||
[NetworkBattleUri.InitNetwork] = new InitNetworkHandler(),
|
||||
[NetworkBattleUri.InitBattle] = new InitBattleHandler(),
|
||||
[NetworkBattleUri.Loaded] = new LoadedHandler(),
|
||||
[NetworkBattleUri.Swap] = new SwapHandler(),
|
||||
};
|
||||
|
||||
private FrameDispatchContext BuildContext(IBattleParticipant from, MsgEnvelope env) =>
|
||||
|
||||
39
SVSim.BattleNode/Sessions/Dispatch/Handlers/SwapHandler.cs
Normal file
39
SVSim.BattleNode/Sessions/Dispatch/Handlers/SwapHandler.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using SVSim.BattleNode.Lifecycle;
|
||||
using SVSim.BattleNode.Protocol;
|
||||
using SVSim.BattleNode.Sessions.Participants; // IHasHandshakePhase
|
||||
|
||||
namespace SVSim.BattleNode.Sessions.Dispatch.Handlers;
|
||||
|
||||
internal sealed class SwapHandler : IFrameHandler
|
||||
{
|
||||
public IReadOnlyList<DispatchRoute> Handle(FrameDispatchContext ctx)
|
||||
{
|
||||
if (ctx.SenderPhase != BattleSessionPhase.AwaitingSwap)
|
||||
return Array.Empty<DispatchRoute>();
|
||||
|
||||
var routes = new List<DispatchRoute>();
|
||||
var hand = ScriptedLifecycle.ComputeHandAfterSwap(BattleFrames.ExtractIdxList(ctx.Env));
|
||||
|
||||
// SwapResponse is always immediate — completes the sender's own mulligan UI.
|
||||
routes.Add(new DispatchRoute(ctx.From, ScriptedLifecycle.BuildSwapResponse(hand), false));
|
||||
ctx.State.PostSwapHands[ctx.From] = hand;
|
||||
ctx.SenderPhase = BattleSessionPhase.AfterReady;
|
||||
|
||||
// Release Ready to every swapper once all handshake-driving participants have swapped.
|
||||
// IHasHandshakePhase membership IS the "participates in mulligan" set.
|
||||
var swappers = new[] { ctx.A, ctx.B }.Where(p => p is IHasHandshakePhase).ToList();
|
||||
if (swappers.All(ctx.State.PostSwapHands.ContainsKey))
|
||||
{
|
||||
foreach (var p in swappers)
|
||||
{
|
||||
var opponent = ReferenceEquals(p, ctx.A) ? ctx.B : ctx.A;
|
||||
var ready = opponent is IHasHandshakePhase
|
||||
&& ctx.State.PostSwapHands.TryGetValue(opponent, out var oppoHand)
|
||||
? ScriptedLifecycle.BuildReady(ctx.State.PostSwapHands[p], oppoHand)
|
||||
: ScriptedLifecycle.BuildReady(ctx.State.PostSwapHands[p]);
|
||||
routes.Add(new DispatchRoute(p, ready, false));
|
||||
}
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user