InputNonSyncBase => InputPassPriority,

stop() method moved to sync'd inputs, asyncs have only pass()
pass() or stop() may be called only once per input presentation (once shown = one and only stop/pass)
This commit is contained in:
Maxmtg
2013-05-25 23:26:15 +00:00
parent 3bdf8d95cc
commit c282b3e28a
21 changed files with 101 additions and 110 deletions

2
.gitattributes vendored
View File

@@ -14159,8 +14159,8 @@ src/main/java/forge/control/input/InputBlock.java svneol=native#text/plain
src/main/java/forge/control/input/InputCleanup.java svneol=native#text/plain src/main/java/forge/control/input/InputCleanup.java svneol=native#text/plain
src/main/java/forge/control/input/InputConfirmMulligan.java svneol=native#text/plain src/main/java/forge/control/input/InputConfirmMulligan.java svneol=native#text/plain
src/main/java/forge/control/input/InputLockUI.java -text src/main/java/forge/control/input/InputLockUI.java -text
src/main/java/forge/control/input/InputNonSyncBase.java -text
src/main/java/forge/control/input/InputPassPriority.java svneol=native#text/plain src/main/java/forge/control/input/InputPassPriority.java svneol=native#text/plain
src/main/java/forge/control/input/InputPassPriorityBase.java -text
src/main/java/forge/control/input/InputPayManaBase.java -text src/main/java/forge/control/input/InputPayManaBase.java -text
src/main/java/forge/control/input/InputPayManaExecuteCommands.java svneol=native#text/plain src/main/java/forge/control/input/InputPayManaExecuteCommands.java svneol=native#text/plain
src/main/java/forge/control/input/InputPayManaOfCostPayment.java -text src/main/java/forge/control/input/InputPayManaOfCostPayment.java -text

View File

