Optimize check for state-based effects to avoid creating a new HashSet unnecessary

This commit is contained in:
drdev
2014-10-20 22:39:47 +00:00
parent 7d8a0829ba
commit 9ec5497321
3 changed files with 17 additions and 21 deletions

View File

@@ -21,8 +21,6 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import forge.GameCommand; import forge.GameCommand;
import forge.card.CardStateName; import forge.card.CardStateName;
import forge.card.CardType; import forge.card.CardType;
@@ -636,11 +634,14 @@ public class GameAction {
return affectedCards; return affectedCards;
} }
public final Set<Card> checkStateEffects(final boolean runEvents) { public final void checkStateEffects(final boolean runEvents) {
checkStateEffects(runEvents, new HashSet<Card>());
}
public final void checkStateEffects(final boolean runEvents, final Set<Card> allAffectedCards) {
// sol(10/29) added for Phase updates, state effects shouldn't be // sol(10/29) added for Phase updates, state effects shouldn't be
// checked during Spell Resolution (except when persist-returning // checked during Spell Resolution (except when persist-returning
if (game.getStack().isResolving()) { if (game.getStack().isResolving()) {
return Collections.emptySet(); return;
} }
// final JFrame frame = Singletons.getView().getFrame(); // final JFrame frame = Singletons.getView().getFrame();
@@ -649,7 +650,7 @@ public class GameAction {
// } // }
if (game.isGameOver()) { if (game.isGameOver()) {
return Collections.emptySet(); return;
} }
// Max: I don't know where to put this! - but since it's a state based action, it must be in check state effects // Max: I don't know where to put this! - but since it's a state based action, it must be in check state effects
@@ -662,9 +663,7 @@ public class GameAction {
game.getStack().setFrozen(true); game.getStack().setFrozen(true);
TrackableObject.freeze(); //prevent views flickering during while updating for state-based effects TrackableObject.freeze(); //prevent views flickering during while updating for state-based effects
// do this multiple times, sometimes creatures/permanents will survive // do this multiple times, sometimes creatures/permanents will survive when they shouldn't
// when they shouldn't
final Set<Card> allAffectedCards = Sets.newHashSet();
for (int q = 0; q < 9; q++) { for (int q = 0; q < 9; q++) {
final Set<Card> affectedCards = checkStaticAbilities(false); final Set<Card> affectedCards = checkStaticAbilities(false);
boolean checkAgain = false; boolean checkAgain = false;
@@ -775,14 +774,12 @@ public class GameAction {
checkGameOverCondition(); checkGameOverCondition();
if (game.getAge() != GameStage.Play) { if (game.getAge() != GameStage.Play) {
return Collections.emptySet(); return;
} }
game.getTriggerHandler().resetActiveTriggers(); game.getTriggerHandler().resetActiveTriggers();
if (!refreeze) { if (!refreeze) {
game.getStack().unfreezeStack(); game.getStack().unfreezeStack();
} }
return allAffectedCards;
} }
private boolean stateBasedAction704_5n(Card c) { private boolean stateBasedAction704_5n(Card c) {

View File

@@ -17,7 +17,6 @@ public class EndTurnEffect extends SpellAbilityEffect {
*/ */
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
Game game = sa.getActivatingPlayer().getGame(); Game game = sa.getActivatingPlayer().getGame();
// Steps taken from gatherer's rulings on Time Stop. // Steps taken from gatherer's rulings on Time Stop.
// 1) All spells and abilities on the stack are exiled. This includes // 1) All spells and abilities on the stack are exiled. This includes

View File

@@ -19,8 +19,6 @@ package forge.game.phase;
import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.*; import forge.game.*;
import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityFactory;
@@ -852,6 +850,8 @@ public class PhaseHandler implements java.io.Serializable {
// don't even offer priority, because it's untap of 1st turn now // don't even offer priority, because it's untap of 1st turn now
givePriorityToPlayer = false; givePriorityToPlayer = false;
final Set<Card> allAffectedCards = new HashSet<Card>();
// MAIN GAME LOOP // MAIN GAME LOOP
while (!game.isGameOver()) { while (!game.isGameOver()) {
if (givePriorityToPlayer) { if (givePriorityToPlayer) {
@@ -864,18 +864,18 @@ public class PhaseHandler implements java.io.Serializable {
int loopCount = 0; int loopCount = 0;
do { do {
final Set<Card> allAffectedCards = Sets.newHashSet(); do {
boolean addedAnythingToStack = false;
do {
// Rule 704.3 Whenever a player would get priority, the game checks ... for state-based actions, // Rule 704.3 Whenever a player would get priority, the game checks ... for state-based actions,
allAffectedCards.addAll(game.getAction().checkStateEffects(false)); game.getAction().checkStateEffects(false, allAffectedCards);
if (game.isGameOver()) { if (game.isGameOver()) {
return; // state-based effects check could lead to game over return; // state-based effects check could lead to game over
} }
addedAnythingToStack = game.getStack().addAllTriggeredAbilitiesToStack(); } while (game.getStack().addAllTriggeredAbilitiesToStack()); //loop so long as something was added to stack
} while (addedAnythingToStack);
game.fireEvent(new GameEventCardStatsChanged(allAffectedCards)); if (!allAffectedCards.isEmpty()) {
game.fireEvent(new GameEventCardStatsChanged(allAffectedCards));
allAffectedCards.clear();
}
if (playerTurn.hasLost() && pPlayerPriority.equals(playerTurn) && pFirstPriority.equals(playerTurn)) { if (playerTurn.hasLost() && pPlayerPriority.equals(playerTurn) && pFirstPriority.equals(playerTurn)) {
// If the active player has lost, and they have priority, set the next player to have priority // If the active player has lost, and they have priority, set the next player to have priority