fixing NPE in CCombat.getCombatDescription. CCombat is given its own copy of combat that cannot be taken away by a different thread.

This commit is contained in:
Maxmtg
2013-06-27 08:39:13 +00:00
parent 67ee42dcda
commit 82bb17ebf9
7 changed files with 20 additions and 19 deletions

View File

@@ -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);

View File

@@ -74,7 +74,7 @@ public class FControlGameEventHandler extends IGameEventVisitor.Base<Void> {
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;
}

View File

@@ -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<AttackingBand> abs : attackedEntities.values())
for (final AttackingBand band : abs) {
if (band.isEmpty()) continue; // there should not be empty bands
if (band.isEmpty()) continue;
Collection<Card> 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<Card> attackers = getAttackersBlockedBy(blocker);

View File

@@ -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} */

View File

@@ -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;
}

View File

@@ -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()

View File

@@ -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");