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.InitNetwork] = new InitNetworkHandler(),
|
||||||
[NetworkBattleUri.InitBattle] = new InitBattleHandler(),
|
[NetworkBattleUri.InitBattle] = new InitBattleHandler(),
|
||||||
[NetworkBattleUri.Loaded] = new LoadedHandler(),
|
[NetworkBattleUri.Loaded] = new LoadedHandler(),
|
||||||
|
[NetworkBattleUri.Swap] = new SwapHandler(),
|
||||||
};
|
};
|
||||||
|
|
||||||
private FrameDispatchContext BuildContext(IBattleParticipant from, MsgEnvelope env) =>
|
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