From 82bb17ebf934924c884031c71dc5673325473a2d Mon Sep 17 00:00:00 2001 From: Maxmtg Date: Thu, 27 Jun 2013 08:39:13 +0000 Subject: [PATCH] fixing NPE in CCombat.getCombatDescription. CCombat is given its own copy of combat that cannot be taken away by a different thread. --- src/main/java/forge/control/FControl.java | 2 -- .../forge/control/FControlGameEventHandler.java | 2 +- src/main/java/forge/game/combat/Combat.java | 6 +++--- src/main/java/forge/gui/input/InputAttack.java | 2 +- src/main/java/forge/gui/input/InputBlock.java | 4 ++-- src/main/java/forge/gui/match/CMatchUI.java | 6 ++++-- .../forge/gui/match/controllers/CCombat.java | 17 +++++++++-------- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/main/java/forge/control/FControl.java b/src/main/java/forge/control/FControl.java index 05d74e4b7c3..141b8ba6143 100644 --- a/src/main/java/forge/control/FControl.java +++ b/src/main/java/forge/control/FControl.java @@ -56,7 +56,6 @@ import forge.gui.home.CHomeUI; import forge.gui.home.VHomeUI; import forge.gui.match.CMatchUI; import forge.gui.match.VMatchUI; -import forge.gui.match.controllers.CCombat; import forge.gui.match.controllers.CDock; import forge.gui.match.controllers.CLog; import forge.gui.match.controllers.CMessage; @@ -415,7 +414,6 @@ public enum FControl { CDock.SINGLETON_INSTANCE.setModel(game, humanLobbyPlayer); CStack.SINGLETON_INSTANCE.setModel(game.getStack(), humanLobbyPlayer); CLog.SINGLETON_INSTANCE.setModel(game.getGameLog()); - CCombat.SINGLETON_INSTANCE.setModel(game); CMessage.SINGLETON_INSTANCE.setModel(game); diff --git a/src/main/java/forge/control/FControlGameEventHandler.java b/src/main/java/forge/control/FControlGameEventHandler.java index dc7f38d8f5c..68c17e2bcb9 100644 --- a/src/main/java/forge/control/FControlGameEventHandler.java +++ b/src/main/java/forge/control/FControlGameEventHandler.java @@ -74,7 +74,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base { if ( combatUpdPlanned.getAndSet(true) ) return null; FThreads.invokeInEdtNowOrLater(new Runnable() { @Override public void run() { combatUpdPlanned.set(false); - CMatchUI.SINGLETON_INSTANCE.showCombat(); + CMatchUI.SINGLETON_INSTANCE.showCombat(fc.getObservedGame().getCombat()); } }); return null; } diff --git a/src/main/java/forge/game/combat/Combat.java b/src/main/java/forge/game/combat/Combat.java index bcec8bc5e43..fa771f45d4c 100644 --- a/src/main/java/forge/game/combat/Combat.java +++ b/src/main/java/forge/game/combat/Combat.java @@ -280,11 +280,11 @@ public class Combat { } /** If there are multiple blockers, the Attacker declares the Assignment Order */ - public void orderBlockersForDamageAssignment() { + public void orderBlockersForDamageAssignment() { // this method performs controller's role for(Collection abs : attackedEntities.values()) for (final AttackingBand band : abs) { - if (band.isEmpty()) continue; // there should not be empty bands + if (band.isEmpty()) continue; Collection blockers = blockedBands.get(band); if ( blockers == null || blockers.isEmpty() ) @@ -300,7 +300,7 @@ public class Combat { } } - public void orderAttackersForDamageAssignment() { + public void orderAttackersForDamageAssignment() { // this method performs controller's role // If there are multiple blockers, the Attacker declares the Assignment Order for (final Card blocker : getAllBlockers()) { List attackers = getAttackersBlockedBy(blocker); diff --git a/src/main/java/forge/gui/input/InputAttack.java b/src/main/java/forge/gui/input/InputAttack.java index a1c7c97a0ac..08786350930 100644 --- a/src/main/java/forge/gui/input/InputAttack.java +++ b/src/main/java/forge/gui/input/InputAttack.java @@ -93,7 +93,7 @@ public class InputAttack extends InputSyncronizedBase { private void showCombat() { playerAttacks.getZone(ZoneType.Battlefield).updateObservers(); // redraw sword icons - CMatchUI.SINGLETON_INSTANCE.showCombat(); + CMatchUI.SINGLETON_INSTANCE.showCombat(combat); } /** {@inheritDoc} */ diff --git a/src/main/java/forge/gui/input/InputBlock.java b/src/main/java/forge/gui/input/InputBlock.java index 4f2038a8403..401b85a0592 100644 --- a/src/main/java/forge/gui/input/InputBlock.java +++ b/src/main/java/forge/gui/input/InputBlock.java @@ -79,7 +79,7 @@ public class InputBlock extends InputSyncronizedBase { showMessage(sb.toString()); } - CMatchUI.SINGLETON_INSTANCE.showCombat(); + CMatchUI.SINGLETON_INSTANCE.showCombat(combat); } /** {@inheritDoc} */ @@ -102,7 +102,7 @@ public class InputBlock extends InputSyncronizedBase { if (isMetaDown && card.getController() == defender) { combat.removeFromCombat(card); - CMatchUI.SINGLETON_INSTANCE.showCombat(); + CMatchUI.SINGLETON_INSTANCE.showCombat(combat); return; } diff --git a/src/main/java/forge/gui/match/CMatchUI.java b/src/main/java/forge/gui/match/CMatchUI.java index 029dfb36ae2..a6312839e2b 100644 --- a/src/main/java/forge/gui/match/CMatchUI.java +++ b/src/main/java/forge/gui/match/CMatchUI.java @@ -31,6 +31,7 @@ import forge.FThreads; import forge.GameEntity; import forge.ImageCache; import forge.Singletons; +import forge.game.combat.Combat; import forge.game.phase.PhaseType; import forge.game.player.LobbyPlayer; import forge.game.player.Player; @@ -260,10 +261,11 @@ public enum CMatchUI { } - public void showCombat() { - if (Singletons.getControl().getObservedGame().getPhaseHandler().inCombat()) { + public void showCombat(Combat combat) { + if (combat != null) { SDisplayUtil.showTab(EDocID.REPORT_COMBAT.getDoc()); } + CCombat.SINGLETON_INSTANCE.setModel(combat); CCombat.SINGLETON_INSTANCE.update(); } // showBlockers() diff --git a/src/main/java/forge/gui/match/controllers/CCombat.java b/src/main/java/forge/gui/match/controllers/CCombat.java index 735b7df782d..b9379ccc114 100644 --- a/src/main/java/forge/gui/match/controllers/CCombat.java +++ b/src/main/java/forge/gui/match/controllers/CCombat.java @@ -5,10 +5,8 @@ import java.util.List; import forge.Card; import forge.Command; import forge.GameEntity; -import forge.game.Game; import forge.game.combat.AttackingBand; import forge.game.combat.Combat; -import forge.game.phase.PhaseHandler; import forge.game.player.Player; import forge.gui.framework.ICDoc; import forge.gui.match.views.VCombat; @@ -24,7 +22,7 @@ public enum CCombat implements ICDoc { /** */ SINGLETON_INSTANCE; - private Game game; + private Combat combat; /* (non-Javadoc) * @see forge.gui.framework.ICDoc#getCommandOnSelect() @@ -46,16 +44,16 @@ public enum CCombat implements ICDoc { */ @Override public void update() { - PhaseHandler pH = game.getPhaseHandler(); - if (pH.inCombat()) // display combat - VCombat.SINGLETON_INSTANCE.updateCombat(pH.getCombat().getAttackers().size(), getCombatDescription(pH.getCombat())); + Combat localCombat = this.combat; // noone will re-assign this from other thread. + if (localCombat != null ) + VCombat.SINGLETON_INSTANCE.updateCombat(localCombat.getAttackers().size(), getCombatDescription(localCombat)); else VCombat.SINGLETON_INSTANCE.updateCombat(0, ""); } - public void setModel(Game game) + public void setModel(Combat combat) { - this.game = game; + this.combat = combat; } @@ -83,6 +81,9 @@ public enum CCombat implements ICDoc { // Associate Bands, Attackers Blockers boolean previousBand = false; for(AttackingBand band : bands) { + if (band.isEmpty()) + continue; + // Space out band blocks from non-band blocks if (previousBand) { display.append("\n");