setInputAndWait - moved to InputQueue, the latter belongs to game now, all calls re-routed

This commit is contained in:
Maxmtg
2013-05-22 21:28:53 +00:00
parent c99fdc6e24
commit 1268ed7249
40 changed files with 113 additions and 131 deletions

View File

@@ -9,8 +9,6 @@ import java.util.concurrent.TimeUnit;
import javax.swing.SwingUtilities;
import forge.control.input.InputSynchronized;
/**
* TODO: Write javadoc for this type.
*
@@ -114,10 +112,6 @@ public class FThreads {
}
}
public static void setInputAndWait(InputSynchronized input) {
Singletons.getControl().getMatch().getInput().setInput(input);
input.awaitLatchRelease();
}
/**
* TODO: Write javadoc for this method.

View File

@@ -10,7 +10,6 @@ import forge.Card;
import forge.CardCharacteristicName;
import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads;
import forge.GameEntity;
import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect;
@@ -747,7 +746,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
InputSelectCardsFromList inp = new InputSelectCardsFromList(1, 1, fetchList);
inp.setCancelAllowed(!mustChoose);
inp.setMessage(selectPrompt);
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
c = inp.hasCancelled() ? null : inp.getSelected().get(0);
}
else {

View File

@@ -8,7 +8,6 @@ import com.google.common.base.Predicate;
import forge.Card;
import forge.CardLists;
import forge.CounterType;
import forge.FThreads;
import forge.GameEntity;
import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility;
@@ -33,7 +32,7 @@ public class CountersProliferateEffect extends SpellAbilityEffect {
if (controller.isHuman()) {
InputProliferate inp = new InputProliferate();
inp.setCancelAllowed(true);
FThreads.setInputAndWait(inp);
controller.getGame().getInputQueue().setInputAndWait(inp);
if ( inp.hasCancelled() )
return;

View File

@@ -48,8 +48,8 @@ public class RestartGameEffect extends SpellAbilityEffect {
playerLibraries.put(p, newLibrary);
}
GameNew.restartGame(game.getMatch(), game, sa.getActivatingPlayer(), playerLibraries);
game.getMatch().getInput().lock(); // restore the 'locked' state of the input,
GameNew.restartGame(game, sa.getActivatingPlayer(), playerLibraries);
game.getInputQueue().lock(); // restore the 'locked' state of the input,
// because the caller method (invokeInNewThread) will try to unlock input. Restart has removed that input state.
}

View File

@@ -7,7 +7,6 @@ import org.apache.commons.lang3.StringUtils;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates.Presets;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.ability.SpellAbilityEffect;
import forge.card.spellability.SpellAbility;
@@ -83,7 +82,7 @@ public class UntapEffect extends SpellAbilityEffect {
if (p.isHuman()) {
InputSelectCards sc = new InputSelectCardsFromList(0, num, list);
FThreads.setInputAndWait(sc);
p.getGame().getInputQueue().setInputAndWait(sc);
if( !sc.hasCancelled() )
for( Card c : sc.getSelected() )
c.untap();

View File

@@ -27,7 +27,6 @@ import com.google.common.collect.Iterables;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads;
import forge.CardPredicates.Presets;
import forge.Command;
import forge.CounterType;
@@ -195,7 +194,7 @@ public class CardFactoryCreatures {
for (int x = 0; x < netAttack; x++) {
InputSelectCards inp = new InputSelectCardsFromList(1,1,wolves);
inp.setMessage("Select target wolf to damage for " + getSourceCard());
FThreads.setInputAndWait(inp);
target.getGame().getInputQueue().setInputAndWait(inp);
inp.getSelected().get(0).addDamage(1, target);
}
} else { // AI Choose spread Damage
@@ -348,7 +347,7 @@ public class CardFactoryCreatures {
"Currently, (%d) selected with a total power of: %d\n\n" + "Click OK when Done.";
target.setMessage(toDisplay);
target.setCancelAllowed(true);
FThreads.setInputAndWait(target);
player.getGame().getInputQueue().setInputAndWait(target);
if(!target.hasCancelled()) {
for (final Card sac : target.getSelected()) {
game.getAction().sacrifice(sac, null);

View File

@@ -24,7 +24,6 @@ import java.util.List;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads;
import forge.CardPredicates.Presets;
import forge.card.cost.Cost;
import forge.card.mana.ManaCost;
@@ -81,7 +80,7 @@ public class CardFactorySorceries {
InputSelectCards inp = new InputSelectCardsFromList(sac, sac, list);
inp.setMessage("Select %d more land(s) to sacrifice");
FThreads.setInputAndWait(inp);
p.getGame().getInputQueue().setInputAndWait(inp);
for( Card crd : inp.getSelected() )
p.getGame().getAction().sacrifice(crd, card);
}
@@ -103,7 +102,7 @@ public class CardFactorySorceries {
if (p.isHuman()) {
InputSelectCards sc = new InputSelectCardsFromList(sac, sac, hand);
sc.setMessage("Select %d more card(s) to discard");
FThreads.setInputAndWait(sc);
p.getGame().getInputQueue().setInputAndWait(sc);
for( Card c : sc.getSelected())
p.discard(c, spell);
} else {
@@ -146,7 +145,7 @@ public class CardFactorySorceries {
final List<Card> list = CardLists.getType(p.getCardsIn(ZoneType.Battlefield), "Creature");
InputSelectCards inp = new InputSelectCardsFromList(sac, sac, list);
inp.setMessage("Select %d more creature(s) to sacrifice");
FThreads.setInputAndWait(inp);
p.getGame().getInputQueue().setInputAndWait(inp);
for( Card crd : inp.getSelected() )
p.getGame().getAction().sacrifice(crd, card);
@@ -245,7 +244,7 @@ public class CardFactorySorceries {
} else {
final int diffCost = newCMC - baseCMC;
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(p, "Pay difference in artifacts CMC", ManaCost.get(diffCost));
FThreads.setInputAndWait(inp);
p.getGame().getInputQueue().setInputAndWait(inp);
if ( inp.isPaid() )
game.getAction().moveToPlay(newArtifact[0]);
else

View File

@@ -38,7 +38,6 @@ import forge.CardUtil;
import forge.Command;
import forge.Constant;
import forge.CounterType;
import forge.FThreads;
import forge.GameEntity;
import forge.card.ColorSet;
import forge.card.MagicColor;
@@ -2764,7 +2763,7 @@ public class CardFactoryUtil {
};
target.setMessage("Choose target creature to haunt.");
FThreads.setInputAndWait(target);
card.getGame().getInputQueue().setInputAndWait(target);
if (!target.hasCancelled()) {
haunterDiesWork.setTargetCard(target.getSelected().get(0));
game.getStack().add(haunterDiesWork);
@@ -3231,7 +3230,7 @@ public class CardFactoryUtil {
InputSelectCards inp = new InputSelectCardsFromList(1, 1, choices);
inp.setCancelAllowed(true);
inp.setMessage("Select target artifact creature to give it +1/+1 counters from the dead " + card);
FThreads.setInputAndWait(inp);
modularPlayer.getGame().getInputQueue().setInputAndWait(inp);
if( !inp.hasCancelled() ) {
card2 = inp.getSelected().get(0);
}

View File

@@ -24,7 +24,6 @@ import com.google.common.base.Predicate;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -230,7 +229,7 @@ public class CostDiscard extends CostPartWithList {
InputSelectCards inp = new InputSelectCardsFromList(c, c, handList);
inp.setMessage("Select %d more " + getDescriptiveType() + " to discard.");
//InputPayment inp = new InputPayCostDiscard(ability, handList, this, c, discardType);
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
if( inp.hasCancelled() || inp.getSelected().size() != c)
return false;

View File

@@ -23,7 +23,6 @@ import java.util.List;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance;
@@ -246,7 +245,7 @@ public class CostExile extends CostPartWithList {
InputSelectCards inp = new InputSelectCardsFromList(c, c, validCards);
inp.setMessage("Exile %d card(s) from your" + from );
inp.setCancelAllowed(true);
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
return !inp.hasCancelled() && executePayment(ability, inp.getSelected());
}

View File

@@ -18,7 +18,6 @@
package forge.card.cost;
import forge.Card;
import forge.FThreads;
import forge.card.MagicColor;
import forge.card.ability.AbilityUtils;
import forge.card.mana.ManaCost;
@@ -130,7 +129,7 @@ public class CostPartMana extends CostPart {
toPay.applySpellCostChange(ability);
if (!toPay.isPaid()) {
InputPayment inpPayment = new InputPayManaOfCostPayment(toPay, ability);
FThreads.setInputAndWait(inpPayment);
game.getInputQueue().setInputAndWait(inpPayment);
if(!inpPayment.isPaid())
return false;
@@ -141,7 +140,7 @@ public class CostPartMana extends CostPart {
if( !ability.isAnnouncing("X") && !xWasBilled) {
source.setXManaCostPaid(0);
InputPayment inpPayment = new InputPayManaX(ability, this.getAmountOfX(), this.canXbe0());
FThreads.setInputAndWait(inpPayment);
game.getInputQueue().setInputAndWait(inpPayment);
if(!inpPayment.isPaid())
return false;
} else {

View File

@@ -24,7 +24,6 @@ import java.util.Map;
import forge.Card;
import forge.CardLists;
import forge.CounterType;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -264,7 +263,7 @@ public class CostPutCounter extends CostPartWithList {
InputSelectCardToPutCounter inp = new InputSelectCardToPutCounter(c, typeList);
inp.setMessage("Put %d " + getCounter().getName() + " counter on " + getDescriptiveType());
inp.setCancelAllowed(true);
FThreads.setInputAndWait(inp);
actor.getGame().getInputQueue().setInputAndWait(inp);
if(inp.hasCancelled())
return false;

View File

@@ -25,7 +25,6 @@ import java.util.Map;
import forge.Card;
import forge.CardLists;
import forge.CounterType;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -150,7 +149,7 @@ public class CostRemoveCounter extends CostPartWithList {
final InputSelectCardToRemoveCounter inp = new InputSelectCardToRemoveCounter(cntRemoved, getCounter(), validCards);
inp.setMessage("Remove %d " + getCounter().getName() + " counters from " + getDescriptiveType());
inp.setCancelAllowed(true);
FThreads.setInputAndWait(inp);
ability.getActivatingPlayer().getGame().getInputQueue().setInputAndWait(inp);
if(inp.hasCancelled())
return false;

View File

@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.List;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -149,7 +148,7 @@ public class CostReturn extends CostPartWithList {
InputSelectCards inp = new InputSelectCardsFromList(c, c, validCards);
inp.setMessage("Return %d " + this.getType() + " " + this.getType() + " card(s) to hand");
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
if (inp.hasCancelled())
return false;

View File

@@ -24,7 +24,6 @@ import com.google.common.collect.Lists;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -169,7 +168,7 @@ public class CostReveal extends CostPartWithList {
if ( num == 0 ) return true;
InputSelectCards inp = new InputSelectCardsFromList(num, num, handList);
inp.setMessage("Select %d more " + getDescriptiveType() + " card(s) to reveal.");
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
if ( inp.hasCancelled() )
return false;

View File

@@ -21,7 +21,6 @@ import java.util.ArrayList;
import java.util.List;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -164,7 +163,7 @@ public class CostSacrifice extends CostPartWithList {
InputSelectCards inp = new InputSelectCardsFromList(c, c, list);
inp.setMessage("Select a " + this.getDescriptiveType() + " to sacrifice (%d left)");
inp.setCancelAllowed(true);
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
if ( inp.hasCancelled() )
return false;

View File

@@ -25,7 +25,6 @@ import com.google.common.base.Predicate;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates.Presets;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -199,7 +198,7 @@ public class CostTapType extends CostPartWithList {
InputSelectCards inp = new InputSelectCardsFromList(c, c, typeList);
inp.setMessage("Select a " + getDescriptiveType() + " to tap (%d left)");
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
if ( inp.hasCancelled() )
return false;

View File

@@ -21,7 +21,6 @@ import java.util.List;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates.Presets;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputSelectCards;
@@ -153,7 +152,7 @@ public class CostUntapType extends CostPartWithList {
}
InputSelectCards inp = new InputSelectCardsFromList(c, c, typeList);
inp.setMessage("Select a " + getDescriptiveType() + " to untap (%d left)");
FThreads.setInputAndWait(inp);
game.getInputQueue().setInputAndWait(inp);
if( inp.hasCancelled() || inp.getSelected().size() != c )
return false;

View File

@@ -63,7 +63,7 @@ public class HumanPlaySpellAbility {
// freeze Stack. No abilities should go onto the stack while I'm filling requirements.
game.getStack().freezeStack();
game.getMatch().getInput().lock();
game.getInputQueue().lock();
// Announce things like how many times you want to Multikick or the value of X
if (!this.announceRequirements()) {
@@ -104,7 +104,7 @@ public class HumanPlaySpellAbility {
return;
}
else {
game.getMatch().getInput().unlock();
game.getInputQueue().unlock();
if (isFree || this.payment.isFullyPaid()) {
if (skipStack) {
AbilityUtils.resolve(this.ability, false);
@@ -149,7 +149,7 @@ public class HumanPlaySpellAbility {
this.ability.resetOnceResolved();
this.payment.refundPayment();
game.getStack().clearFrozen();
game.getMatch().getInput().unlock();
game.getInputQueue().unlock();
// Singletons.getModel().getGame().getStack().removeFromFrozenStack(this.ability);
}

View File

@@ -24,7 +24,6 @@ import com.google.common.base.Predicate;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.control.input.InputSelectTargets;
import forge.game.GameState;
@@ -107,7 +106,7 @@ public class TargetSelection {
List<Card> validTargets = this.getValidCardsToTarget();
if (zone.size() == 1 && zone.get(0) == ZoneType.Battlefield) {
InputSelectTargets inp = new InputSelectTargets(validTargets, ability, mandatory);
FThreads.setInputAndWait(inp);
ability.getActivatingPlayer().getGame().getInputQueue().setInputAndWait(inp);
choiceResult = !inp.hasCancelled();
bTargetingDone = inp.hasPressedOk();
} else {

View File

@@ -26,7 +26,6 @@ import com.google.common.collect.Iterables;
import forge.Card;
import forge.CardPredicates;
import forge.GameEntity;
import forge.Singletons;
import forge.game.GameState;
import forge.game.phase.CombatUtil;
import forge.game.player.Player;
@@ -102,7 +101,7 @@ public class InputAttack extends InputBase {
game.getPhaseHandler().setCombat(!game.getCombat().getAttackers().isEmpty());
game.getPhaseHandler().setPlayersPriorityPermission(false);
Singletons.getControl().getMatch().getInput().updateObservers();
game.getInputQueue().updateObservers();
}
@Override

View File

@@ -19,7 +19,6 @@ package forge.control.input;
import forge.Card;
import forge.FThreads;
import forge.Singletons;
import forge.game.player.Player;
import forge.gui.match.CMatchUI;
@@ -60,7 +59,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
// 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
Singletons.getControl().getMatch().getInput().removeInput(this);
player.getGame().getInputQueue().removeInput(this);
afterStop(); // sync inputs will release their latch there
}
@@ -73,7 +72,7 @@ public abstract class InputBase implements java.io.Serializable, Input {
}
};
if( FThreads.isEDT() )
player.getGame().getMatch().getInput().LockAndInvokeGameAction(pass);
player.getGame().getInputQueue().LockAndInvokeGameAction(pass);
else
pass.run();
}

View File

@@ -77,7 +77,7 @@ public class InputCleanup extends InputBase {
if (!zone.is(ZoneType.Hand, Singletons.getControl().getPlayer()))
return;
game.getMatch().getInput().LockAndInvokeGameAction(new Runnable() {
game.getInputQueue().LockAndInvokeGameAction(new Runnable() {
@Override
public void run() {
card.getController().discard(card, null);

View File

@@ -4,7 +4,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import forge.Card;
import forge.FThreads;
import forge.Singletons;
import forge.game.player.Player;
import forge.gui.match.CMatchUI;
import forge.view.ButtonUtil;
@@ -15,6 +14,14 @@ import forge.view.ButtonUtil;
*/
public class InputLockUI implements Input {
private final AtomicInteger iCall = new AtomicInteger();
private final InputQueue iq;
/**
* TODO: Write javadoc for Constructor.
* @param inputQueue
*/
public InputLockUI(InputQueue inputQueue) {
iq = inputQueue;
}
public void showMessage() {
int ixCall = 1 + iCall.getAndIncrement();
@@ -51,7 +58,7 @@ public class InputLockUI implements Input {
};
protected final boolean isActive() {
return Singletons.getControl().getMatch().getInput().getInput() == this;
return iq.getInput() == this;
}
protected void showMessage(String message) {

View File

@@ -89,7 +89,7 @@ public class InputPassPriority extends InputBase {
}
};
player.getGame().getMatch().getInput().LockAndInvokeGameAction(execAbility);
player.getGame().getInputQueue().LockAndInvokeGameAction(execAbility);
}
else {
SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE);

View File

@@ -197,7 +197,7 @@ public abstract class InputPayManaBase extends InputSyncronizedBase implements I
onManaAbilityPlayed(chosen);
}
};
game.getMatch().getInput().LockAndInvokeGameAction(proc);
game.getInputQueue().LockAndInvokeGameAction(proc);
// EDT that removes lockUI from input stack will call our showMessage() method
}

