mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Added syncPoint between a moment when Game thread adds input to stack and EDT->showMessage, to ensure Game thread's changes happen-before whatever EDT will read
input/InputAttack.java is initialized with combat instead of game (cosmtic change though) CMatchUI stopAtPhase will use an existing method to get the needed checkBox
This commit is contained in:
@@ -88,11 +88,19 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
|
||||
|
||||
public void setInputAndWait(InputSynchronized input) {
|
||||
this.inputStack.push(input);
|
||||
syncPoint();
|
||||
this.updateObservers();
|
||||
|
||||
input.awaitLatchRelease();
|
||||
}
|
||||
|
||||
|
||||
public void syncPoint() {
|
||||
synchronized (inputLock) {
|
||||
// acquire and release lock, so that actions from Game thread happen before EDT reads their results
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Write javadoc for this method.
|
||||
*/
|
||||
|
||||
@@ -493,7 +493,7 @@ public class PlayerControllerHuman extends PlayerController {
|
||||
|
||||
case COMBAT_DECLARE_ATTACKERS:
|
||||
game.getCombat().initiatePossibleDefenders(player.getOpponents());
|
||||
InputSynchronized inpAttack = new InputAttack(player);
|
||||
InputSynchronized inpAttack = new InputAttack(player, game.getCombat());
|
||||
Singletons.getControl().getInputQueue().setInputAndWait(inpAttack);
|
||||
return;
|
||||
|
||||
|
||||
@@ -62,6 +62,7 @@ public class InputProxy implements Observer {
|
||||
Runnable showMessage = new Runnable() {
|
||||
@Override public void run() {
|
||||
Input current = getInput();
|
||||
Singletons.getControl().getInputQueue().syncPoint();
|
||||
//System.out.printf("\t%s > showMessage @ %s/%s during %s%n", FThreads.debugGetCurrThreadId(), nextInput.getClass().getSimpleName(), current.getClass().getSimpleName(), game.getPhaseHandler().debugPrintState());
|
||||
current.showMessageInitial();
|
||||
}
|
||||
|
||||
@@ -26,10 +26,9 @@ import com.google.common.collect.Iterables;
|
||||
import forge.Card;
|
||||
import forge.CardPredicates;
|
||||
import forge.GameEntity;
|
||||
import forge.game.Game;
|
||||
import forge.game.phase.Combat;
|
||||
import forge.game.phase.CombatUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.MyObservable;
|
||||
import forge.view.ButtonUtil;
|
||||
@@ -47,14 +46,15 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
private static final long serialVersionUID = 7849903731842214245L;
|
||||
|
||||
|
||||
private final Game game;
|
||||
private List<GameEntity> defenders;
|
||||
private final Combat combat;
|
||||
private final List<GameEntity> defenders;
|
||||
private GameEntity currentDefender;
|
||||
private final Player player;
|
||||
|
||||
public InputAttack(Player human) {
|
||||
player = human;
|
||||
game = human.getGame();
|
||||
public InputAttack(Player human, Combat combat) {
|
||||
this.player = human;
|
||||
this.combat = combat;
|
||||
this.defenders = combat.getDefenders();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
// TODO still seems to have some issues with multiple planeswalkers
|
||||
|
||||
ButtonUtil.enableOnlyOk();
|
||||
defenders = game.getCombat().getDefenders();
|
||||
|
||||
setCurrentDefender(defenders.isEmpty() ? null : defenders.get(0));
|
||||
|
||||
if ( null == currentDefender ) {
|
||||
@@ -78,8 +78,8 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
continue; // do not force
|
||||
|
||||
for(GameEntity def : defenders ) {
|
||||
if( CombatUtil.canAttack(c, def, game.getCombat()) ) {
|
||||
game.getCombat().addAttacker(c, currentDefender);
|
||||
if( CombatUtil.canAttack(c, def, combat) ) {
|
||||
combat.addAttacker(c, currentDefender);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -110,9 +110,9 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected final void onCardSelected(final Card card, boolean isMetaDown) {
|
||||
final List<Card> att = game.getCombat().getAttackers();
|
||||
final List<Card> att = combat.getAttackers();
|
||||
if (isMetaDown && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.")) {
|
||||
game.getCombat().removeFromCombat(card);
|
||||
combat.removeFromCombat(card);
|
||||
showCombat();
|
||||
return;
|
||||
}
|
||||
@@ -128,12 +128,11 @@ public class InputAttack extends InputSyncronizedBase {
|
||||
}
|
||||
}
|
||||
|
||||
Zone zone = game.getZoneOf(card);
|
||||
if (zone.is(ZoneType.Battlefield, player) && CombatUtil.canAttack(card, currentDefender, game.getCombat())) {
|
||||
if( game.getCombat().isAttacking(card)) {
|
||||
game.getCombat().removeFromCombat(card);
|
||||
if (player.getZone(ZoneType.Battlefield).contains(card) && CombatUtil.canAttack(card, currentDefender, combat)) {
|
||||
if( combat.isAttacking(card)) {
|
||||
combat.removeFromCombat(card);
|
||||
}
|
||||
game.getCombat().addAttacker(card, currentDefender);
|
||||
combat.addAttacker(card, currentDefender);
|
||||
showCombat();
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -42,6 +42,7 @@ import forge.gui.match.controllers.CMessage;
|
||||
import forge.gui.match.controllers.CPicture;
|
||||
import forge.gui.match.nonsingleton.VCommand;
|
||||
import forge.gui.match.nonsingleton.VField;
|
||||
import forge.gui.match.nonsingleton.VField.PhaseLabel;
|
||||
import forge.gui.match.nonsingleton.VHand;
|
||||
import forge.gui.match.views.VPlayers;
|
||||
import forge.gui.toolbox.FSkin;
|
||||
@@ -233,23 +234,8 @@ public enum CMatchUI {
|
||||
*/
|
||||
public final boolean stopAtPhase(final Player turn, final PhaseType phase) {
|
||||
VField vf = getFieldViewFor(turn);
|
||||
|
||||
switch (phase) {
|
||||
case UPKEEP: return vf.getLblUpkeep().getEnabled();
|
||||
case DRAW: return vf.getLblDraw().getEnabled();
|
||||
case MAIN1: return vf.getLblMain1().getEnabled();
|
||||
case COMBAT_BEGIN: return vf.getLblBeginCombat().getEnabled();
|
||||
case COMBAT_DECLARE_ATTACKERS: return vf.getLblDeclareAttackers().getEnabled();
|
||||
case COMBAT_DECLARE_BLOCKERS: return vf.getLblDeclareBlockers().getEnabled();
|
||||
case COMBAT_FIRST_STRIKE_DAMAGE: return vf.getLblFirstStrike().getEnabled();
|
||||
case COMBAT_DAMAGE: return vf.getLblCombatDamage().getEnabled();
|
||||
case COMBAT_END: return vf.getLblEndCombat().getEnabled();
|
||||
case MAIN2: return vf.getLblMain2().getEnabled();
|
||||
case END_OF_TURN: return vf.getLblEndTurn().getEnabled();
|
||||
default:
|
||||
}
|
||||
|
||||
return true;
|
||||
PhaseLabel label = vf.getLabelFor(phase);
|
||||
return label == null || label.isTurnedOn();
|
||||
}
|
||||
|
||||
public void setCard(final Card c) {
|
||||
|
||||
Reference in New Issue
Block a user