public Task(ParallelSandbox sandbox, PendingBranch pendingBranch) : base(false, true) { m_sandbox = sandbox; m_pendingBranches.Add(pendingBranch); while (m_pendingCursor < m_pendingBranches.Count) { m_currentBranch = m_pendingBranches[m_pendingCursor++]; bool aborted = false; if (m_currentBranch.Root != null) { CurrentBranchDepth = m_currentBranch.Depth; CurrentBranchOrder = m_currentBranch.Order; m_currentBranch.Root.OverrideController(this); aborted = !m_currentBranch.Root.RunTurnFromMainPhase(m_currentBranch.Response); } else { CurrentBranchDepth = 0; CurrentBranchOrder = 0; m_currentBranch.Root = m_sandbox.RootGame.CloneWithController(this); aborted = !m_currentBranch.Root.RunTurn(); } if (!aborted) { m_sandbox.AddResult(m_currentBranch.Root, m_currentBranch.ChoicePath); } } }
protected override void NoteBranch(PendingBranch pending, BoundNode gotoStmt, BoundStatement targetStmt) { targetStmt.AssertIsLabeledStatement(); if (!gotoStmt.WasCompilerGenerated && !targetStmt.WasCompilerGenerated && RegionContains(targetStmt.Syntax.Span) && !RegionContains(gotoStmt.Syntax.Span)) { _entryPoints.Add((LabeledStatementSyntax)targetStmt.Syntax); } }
protected override void ResolveBranch(PendingBranch pending, LabelSymbol label, BoundStatement target, ref bool labelStateChanged) { // branches into a region are considered entry points if (IsInside && pending.Branch != null && !RegionContains(pending.Branch.Syntax.Span)) { pending.State = pending.State.Reachable ? TopState() : UnreachableState(); } base.ResolveBranch(pending, label, target, ref labelStateChanged); }
protected override void ResolveBranch(PendingBranch pending, LabelSymbol label, BoundStatement target, ref bool labelStateChanged) { // branches into a region are considered entry points if (IsInside && pending.Branch != null && !RegionContains(pending.Branch.Syntax.Span)) { pending.State = pending.State.Reachable ? ReachableState() : UnreachableState(); } base.ResolveBranch(pending, label, target, ref labelStateChanged); }
protected override void NoteBranch( PendingBranch pending, BoundNode gotoStmt, BoundStatement targetStmt) { targetStmt.AssertIsLabeledStatement(); if (!gotoStmt.WasCompilerGenerated && !targetStmt.WasCompilerGenerated && !RegionContains(gotoStmt.Syntax.Span) && RegionContains(targetStmt.Syntax.Span)) { pending.State = ResetState(pending.State); } base.NoteBranch(pending, gotoStmt, targetStmt); }
protected override void StartBranch(PendingBranch branch) { Tpl.Task.Factory.StartNew(() => new Task(this, branch), Tpl.TaskCreationOptions.AttachedToParent); }
protected override void NoteBranch(PendingBranch pending, BoundStatement gotoStmt, BoundStatement targetStmt) { targetStmt.AssertIsLabeledStatement(); if (!gotoStmt.WasCompilerGenerated && !targetStmt.WasCompilerGenerated && RegionContains(targetStmt.Syntax.Span) && !RegionContains(gotoStmt.Syntax.Span)) entryPoints.Add((LabeledStatementSyntax)targetStmt.Syntax); }
private void OnInteraction(Interactions.BaseInteraction io, IEnumerable<Choice> choices) { ++CurrentBranchDepth; if (!ChoiceMade) { var mainPhase = io as Interactions.TacticalPhase; PendingBranch firstBranch = null; foreach (var choice in choices) { if (mainPhase != null && choice is KillBranchChoice) { continue; } var branch = ForkBranch(choice); if (mainPhase != null) { // create save point branch.Root = io.Game.Clone(); branch.Depth = CurrentBranchDepth; branch.Order = Math.Max(choice.Order, CurrentBranchOrder); if (choice is PlayCardChoice) { branch.Response = mainPhase.CompiledRespondPlay( mainPhase.PlayCardCandidates[(choice as PlayCardChoice).CardIndex]); } else if (choice is ActivateAssistChoice) { branch.Response = mainPhase.CompiledRespondActivate( mainPhase.ActivateAssistCandidates[(choice as ActivateAssistChoice).CardIndex]); } else if (choice is CastSpellChoice) { branch.Response = mainPhase.CompiledRespondCast( mainPhase.CastSpellCandidates[(choice as CastSpellChoice).SpellIndex]); } else if (choice is SacrificeChoice) { branch.Response = mainPhase.CompiledRespondSacrifice( mainPhase.SacrificeCandidates[(choice as SacrificeChoice).CardIndex]); } else if (choice is RedeemChoice) { branch.Response = mainPhase.CompiledRespondRedeem( mainPhase.RedeemCandidates[(choice as RedeemChoice).CardIndex]); } else if (choice is AttackCardChoice) { branch.Response = mainPhase.CompiledRespondAttackCard( mainPhase.AttackerCandidates[(choice as AttackCardChoice).AttackerIndex], mainPhase.DefenderCandidates[(choice as AttackCardChoice).DefenderIndex]); } else if (choice is AttackPlayerChoice) { branch.Response = mainPhase.CompiledRespondAttackPlayer( mainPhase.AttackerCandidates[(choice as AttackPlayerChoice).AttackerIndex], mainPhase.Game.Players[(choice as AttackPlayerChoice).PlayerIndex]); } else if (choice is PassChoice) { branch.Response = mainPhase.CompiledRespondPass(); } } if (firstBranch == null) { firstBranch = branch; } else { if (m_pendingBranches.Count < BatchSize) { m_pendingBranches.Add(branch); } else { m_sandbox.StartBranch(branch); } } } if (firstBranch != null) { m_currentBranch = firstBranch; } } if (ChoiceMade) { var nextChoice = NextChoice; nextChoice.Make(io); CurrentBranchOrder = Math.Max(nextChoice.Order, CurrentBranchOrder); } else { // no choice generated System.Diagnostics.Debug.Assert(io is Interactions.TacticalPhase); (io as Interactions.TacticalPhase).RespondAbort(); } }
private bool TryMoveNextBranch() { // discard the current choice path if (m_pendingBranches.Count > 0) { m_currentBranch = m_pendingBranches[0]; m_pendingBranches.RemoveAt(0); return true; } return false; }
protected abstract void StartBranch(PendingBranch branch);
protected override void StartBranch(PendingBranch branch) { s_stp.QueueWorkItem(() => new Task(this, branch)); }