View File

@@ -43,9 +43,16 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
private static final long serialVersionUID = 3955194449319994301L;
private final BlockingDeque<Input> inputStack = new LinkedBlockingDeque<Input>();
private final GameState game;
public InputQueue() {}
private final InputLockUI inputLock;
public InputQueue(GameState game0) {
game = game0;
inputLock = new InputLockUI(this);
}
/**
* <p>
@@ -119,7 +126,7 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
*
* @return a {@link forge.control.input.InputBase} object.
*/
public final Input getActualInput(GameState game) {
public final Input getActualInput() {
GameAge age = game.getAge();
if ( age != GameAge.Play && age != GameAge.Mulligan)
return inputLock;
@@ -187,7 +194,6 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
} // getInput()
private final static InputLockUI inputLock = new InputLockUI();
public void lock() {
setInput(inputLock);
}
@@ -203,19 +209,12 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
return inputStack.toString();
}
public void setInputAndWait(InputSynchronized input) {
this.setInput(input);
input.awaitLatchRelease();
}
public void LockAndInvokeGameAction(final Runnable proc) {
//final GameState game = Singletons.getControl().getMatch().getCurrentGame();
//final InputQueue iq = game.getMatch().getInput();
// StackTraceElement[] trace = Thread.currentThread().getStackTrace();
// System.out.printf("%s > Invoke in new thread during %s called from %s%n", FThreads.isEDT() ? "EDT" : "TRD", game.getPhaseHandler().getPhase(), trace[2].toString());
// if( trace[2].toString().contains("InputBase.stop"))
// for(StackTraceElement se : trace) {
// System.out.println(se.toString());
// }
this.lock();
Runnable toRun = new Runnable() {
@Override
@@ -224,7 +223,11 @@ public class InputQueue extends MyObservable implements java.io.Serializable {
InputQueue.this.unlock();
}
};
if(FThreads.isEDT()) {
FThreads.invokeInNewThread(toRun);
} else { // this branch is experimental
toRun.run();
}
}
} // InputControl

