mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 11:18: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) {
|
public void setInputAndWait(InputSynchronized input) {
|
||||||
this.inputStack.push(input);
|
this.inputStack.push(input);
|
||||||
|
syncPoint();
|
||||||
this.updateObservers();
|
this.updateObservers();
|
||||||
|
|
||||||
input.awaitLatchRelease();
|
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.
|
* TODO: Write javadoc for this method.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ public class PlayerControllerHuman extends PlayerController {
|
|||||||
|
|
||||||
case COMBAT_DECLARE_ATTACKERS:
|
case COMBAT_DECLARE_ATTACKERS:
|
||||||
game.getCombat().initiatePossibleDefenders(player.getOpponents());
|
game.getCombat().initiatePossibleDefenders(player.getOpponents());
|
||||||
InputSynchronized inpAttack = new InputAttack(player);
|
InputSynchronized inpAttack = new InputAttack(player, game.getCombat());
|
||||||
Singletons.getControl().getInputQueue().setInputAndWait(inpAttack);
|
Singletons.getControl().getInputQueue().setInputAndWait(inpAttack);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ public class InputProxy implements Observer {
|
|||||||
Runnable showMessage = new Runnable() {
|
Runnable showMessage = new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
Input current = getInput();
|
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());
|
//System.out.printf("\t%s > showMessage @ %s/%s during %s%n", FThreads.debugGetCurrThreadId(), nextInput.getClass().getSimpleName(), current.getClass().getSimpleName(), game.getPhaseHandler().debugPrintState());
|
||||||
current.showMessageInitial();
|
current.showMessageInitial();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,9 @@ import com.google.common.collect.Iterables;
|
|||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.game.Game;
|
import forge.game.phase.Combat;
|
||||||
import forge.game.phase.CombatUtil;
|
import forge.game.phase.CombatUtil;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.Zone;
|
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.util.MyObservable;
|
import forge.util.MyObservable;
|
||||||
import forge.view.ButtonUtil;
|
import forge.view.ButtonUtil;
|
||||||
@@ -47,14 +46,15 @@ public class InputAttack extends InputSyncronizedBase {
|
|||||||
private static final long serialVersionUID = 7849903731842214245L;
|
private static final long serialVersionUID = 7849903731842214245L;
|
||||||
|
|
||||||
|
|
||||||
private final Game game;
|
private final Combat combat;
|
||||||
private List<GameEntity> defenders;
|
private final List<GameEntity> defenders;
|
||||||
private GameEntity currentDefender;
|
private GameEntity currentDefender;
|
||||||
private final Player player;
|
private final Player player;
|
||||||
|
|
||||||
public InputAttack(Player human) {
|
public InputAttack(Player human, Combat combat) {
|
||||||
player = human;
|
this.player = human;
|
||||||
game = human.getGame();
|
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
|
// TODO still seems to have some issues with multiple planeswalkers
|
||||||
|
|
||||||
ButtonUtil.enableOnlyOk();
|
ButtonUtil.enableOnlyOk();
|
||||||
defenders = game.getCombat().getDefenders();
|
|
||||||
setCurrentDefender(defenders.isEmpty() ? null : defenders.get(0));
|
setCurrentDefender(defenders.isEmpty() ? null : defenders.get(0));
|
||||||
|
|
||||||
if ( null == currentDefender ) {
|
if ( null == currentDefender ) {
|
||||||
@@ -78,8 +78,8 @@ public class InputAttack extends InputSyncronizedBase {
|
|||||||
continue; // do not force
|
continue; // do not force
|
||||||
|
|
||||||
for(GameEntity def : defenders ) {
|
for(GameEntity def : defenders ) {
|
||||||
if( CombatUtil.canAttack(c, def, game.getCombat()) ) {
|
if( CombatUtil.canAttack(c, def, combat) ) {
|
||||||
game.getCombat().addAttacker(c, currentDefender);
|
combat.addAttacker(c, currentDefender);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,9 +110,9 @@ public class InputAttack extends InputSyncronizedBase {
|
|||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
protected final void onCardSelected(final Card card, boolean isMetaDown) {
|
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.")) {
|
if (isMetaDown && att.contains(card) && !card.hasKeyword("CARDNAME attacks each turn if able.")) {
|
||||||
game.getCombat().removeFromCombat(card);
|
combat.removeFromCombat(card);
|
||||||
showCombat();
|
showCombat();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -128,12 +128,11 @@ public class InputAttack extends InputSyncronizedBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Zone zone = game.getZoneOf(card);
|
if (player.getZone(ZoneType.Battlefield).contains(card) && CombatUtil.canAttack(card, currentDefender, combat)) {
|
||||||
if (zone.is(ZoneType.Battlefield, player) && CombatUtil.canAttack(card, currentDefender, game.getCombat())) {
|
if( combat.isAttacking(card)) {
|
||||||
if( game.getCombat().isAttacking(card)) {
|
combat.removeFromCombat(card);
|
||||||
game.getCombat().removeFromCombat(card);
|
|
||||||
}
|
}
|
||||||
game.getCombat().addAttacker(card, currentDefender);
|
combat.addAttacker(card, currentDefender);
|
||||||
showCombat();
|
showCombat();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import forge.gui.match.controllers.CMessage;
|
|||||||
import forge.gui.match.controllers.CPicture;
|
import forge.gui.match.controllers.CPicture;
|
||||||
import forge.gui.match.nonsingleton.VCommand;
|
import forge.gui.match.nonsingleton.VCommand;
|
||||||
import forge.gui.match.nonsingleton.VField;
|
import forge.gui.match.nonsingleton.VField;
|
||||||
|
import forge.gui.match.nonsingleton.VField.PhaseLabel;
|
||||||
import forge.gui.match.nonsingleton.VHand;
|
import forge.gui.match.nonsingleton.VHand;
|
||||||
import forge.gui.match.views.VPlayers;
|
import forge.gui.match.views.VPlayers;
|
||||||
import forge.gui.toolbox.FSkin;
|
import forge.gui.toolbox.FSkin;
|
||||||
@@ -233,23 +234,8 @@ public enum CMatchUI {
|
|||||||
*/
|
*/
|
||||||
public final boolean stopAtPhase(final Player turn, final PhaseType phase) {
|
public final boolean stopAtPhase(final Player turn, final PhaseType phase) {
|
||||||
VField vf = getFieldViewFor(turn);
|
VField vf = getFieldViewFor(turn);
|
||||||
|
PhaseLabel label = vf.getLabelFor(phase);
|
||||||
switch (phase) {
|
return label == null || label.isTurnedOn();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCard(final Card c) {
|
public void setCard(final Card c) {
|
||||||
|
|||||||
Reference in New Issue
Block a user