@@ -42,7 +42,7 @@ import forge.view.ButtonUtil;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public class InputAttack extends InputNonSyncBase { public class InputAttack extends InputPassPriorityBase {
/** Constant <code>serialVersionUID=7849903731842214245L</code>. */ /** Constant <code>serialVersionUID=7849903731842214245L</code>. */
private static final long serialVersionUID = 7849903731842214245L; private static final long serialVersionUID = 7849903731842214245L;
@@ -96,10 +96,10 @@ public class InputAttack extends InputNonSyncBase {
public final void selectButtonOK() { public final void selectButtonOK() {
// Propaganda costs could have been paid here. // Propaganda costs could have been paid here.
setCurrentDefender(null); // remove highlights setCurrentDefender(null); // remove highlights
game.getPhaseHandler().setCombat(!game.getCombat().getAttackers().isEmpty()); game.getPhaseHandler().setCombat(!game.getCombat().getAttackers().isEmpty());
game.getPhaseHandler().setPlayersPriorityPermission(false); game.getPhaseHandler().setPlayersPriorityPermission(false);
game.getInputQueue().updateObservers();
pass();
} }
@Override @Override

View File

@@ -6,7 +6,7 @@ import forge.game.player.Player;
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public class InputAutoPassPriority extends InputNonSyncBase { public class InputAutoPassPriority extends InputPassPriorityBase {
private static final long serialVersionUID = -7520803307255234647L; private static final long serialVersionUID = -7520803307255234647L;
public InputAutoPassPriority(Player player) { public InputAutoPassPriority(Player player) {
@@ -15,7 +15,7 @@ public class InputAutoPassPriority extends InputNonSyncBase {
@Override @Override
public void showMessage() { public void showMessage() {
passPriority(); pass();
} }
} }

View File

@@ -35,11 +35,15 @@ public abstract class InputBase implements java.io.Serializable, Input {
/** Constant <code>serialVersionUID=-6539552513871194081L</code>. */ /** Constant <code>serialVersionUID=-6539552513871194081L</code>. */
private static final long serialVersionUID = -6539552513871194081L; private static final long serialVersionUID = -6539552513871194081L;
private InputQueue queue; private InputQueue queue;
private boolean finished = false;
protected final boolean isFinished() { return finished; }
protected final void setFinished() { finished = true; }
// showMessage() is always the first method called // showMessage() is always the first method called
@Override @Override
public final void showMessage(InputQueue iq) { public final void showMessage(InputQueue iq) {
queue = iq; queue = iq;
finished = false;
showMessage(); showMessage();
} }
@@ -55,23 +59,18 @@ public abstract class InputBase implements java.io.Serializable, Input {
public void selectButtonCancel() { } public void selectButtonCancel() { }
// to remove need for CMatchUI dependence // to remove need for CMatchUI dependence
protected void showMessage(String message) { protected final void showMessage(String message) {
CMatchUI.SINGLETON_INSTANCE.showMessage(message); CMatchUI.SINGLETON_INSTANCE.showMessage(message);
} }
// Removes this input from the stack and releases any latches (in synchronous imports)
protected final void stop() {
// clears a "temp" Input like Input_PayManaCost if there is one
queue.removeInput(this);
afterStop(); // sync inputs will release their latch there
}
protected void afterStop() { } protected void afterStop() { }
protected final void flashIncorrectAction() { protected final void flashIncorrectAction() {
SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE); SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE);
} }
protected InputQueue getQueue() {
return queue;
}
} }

View File

@@ -37,7 +37,7 @@ import forge.view.ButtonUtil;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public class InputBlock extends InputNonSyncBase { public class InputBlock extends InputPassPriorityBase {
/** Constant <code>serialVersionUID=6120743598368928128L</code>. */ /** Constant <code>serialVersionUID=6120743598368928128L</code>. */
private static final long serialVersionUID = 6120743598368928128L; private static final long serialVersionUID = 6120743598368928128L;
@@ -92,7 +92,7 @@ public class InputBlock extends InputNonSyncBase {
currentAttacker = null; currentAttacker = null;
allBlocking.clear(); allBlocking.clear();
passPriority(); pass();
} }
} }

View File

@@ -31,7 +31,7 @@ import forge.view.ButtonUtil;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public class InputCleanup extends InputNonSyncBase { public class InputCleanup extends InputPassPriorityBase {
/** Constant <code>serialVersionUID=-4164275418971547948L</code>. */ /** Constant <code>serialVersionUID=-4164275418971547948L</code>. */
private static final long serialVersionUID = -4164275418971547948L; private static final long serialVersionUID = -4164275418971547948L;
private final GameState game; private final GameState game;
@@ -55,7 +55,7 @@ public class InputCleanup extends InputNonSyncBase {
final int max = active.getMaxHandSize(); final int max = active.getMaxHandSize();
// goes to the next phase // goes to the next phase
if (active.isUnlimitedHandSize() || n <= max || n <= 0 || active != turnOwner) { if (active.isUnlimitedHandSize() || n <= max || n <= 0 || active != turnOwner) {
passPriority(); pass();
return; return;
} }
ButtonUtil.disableAll(); ButtonUtil.disableAll();

View File

@@ -1,26 +0,0 @@
package forge.control.input;
import forge.FThreads;
import forge.game.player.Player;
public abstract class InputNonSyncBase extends InputBase {
private static final long serialVersionUID = -4038934296796872326L;
protected final Player player;
public InputNonSyncBase(Player p) {
this.player = p;
}
protected void passPriority() {
final Runnable pass = new Runnable() {
@Override public void run() {
player.getController().passPriority();
}
};
if( FThreads.isEDT() )
FThreads.invokeInNewThread(pass);
// player.getGame().getInputQueue().LockAndInvokeGameAction(pass);
else
pass.run();
}
}

View File

@@ -33,10 +33,9 @@ import forge.view.ButtonUtil;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public class InputPassPriority extends InputNonSyncBase { public class InputPassPriority extends InputPassPriorityBase {
/** Constant <code>serialVersionUID=-581477682214137181L</code>. */ /** Constant <code>serialVersionUID=-581477682214137181L</code>. */
private static final long serialVersionUID = -581477682214137181L; private static final long serialVersionUID = -581477682214137181L;
private boolean canUse = false;
/** /**
* TODO: Write javadoc for Constructor. * TODO: Write javadoc for Constructor.
@@ -53,7 +52,6 @@ public class InputPassPriority extends InputNonSyncBase {
p.getZone(ZoneType.Battlefield).updateObservers(); p.getZone(ZoneType.Battlefield).updateObservers();
} }
ButtonUtil.enableOnlyOk(); ButtonUtil.enableOnlyOk();
canUse = true;
final PhaseHandler ph = player.getGame().getPhaseHandler(); final PhaseHandler ph = player.getGame().getPhaseHandler();
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
@@ -77,11 +75,8 @@ public class InputPassPriority extends InputNonSyncBase {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public final void selectButtonOK() { public final void selectButtonOK() {
if( canUse ) { if( isFinished() ) return;
canUse = false; pass();
passPriority();
}
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@@ -0,0 +1,29 @@
package forge.control.input;
import forge.FThreads;
import forge.game.player.Player;
public abstract class InputPassPriorityBase extends InputBase {
private static final long serialVersionUID = -4038934296796872326L;
protected final Player player;
public InputPassPriorityBase(Player p) {
this.player = p;
}
final Runnable passPriority = new Runnable() {
@Override public void run() {
player.getController().passPriority();
}
};
protected final void pass() { // no futher overloads possible
setFinished();
if( FThreads.isEDT() )
FThreads.invokeInNewThread(passPriority);
else
passPriority.run();
}
}

View File

@@ -100,6 +100,8 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
* a boolean. * a boolean.
*/ */
public final void removeInput(Input inp) { public final void removeInput(Input inp) {
FThreads.assertExecutedByEdt(false);
Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop(); Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop();
// StackTraceElement[] trace = Thread.currentThread().getStackTrace(); // StackTraceElement[] trace = Thread.currentThread().getStackTrace();
@@ -153,9 +155,9 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
switch (phase) { switch (phase) {
case COMBAT_DECLARE_ATTACKERS: case COMBAT_DECLARE_ATTACKERS:
stack.freezeStack(); stack.freezeStack();
if (playerTurn.isHuman() && !playerTurn.getController().mayAutoPass(phase)) { if (!playerTurn.getController().mayAutoPass(phase)) {
game.getCombat().initiatePossibleDefenders(playerTurn.getOpponents()); game.getCombat().initiatePossibleDefenders(playerTurn.getOpponents());
return new InputAttack(playerTurn); return playerTurn.getController().getAttackInput();
} }
break; break;
@@ -215,10 +217,10 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
} }
public void LockAndInvokeGameAction(final Runnable proc) { public void LockAndInvokeGameAction(final Runnable proc) {
this.lock();
Runnable toRun = new Runnable() { Runnable toRun = new Runnable() {
@Override @Override
public void run() { public void run() {
InputQueue.this.lock();
proc.run(); proc.run();
InputQueue.this.unlock(); InputQueue.this.unlock();
} }

View File

@@ -9,7 +9,7 @@ import forge.error.BugReporter;
public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized { public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized {
private static final long serialVersionUID = 8756177361251703052L; private static final long serialVersionUID = 8756177361251703052L;
private boolean finished = false;
private final CountDownLatch cdlDone; private final CountDownLatch cdlDone;
@@ -27,32 +27,35 @@ public abstract class InputSyncronizedBase extends InputBase implements InputSyn
} }
@Override protected final void stop() {
protected void afterStop() { setFinished();
finished = true; FThreads.invokeInNewThread(new Runnable() {
cdlDone.countDown(); @Override
public void run() {
getQueue().removeInput(InputSyncronizedBase.this);
cdlDone.countDown();
}
});
} }
@Override @Override
public final void selectButtonCancel() { public final void selectButtonCancel() {
if( finished ) return; if( isFinished() ) return;
onCancel(); onCancel();
} }
@Override @Override
public final void selectButtonOK() { public final void selectButtonOK() {
if( finished ) return; if( isFinished() ) return;
onOk(); onOk();
} }
@Override @Override
public final void selectCard(Card c, boolean isMetaDown) { public final void selectCard(Card c, boolean isMetaDown) {
if( finished ) return; if( isFinished() ) return;
onCardSelected(c); onCardSelected(c);
} }
protected final boolean isFinished() { return finished; }
protected void onCardSelected(Card c) {} protected void onCardSelected(Card c) {}
protected void onCancel() {} protected void onCancel() {}
protected void onOk() {} protected void onOk() {}

View File

@@ -125,14 +125,14 @@ public class MatchController {
final Player firstPlayer = determineFirstTurnPlayer(getLastGameOutcome(), currentGame); final Player firstPlayer = determineFirstTurnPlayer(getLastGameOutcome(), currentGame);
currentGame.getInputQueue().clearInput();
if(currentGame.getType() == GameType.Planechase)
firstPlayer.initPlane();
// This code was run from EDT. // This code was run from EDT.
FThreads.invokeInNewThread( new Runnable() { FThreads.invokeInNewThread( new Runnable() {
@Override @Override
public void run() { public void run() {
currentGame.getInputQueue().clearInput();
if(currentGame.getType() == GameType.Planechase)
firstPlayer.initPlane();
currentGame.getAction().mulligan(firstPlayer); currentGame.getAction().mulligan(firstPlayer);
} }
}); });

View File

@@ -848,7 +848,6 @@ public class AiController {
break; break;
} }
} }
player.getController().passPriority();
} }

View File

@@ -3,7 +3,7 @@ package forge.game.ai;
import java.util.List; import java.util.List;
import forge.Card; import forge.Card;
import forge.control.input.InputNonSyncBase; import forge.control.input.InputPassPriorityBase;
import forge.game.GameState; import forge.game.GameState;
import forge.game.phase.CombatUtil; import forge.game.phase.CombatUtil;
import forge.game.player.Player; import forge.game.player.Player;
@@ -12,7 +12,7 @@ import forge.game.player.Player;
* TODO: Write javadoc for this type. * TODO: Write javadoc for this type.
* *
*/ */
public class AiInputBlock extends InputNonSyncBase { public class AiInputBlock extends InputPassPriorityBase {
private final GameState game; private final GameState game;
/** /**
* TODO: Write javadoc for Constructor. * TODO: Write javadoc for Constructor.
@@ -32,9 +32,6 @@ public class AiInputBlock extends InputNonSyncBase {
final List<Card> blockers = player.getCreaturesInPlay(); final List<Card> blockers = player.getCreaturesInPlay();
game.setCombat(ComputerUtilBlock.getBlockers(player, game.getCombat(), blockers)); game.setCombat(ComputerUtilBlock.getBlockers(player, game.getCombat(), blockers));
CombatUtil.orderMultipleCombatants(game); CombatUtil.orderMultipleCombatants(game);
game.getPhaseHandler().setPlayersPriorityPermission(false); pass();
// was not added to stack, so will be replaced by plain update
game.getInputQueue().updateObservers();
} }
} }

View File

@@ -17,7 +17,7 @@
*/ */
package forge.game.ai; package forge.game.ai;
import forge.control.input.InputNonSyncBase; import forge.control.input.InputPassPriorityBase;
/** /**
* <p> * <p>
@@ -27,7 +27,7 @@ import forge.control.input.InputNonSyncBase;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public class AiInputCommon extends InputNonSyncBase implements AiInput { public class AiInputCommon extends InputPassPriorityBase implements AiInput {
/** Constant <code>serialVersionUID=-3091338639571662216L</code>. */ /** Constant <code>serialVersionUID=-3091338639571662216L</code>. */
private static final long serialVersionUID = -3091338639571662216L; private static final long serialVersionUID = -3091338639571662216L;
@@ -71,6 +71,7 @@ public class AiInputCommon extends InputNonSyncBase implements AiInput {
@Override @Override
public void run() { public void run() {
computer.onPriorityRecieved(); computer.onPriorityRecieved();
pass();
} }
}; };
} }

View File

@@ -232,29 +232,11 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
} }
public final void handleBeginPhase() { public final void handleBeginPhase() {
this.setPhaseEffects(false);
if ( FThreads.isEDT() ) {
System.out.printf("Handle begin %s phase of %s turn from EDT%n", phase, playerTurn);
FThreads.invokeInNewThread(beginPhase);
} else {
beginPhase.run();
}
}
private final Runnable beginPhase = new Runnable() { @Override public void run() {
doBeginPhase();
updateObservers();
} };
/**
* <p>
* handleBeginPhase.
* </p>
*/
private final void doBeginPhase() {
if (null == playerTurn) { if (null == playerTurn) {
return; return;
} }
this.setPhaseEffects(false);
// Handle effects that happen at the beginning of phases // Handle effects that happen at the beginning of phases
game.getAction().checkStateEffects(); game.getAction().checkStateEffects();
@@ -263,7 +245,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
case UNTAP: case UNTAP:
//SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc()); //SDisplayUtil.showTab(EDocID.REPORT_STACK.getDoc());
game.getPhaseHandler().setPlayersPriorityPermission(false); game.getPhaseHandler().setPlayersPriorityPermission(false);
updateObservers(); //updateObservers();
PhaseUtil.handleUntap(game); PhaseUtil.handleUntap(game);
break; break;
@@ -307,7 +289,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
if (playerTurn.isSkippingCombat()) { if (playerTurn.isSkippingCombat()) {
this.setPlayersPriorityPermission(false); this.setPlayersPriorityPermission(false);
playerTurn.removeKeyword("Skip your next combat phase."); playerTurn.removeKeyword("Skip your next combat phase.");
} } /* else game.getInputQueue().setInput(playerTurn.getController().getAttackInput());*/
break; break;
case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY: case COMBAT_DECLARE_ATTACKERS_INSTANT_ABILITY:
@@ -836,8 +818,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
*/ */
public final void setPhaseState(final PhaseType phase0) { public final void setPhaseState(final PhaseType phase0) {
this.phase = phase0; this.phase = phase0;
this.setPhaseEffects(false); this.handleBeginPhase();
this.doBeginPhase();
} }
/** /**

View File

@@ -45,6 +45,8 @@ public abstract class PlayerController {
public abstract Input getDefaultInput(); public abstract Input getDefaultInput();
public abstract Input getBlockInput(); public abstract Input getBlockInput();
public abstract Input getCleanupInput(); public abstract Input getCleanupInput();
public abstract Input getAttackInput();
public final Input getAutoPassPriorityInput() { return autoPassPriorityInput; } public final Input getAutoPassPriorityInput() { return autoPassPriorityInput; }
/** /**

View File

@@ -65,6 +65,11 @@ public class PlayerControllerAi extends PlayerController {
return blockInput; return blockInput;
} }
@Override
public Input getAttackInput() {
return defaultInput;
}
/** /**
* @return the cleanupInput * @return the cleanupInput
*/ */

View File

@@ -19,6 +19,7 @@ import forge.card.spellability.SpellAbility;
import forge.card.spellability.Target; import forge.card.spellability.Target;
import forge.card.spellability.TargetSelection; import forge.card.spellability.TargetSelection;
import forge.control.input.Input; import forge.control.input.Input;
import forge.control.input.InputAttack;
import forge.control.input.InputBlock; import forge.control.input.InputBlock;
import forge.control.input.InputCleanup; import forge.control.input.InputCleanup;
import forge.control.input.InputConfirmMulligan; import forge.control.input.InputConfirmMulligan;
@@ -67,6 +68,9 @@ public class PlayerControllerHuman extends PlayerController {
return blockInput; return blockInput;
} }
@Override
public Input getAttackInput() { return new InputAttack(player); }
/** /**
* @return the cleanupInput * @return the cleanupInput
*/ */

View File

@@ -522,7 +522,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
} }
} }
if (this.getSimultaneousStackEntryList().size() > 0) { if (!this.getSimultaneousStackEntryList().isEmpty()) {
game.getPhaseHandler().passPriority(); game.getPhaseHandler().passPriority();
} }
} }

View File

@@ -54,6 +54,7 @@ public class InputProxy implements Observer {
@Override @Override
public final synchronized void update(final Observable observable, final Object obj) { public final synchronized void update(final Observable observable, final Object obj) {
//synchronized(this) {} // want to update all changes to memory //synchronized(this) {} // want to update all changes to memory
FThreads.assertExecutedByEdt(false);
final PhaseHandler ph = game.getPhaseHandler(); final PhaseHandler ph = game.getPhaseHandler();
@@ -62,9 +63,8 @@ public class InputProxy implements Observer {
if ( game.getInputQueue().isEmpty() && ph.hasPhaseEffects()) { if ( game.getInputQueue().isEmpty() && ph.hasPhaseEffects()) {
if(INPUT_DEBUG) if(INPUT_DEBUG)
System.out.printf("\t%s > handle begin phase during %s%n", FThreads.debugGetCurrThreadId(), ph.debugPrintState()); System.out.printf("\t%s > handle begin phase for %s%n", FThreads.debugGetCurrThreadId(), ph.debugPrintState());
ph.handleBeginPhase(); ph.handleBeginPhase();
return;
} }
final Input nextInput = game.getInputQueue().getActualInput(); final Input nextInput = game.getInputQueue().getActualInput();