View File

@@ -329,9 +329,8 @@ public class GameNew {
}
// ultimate of Karn the Liberated
public static void restartGame(final MatchController match, final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
Map<LobbyPlayer, PlayerStartConditions> players = match.getPlayers();
public static void restartGame( final GameState game, final Player startingTurn, Map<Player, List<Card>> playerLibraries) {
final Map<LobbyPlayer, PlayerStartConditions> players = game.getMatch().getPlayers();
Map<Player, PlayerStartConditions> playersConditions = new HashMap<Player, PlayerStartConditions>();
for (Player p : game.getPlayers()) {
@@ -339,7 +338,8 @@ public class GameNew {
}
game.setAge(GameAge.Mulligan);
match.getInput().clearInput();
// TODO: Apply new mulligan code here
game.getInputQueue().clearInput();
//Card.resetUniqueNumber();
// need this code here, otherwise observables fail

View File

@@ -39,6 +39,7 @@ import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.trigger.TriggerHandler;
import forge.card.trigger.TriggerType;
import forge.control.input.InputQueue;
import forge.game.phase.Cleanup;
import forge.game.phase.Combat;
import forge.game.phase.EndOfCombat;
@@ -86,6 +87,8 @@ public class GameState {
private final MatchController match;
private GameAge age = GameAge.BeforeMulligan;
private final InputQueue inputQueue;
/**
* Constructor.
* @param players2.entrySet()
@@ -120,6 +123,8 @@ public class GameState {
endOfTurn = new EndOfTurn(this);
endOfCombat = new EndOfCombat(this);
inputQueue = new InputQueue(this);
if ( match0.getGameType() == GameType.Quest)
events.register(Singletons.getModel().getQuest()); // this one listens to player's mulligans ATM
@@ -619,4 +624,9 @@ public class GameState {
void setAge(GameAge value) {
age = value;
}
public InputQueue getInputQueue() {
return inputQueue;
}
}

View File

@@ -12,7 +12,6 @@ import forge.FThreads;
import forge.Singletons;
import forge.card.trigger.TriggerType;
import forge.control.FControl;
import forge.control.input.InputQueue;
import forge.deck.Deck;
import forge.error.BugReporter;
import forge.game.event.DuelOutcomeEvent;
@@ -57,8 +56,6 @@ public class MatchController {
private final List<GameOutcome> gamesPlayed = new ArrayList<GameOutcome>();
private final List<GameOutcome> gamesPlayedRo;
private InputQueue inputQueue;
/**
* This should become constructor once.
*/
@@ -145,7 +142,6 @@ public class MatchController {
*/
public void startRound() {
inputQueue = new InputQueue();
currentGame = new GameState(players, gameType, this);
try {
@@ -161,7 +157,7 @@ public class MatchController {
final Player firstPlayer = determineFirstTurnPlayer(getLastGameOutcome(), currentGame);
getInput().clearInput();
currentGame.getInputQueue().clearInput();
if(currentGame.getType() == GameType.Planechase)
firstPlayer.initPlane();
@@ -182,7 +178,7 @@ public class MatchController {
final HashMap<String, Object> runParams = new HashMap<String, Object>();
currentGame.getTriggerHandler().runTrigger(TriggerType.NewGame, runParams, false);
currentGame.setAge(GameAge.Play);
getInput().clearInput();
currentGame.getInputQueue().clearInput();
}
});
}
@@ -216,7 +212,7 @@ public class MatchController {
Singletons.getControl().changeState(FControl.Screens.MATCH_SCREEN);
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
CMessage.SINGLETON_INSTANCE.getInputControl().setMatch(match);
CMessage.SINGLETON_INSTANCE.getInputControl().setGame(currentGame);
// models shall notify controllers of changes
@@ -345,10 +341,6 @@ public class MatchController {
return players;
}
public final InputQueue getInput() {
return inputQueue;
}
/**
* TODO: Write javadoc for this method.
* @return

View File

@@ -36,6 +36,6 @@ public class AiInputBlock extends InputBase {
game.getPhaseHandler().setPlayersPriorityPermission(false);
// was not added to stack, so will be replaced by plain update
Singletons.getControl().getMatch().getInput().updateObservers();
Singletons.getControl().getMatch().getCurrentGame().getInputQueue().updateObservers();
}
}

View File

@@ -62,7 +62,7 @@ public class AiInputCommon extends InputBase implements AiInput {
* \"Detailed Error Trace\" to the Forge forum.");
*/
computer.getGame().getMatch().getInput().LockAndInvokeGameAction(aiActions);
computer.getGame().getInputQueue().LockAndInvokeGameAction(aiActions);
} // getMessage();

View File

@@ -751,7 +751,7 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
};
if ( FThreads.isEDT() )
game.getMatch().getInput().LockAndInvokeGameAction(proc);
game.getInputQueue().LockAndInvokeGameAction(proc);
else
proc.run();
}

View File

@@ -28,7 +28,6 @@ import forge.CardLists;
import forge.CardPredicates;
import forge.CardPredicates.Presets;
import forge.CounterType;
import forge.FThreads;
import forge.GameEntity;
import forge.control.input.InputSelectCards;
import forge.control.input.InputSelectCardsFromList;
@@ -213,7 +212,7 @@ public class Untap extends Phase {
} else {
final InputSelectCards target = new InputSelectCardsFromList(1,1, landList);
target.setMessage("Select one tapped land to untap");
FThreads.setInputAndWait(target);
player.getGame().getInputQueue().setInputAndWait(target);
if( !target.hasCancelled() && !target.getSelected().isEmpty())
target.getSelected().get(0).untap();
}
@@ -229,7 +228,7 @@ public class Untap extends Phase {
} else {
final InputSelectCards target = new InputSelectCardsFromList(1,1, artList);
target.setMessage("Select one tapped artifact to untap");
FThreads.setInputAndWait(target);
turnOwner.getGame().getInputQueue().setInputAndWait(target);
if( !target.hasCancelled() && !target.getSelected().isEmpty())
target.getSelected().get(0).untap();
}
@@ -243,7 +242,7 @@ public class Untap extends Phase {
} else {
final InputSelectCards target = new InputSelectCardsFromList(1, 1, creatures);
target.setMessage("Select one creature to untap");
FThreads.setInputAndWait(target);
player.getGame().getInputQueue().setInputAndWait(target);
if( !target.hasCancelled() && !target.getSelected().isEmpty())
target.getSelected().get(0).untap();
}

View File

@@ -26,7 +26,6 @@ import com.google.common.base.Predicate;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads;
import forge.CardPredicates.Presets;
import forge.CounterType;
import forge.card.cardfactory.CardFactoryUtil;
@@ -271,7 +270,7 @@ public class Upkeep extends Phase {
final boolean isUpkeepPaid;
if (controller.isHuman()) {
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(controller, sb, upkeepCost);
FThreads.setInputAndWait(inp);
controller.getGame().getInputQueue().setInputAndWait(inp);
isUpkeepPaid = inp.isPaid();
} else { // computer
Ability aiPaid = Upkeep.getBlankAbility(c, upkeepCost.toString());
@@ -356,7 +355,7 @@ public class Upkeep extends Phase {
boolean isUpkeepPaid = false;
if (controller.isHuman()) {
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(controller, sb, upkeepCost);
FThreads.setInputAndWait(inp);
controller.getGame().getInputQueue().setInputAndWait(inp);
isUpkeepPaid = inp.isPaid();
} else { // computers
final Ability aiPaid = Upkeep.getBlankAbility(c, upkeepCost.toString());
@@ -436,7 +435,7 @@ public class Upkeep extends Phase {
};
};
chooseArt.setMessage(abyss.getName() + " - Select one nonartifact creature to destroy");
FThreads.setInputAndWait(chooseArt); // Input
player.getGame().getInputQueue().setInputAndWait(chooseArt); // Input
if (!chooseArt.hasCancelled()) {
game.getAction().destroyNoRegeneration(chooseArt.getSelected().get(0), this);
}
@@ -565,7 +564,7 @@ public class Upkeep extends Phase {
public void resolve() {
if (game.getZoneOf(c).is(ZoneType.Battlefield)) {
InputPayment inp = new InputPayManaExecuteCommands(cp, "Pay Demonic Hordes upkeep cost", cost.getPayCosts().getTotalMana() /*, true */);
FThreads.setInputAndWait(inp);
cp.getGame().getInputQueue().setInputAndWait(inp);
if ( !inp.isPaid() )
unpaidHordesAb.resolve();
}
@@ -923,7 +922,7 @@ public class Upkeep extends Phase {
} else {
InputSelectCards inp = new InputSelectCardsFromList(num, num, list);
inp.setMessage(source.getName() + " - Select %d untapped artifact(s), creature(s), or land(s) you control");
FThreads.setInputAndWait(inp);
player.getGame().getInputQueue().setInputAndWait(inp);
for(Card crd : inp.getSelected())
crd.tap();
}

View File

@@ -165,7 +165,7 @@ public class HumanPlay {
if( !isPaid ) {
InputPayManaBase inputPay = new InputPayManaSimple(p.getGame(), sa, manaCost);
FThreads.setInputAndWait(inputPay);
p.getGame().getInputQueue().setInputAndWait(inputPay);
isPaid = inputPay.isPaid();
}
return isPaid;
@@ -462,7 +462,7 @@ public class HumanPlay {
InputPayment toSet = current == null
? new InputPayManaExecuteCommands(p, source + "\r\n", cost.getCostMana().getManaToPay())
: new InputPayManaExecuteCommands(p, source + "\r\n" + "Current Card: " + current + "\r\n" , cost.getCostMana().getManaToPay());
FThreads.setInputAndWait(toSet);
game.getInputQueue().setInputAndWait(toSet);
return toSet.isPaid();
}
@@ -473,7 +473,8 @@ public class HumanPlay {
inp.setMessage("Select %d " + cpl.getDescriptiveType() + " card(s) to " + actionName);
inp.setCancelAllowed(true);
FThreads.setInputAndWait(inp);
GameState game = sourceAbility.getActivatingPlayer().getGame();
game.getInputQueue().setInputAndWait(inp);
if( inp.hasCancelled() || inp.getSelected().size() != amount)
return false;

View File

@@ -12,7 +12,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import forge.Card;
import forge.FThreads;
import forge.GameEntity;
import forge.card.mana.Mana;
import forge.card.replacement.ReplacementEffect;
@@ -243,7 +242,7 @@ public class PlayerControllerHuman extends PlayerController {
// TODO: Either compose a message here, or pass it as parameter from caller.
inp.setMessage("Select %d " + validMessage + "(s) to sacrifice");
FThreads.setInputAndWait(inp);
player.getGame().getInputQueue().setInputAndWait(inp);
if( inp.hasCancelled() )
return new ArrayList<Card>();
else return inp.getSelected();
@@ -343,7 +342,7 @@ public class PlayerControllerHuman extends PlayerController {
InputSelectCards inp = new InputSelectCardsFromList(min, max, valid);
inp.setMessage("Discard %d cards");
FThreads.setInputAndWait(inp);
player.getGame().getInputQueue().setInputAndWait(inp);
return inp.getSelected();
}
@@ -433,7 +432,7 @@ public class PlayerControllerHuman extends PlayerController {
}
};
target.setMessage("Select %d cards to discard, unless you discard a " + uType + ".");
FThreads.setInputAndWait(target);
player.getGame().getInputQueue().setInputAndWait(target);
return target.getSelected();
}
@@ -472,7 +471,7 @@ public class PlayerControllerHuman extends PlayerController {
@Override
public List<Card> getCardsToMulligan(boolean isCommander) {
final InputConfirmMulligan inp = new InputConfirmMulligan(player, isCommander);
FThreads.setInputAndWait(inp);
player.getGame().getInputQueue().setInputAndWait(inp);
return inp.isKeepHand() ? null : inp.getSelectedCards();
}
}

View File

@@ -392,7 +392,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
int mkMagnitude = sa.getSourceCard().getKickerMagnitude();
String prompt = String.format("Multikicker for %s\r\nTimes Kicked: %d\r\n", sa.getSourceCard(), mkMagnitude );
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(activating, prompt, sp.getMultiKickerManaCost());
FThreads.setInputAndWait(toSet);
activating.getGame().getInputQueue().setInputAndWait(toSet);
if ( !toSet.isPaid() )
break;
@@ -437,7 +437,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
ability.resolve();
String prompt = String.format("Replicate for %s\r\nTimes Replicated: %d\r\n", sa.getSourceCard(), sa.getSourceCard().getReplicateMagnitude());
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(controller, prompt, sp.getReplicateManaCost());
FThreads.setInputAndWait(toSet);
controller.getGame().getInputQueue().setInputAndWait(toSet);
if ( toSet.isPaid() ) {
this.run();
} else {
@@ -643,7 +643,7 @@ public class MagicStack extends MyObservable implements Iterable<SpellAbilitySta
if (source.getController().isHuman()) {
final InputSelectCards targetHaunted = new InputSelectCardsFromList(1,1, creats);
targetHaunted.setMessage("Choose target creature to haunt.");
FThreads.setInputAndWait(targetHaunted);
source.getGame().getInputQueue().setInputAndWait(targetHaunted);
haunterDiesWork.setTargetCard(targetHaunted.getSelected().get(0));
MagicStack.this.add(haunterDiesWork);
} else {

View File

@@ -25,7 +25,6 @@ import forge.Card;
import forge.FThreads;
import forge.control.input.Input;
import forge.game.GameState;
import forge.game.MatchController;
import forge.game.phase.PhaseHandler;
import forge.game.player.Player;
@@ -41,26 +40,25 @@ public class InputProxy implements Observer {
/** The input. */
private AtomicReference<Input> input = new AtomicReference<Input>();
private MatchController match = null;
private GameState game = null;
private static final boolean INPUT_DEBUG = false;
public void setMatch(MatchController match0) {
match = match0;
match.getCurrentGame().getStack().addObserver(this);
match.getCurrentGame().getPhaseHandler().addObserver(this);
match.getInput().addObserver(this);
public void setGame(GameState game0) {
game = game0;
game.getStack().addObserver(this);
game.getPhaseHandler().addObserver(this);
game.getInputQueue().addObserver(this);
}
@Override
public final synchronized void update(final Observable observable, final Object obj) {
final GameState game = match.getCurrentGame();
final PhaseHandler ph = game.getPhaseHandler();
if(INPUT_DEBUG)
System.out.printf("%s > InputProxy.update() =>%n", FThreads.debugGetCurrThreadId());
if ( match.getInput().isEmpty() && ph.hasPhaseEffects()) {
if ( game.getInputQueue().isEmpty() && ph.hasPhaseEffects()) {
Runnable rPhase = new Runnable() {
@Override
public void run() {
@@ -74,10 +72,10 @@ public class InputProxy implements Observer {
return;
}
final Input nextInput = match.getInput().getActualInput(game);
final Input nextInput = game.getInputQueue().getActualInput();
if(INPUT_DEBUG)
System.out.printf("\tinput is %s during %s, \tstack = %s%n", nextInput == null ? "null" : nextInput.getClass().getSimpleName(), ph.debugPrintState(), match.getInput().printInputStack());
System.out.printf("\tinput is %s during %s, \tstack = %s%n", nextInput == null ? "null" : nextInput.getClass().getSimpleName(), ph.debugPrintState(), game.getInputQueue().printInputStack());
this.input.set(nextInput);
Runnable showMessage = new Runnable() {

View File

@@ -32,7 +32,6 @@ import forge.Card;
import forge.Command;
import forge.FThreads;
import forge.Constant.Preferences;
import forge.Singletons;
import forge.card.cardfactory.CardFactoryUtil;
import forge.card.spellability.SpellAbility;
import forge.control.input.Input;
@@ -201,7 +200,7 @@ public class CField implements ICDoc {
/** */
private void manaAction(byte colorCode) {
if (CField.this.player == CField.this.playerViewer) {
final Input in = Singletons.getControl().getMatch().getInput().getInput();
final Input in = CField.this.player.getGame().getInputQueue().getInput();
if (in instanceof InputPayManaBase) {
// Do something
((InputPayManaBase) in).selectManaPool(colorCode);