diff --git a/src/main/java/forge/FThreads.java b/src/main/java/forge/FThreads.java index 1bc9bcd3cd8..5af103ca54a 100644 --- a/src/main/java/forge/FThreads.java +++ b/src/main/java/forge/FThreads.java @@ -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. diff --git a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java index 1e0dacde2ae..2f006d8bac0 100644 --- a/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java +++ b/src/main/java/forge/card/ability/effects/ChangeZoneEffect.java @@ -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 { diff --git a/src/main/java/forge/card/ability/effects/CountersProliferateEffect.java b/src/main/java/forge/card/ability/effects/CountersProliferateEffect.java index 1cc6640b6c1..a8b57114c86 100644 --- a/src/main/java/forge/card/ability/effects/CountersProliferateEffect.java +++ b/src/main/java/forge/card/ability/effects/CountersProliferateEffect.java @@ -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; diff --git a/src/main/java/forge/card/ability/effects/RestartGameEffect.java b/src/main/java/forge/card/ability/effects/RestartGameEffect.java index 62ede44b638..dc04a651eb7 100644 --- a/src/main/java/forge/card/ability/effects/RestartGameEffect.java +++ b/src/main/java/forge/card/ability/effects/RestartGameEffect.java @@ -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. } diff --git a/src/main/java/forge/card/ability/effects/UntapEffect.java b/src/main/java/forge/card/ability/effects/UntapEffect.java index 5de3d4e99b9..3841dbb7574 100644 --- a/src/main/java/forge/card/ability/effects/UntapEffect.java +++ b/src/main/java/forge/card/ability/effects/UntapEffect.java @@ -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(); diff --git a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java index 028e8756ec9..3108acab72a 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java @@ -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); diff --git a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java index e43ca7048e2..752750128ef 100644 --- a/src/main/java/forge/card/cardfactory/CardFactorySorceries.java +++ b/src/main/java/forge/card/cardfactory/CardFactorySorceries.java @@ -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 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 diff --git a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java index 2f1a63f5df9..9daa812e931 100644 --- a/src/main/java/forge/card/cardfactory/CardFactoryUtil.java +++ b/src/main/java/forge/card/cardfactory/CardFactoryUtil.java @@ -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); } diff --git a/src/main/java/forge/card/cost/CostDiscard.java b/src/main/java/forge/card/cost/CostDiscard.java index d09306380d6..d4a3aa8ca8b 100644 --- a/src/main/java/forge/card/cost/CostDiscard.java +++ b/src/main/java/forge/card/cost/CostDiscard.java @@ -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; diff --git a/src/main/java/forge/card/cost/CostExile.java b/src/main/java/forge/card/cost/CostExile.java index 5adeda94fbe..110f7df3b8f 100644 --- a/src/main/java/forge/card/cost/CostExile.java +++ b/src/main/java/forge/card/cost/CostExile.java @@ -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()); } diff --git a/src/main/java/forge/card/cost/CostPartMana.java b/src/main/java/forge/card/cost/CostPartMana.java index ff0cabfc33b..231b02e3a91 100644 --- a/src/main/java/forge/card/cost/CostPartMana.java +++ b/src/main/java/forge/card/cost/CostPartMana.java @@ -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 { diff --git a/src/main/java/forge/card/cost/CostPutCounter.java b/src/main/java/forge/card/cost/CostPutCounter.java index 17a7d653229..de2d652bc6f 100644 --- a/src/main/java/forge/card/cost/CostPutCounter.java +++ b/src/main/java/forge/card/cost/CostPutCounter.java @@ -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; diff --git a/src/main/java/forge/card/cost/CostRemoveCounter.java b/src/main/java/forge/card/cost/CostRemoveCounter.java index 03efd1c355e..e35a8dc569b 100644 --- a/src/main/java/forge/card/cost/CostRemoveCounter.java +++ b/src/main/java/forge/card/cost/CostRemoveCounter.java @@ -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; diff --git a/src/main/java/forge/card/cost/CostReturn.java b/src/main/java/forge/card/cost/CostReturn.java index 755b0b42179..80b6727ef77 100644 --- a/src/main/java/forge/card/cost/CostReturn.java +++ b/src/main/java/forge/card/cost/CostReturn.java @@ -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; diff --git a/src/main/java/forge/card/cost/CostReveal.java b/src/main/java/forge/card/cost/CostReveal.java index ad2ee5e91b9..e3c06465b75 100644 --- a/src/main/java/forge/card/cost/CostReveal.java +++ b/src/main/java/forge/card/cost/CostReveal.java @@ -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; diff --git a/src/main/java/forge/card/cost/CostSacrifice.java b/src/main/java/forge/card/cost/CostSacrifice.java index b77963e8b49..95040355c30 100644 --- a/src/main/java/forge/card/cost/CostSacrifice.java +++ b/src/main/java/forge/card/cost/CostSacrifice.java @@ -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; diff --git a/src/main/java/forge/card/cost/CostTapType.java b/src/main/java/forge/card/cost/CostTapType.java index e4b28ab00b7..9fddda10f8e 100644 --- a/src/main/java/forge/card/cost/CostTapType.java +++ b/src/main/java/forge/card/cost/CostTapType.java @@ -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; diff --git a/src/main/java/forge/card/cost/CostUntapType.java b/src/main/java/forge/card/cost/CostUntapType.java index 06f53d19e2a..ed04ce26543 100644 --- a/src/main/java/forge/card/cost/CostUntapType.java +++ b/src/main/java/forge/card/cost/CostUntapType.java @@ -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; diff --git a/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java b/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java index 291d0f26108..b4e19ba24d2 100644 --- a/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java +++ b/src/main/java/forge/card/spellability/HumanPlaySpellAbility.java @@ -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); } diff --git a/src/main/java/forge/card/spellability/TargetSelection.java b/src/main/java/forge/card/spellability/TargetSelection.java index 871398f9bea..5e99f04a7a5 100644 --- a/src/main/java/forge/card/spellability/TargetSelection.java +++ b/src/main/java/forge/card/spellability/TargetSelection.java @@ -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 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 { diff --git a/src/main/java/forge/control/input/InputAttack.java b/src/main/java/forge/control/input/InputAttack.java index 13df5c1c5da..df34b6f487a 100644 --- a/src/main/java/forge/control/input/InputAttack.java +++ b/src/main/java/forge/control/input/InputAttack.java @@ -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 diff --git a/src/main/java/forge/control/input/InputBase.java b/src/main/java/forge/control/input/InputBase.java index 28cb7a0577f..eb604ce3e0c 100644 --- a/src/main/java/forge/control/input/InputBase.java +++ b/src/main/java/forge/control/input/InputBase.java @@ -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(); } diff --git a/src/main/java/forge/control/input/InputCleanup.java b/src/main/java/forge/control/input/InputCleanup.java index 07deba3c7c7..ab22214865f 100644 --- a/src/main/java/forge/control/input/InputCleanup.java +++ b/src/main/java/forge/control/input/InputCleanup.java @@ -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); diff --git a/src/main/java/forge/control/input/InputLockUI.java b/src/main/java/forge/control/input/InputLockUI.java index e3a053181c3..a0cf414bd8f 100644 --- a/src/main/java/forge/control/input/InputLockUI.java +++ b/src/main/java/forge/control/input/InputLockUI.java @@ -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,7 +14,15 @@ 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(); FThreads.delay(500, new InputUpdater(ixCall)); @@ -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) { diff --git a/src/main/java/forge/control/input/InputPassPriority.java b/src/main/java/forge/control/input/InputPassPriority.java index c0fa7ac7b2e..6e5ef9f91b0 100644 --- a/src/main/java/forge/control/input/InputPassPriority.java +++ b/src/main/java/forge/control/input/InputPassPriority.java @@ -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); diff --git a/src/main/java/forge/control/input/InputPayManaBase.java b/src/main/java/forge/control/input/InputPayManaBase.java index 3dde1e84e03..03e6b2429e2 100644 --- a/src/main/java/forge/control/input/InputPayManaBase.java +++ b/src/main/java/forge/control/input/InputPayManaBase.java @@ -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 } diff --git a/src/main/java/forge/control/input/InputQueue.java b/src/main/java/forge/control/input/InputQueue.java index b6f64a71fe9..9829e096223 100644 --- a/src/main/java/forge/control/input/InputQueue.java +++ b/src/main/java/forge/control/input/InputQueue.java @@ -43,9 +43,16 @@ public class InputQueue extends MyObservable implements java.io.Serializable { private static final long serialVersionUID = 3955194449319994301L; private final BlockingDeque inputStack = new LinkedBlockingDeque(); + private final GameState game; + + + private final InputLockUI inputLock; - public InputQueue() {} + public InputQueue(GameState game0) { + game = game0; + inputLock = new InputLockUI(this); + } /** *

@@ -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); } @@ -202,20 +208,13 @@ public class InputQueue extends MyObservable implements java.io.Serializable { public String printInputStack() { 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(); } }; - FThreads.invokeInNewThread(toRun); + if(FThreads.isEDT()) { + FThreads.invokeInNewThread(toRun); + } else { // this branch is experimental + toRun.run(); + } } } // InputControl diff --git a/src/main/java/forge/game/GameNew.java b/src/main/java/forge/game/GameNew.java index 4bbf2d23a00..85969571013 100644 --- a/src/main/java/forge/game/GameNew.java +++ b/src/main/java/forge/game/GameNew.java @@ -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> playerLibraries) { - - Map players = match.getPlayers(); + public static void restartGame( final GameState game, final Player startingTurn, Map> playerLibraries) { + final Map players = game.getMatch().getPlayers(); Map playersConditions = new HashMap(); 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 diff --git a/src/main/java/forge/game/GameState.java b/src/main/java/forge/game/GameState.java index 8afdaf7a66c..67959aa9052 100644 --- a/src/main/java/forge/game/GameState.java +++ b/src/main/java/forge/game/GameState.java @@ -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() @@ -119,7 +122,9 @@ public class GameState { cleanup = new Cleanup(this); 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; + } } diff --git a/src/main/java/forge/game/MatchController.java b/src/main/java/forge/game/MatchController.java index f0ebb1f1df5..1327bb256f8 100644 --- a/src/main/java/forge/game/MatchController.java +++ b/src/main/java/forge/game/MatchController.java @@ -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 gamesPlayed = new ArrayList(); private final List 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 runParams = new HashMap(); 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 diff --git a/src/main/java/forge/game/ai/AiInputBlock.java b/src/main/java/forge/game/ai/AiInputBlock.java index 8d65e48a269..df1456636c5 100644 --- a/src/main/java/forge/game/ai/AiInputBlock.java +++ b/src/main/java/forge/game/ai/AiInputBlock.java @@ -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(); } } diff --git a/src/main/java/forge/game/ai/AiInputCommon.java b/src/main/java/forge/game/ai/AiInputCommon.java index 28f12dd40b2..30abccbcc94 100644 --- a/src/main/java/forge/game/ai/AiInputCommon.java +++ b/src/main/java/forge/game/ai/AiInputCommon.java @@ -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(); diff --git a/src/main/java/forge/game/phase/PhaseHandler.java b/src/main/java/forge/game/phase/PhaseHandler.java index 1b31bbbb9dc..24365c461ec 100644 --- a/src/main/java/forge/game/phase/PhaseHandler.java +++ b/src/main/java/forge/game/phase/PhaseHandler.java @@ -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(); } diff --git a/src/main/java/forge/game/phase/Untap.java b/src/main/java/forge/game/phase/Untap.java index a02c96d9141..7f4b4e6b37c 100644 --- a/src/main/java/forge/game/phase/Untap.java +++ b/src/main/java/forge/game/phase/Untap.java @@ -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(); } diff --git a/src/main/java/forge/game/phase/Upkeep.java b/src/main/java/forge/game/phase/Upkeep.java index a73cfb9d6b3..7a32f394886 100644 --- a/src/main/java/forge/game/phase/Upkeep.java +++ b/src/main/java/forge/game/phase/Upkeep.java @@ -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(); } diff --git a/src/main/java/forge/game/player/HumanPlay.java b/src/main/java/forge/game/player/HumanPlay.java index 5cbd6581c47..3facd8c2d7c 100644 --- a/src/main/java/forge/game/player/HumanPlay.java +++ b/src/main/java/forge/game/player/HumanPlay.java @@ -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; diff --git a/src/main/java/forge/game/player/PlayerControllerHuman.java b/src/main/java/forge/game/player/PlayerControllerHuman.java index bfeb8fe531d..95dc47b36e4 100644 --- a/src/main/java/forge/game/player/PlayerControllerHuman.java +++ b/src/main/java/forge/game/player/PlayerControllerHuman.java @@ -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(); 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 getCardsToMulligan(boolean isCommander) { final InputConfirmMulligan inp = new InputConfirmMulligan(player, isCommander); - FThreads.setInputAndWait(inp); + player.getGame().getInputQueue().setInputAndWait(inp); return inp.isKeepHand() ? null : inp.getSelectedCards(); } } diff --git a/src/main/java/forge/game/zone/MagicStack.java b/src/main/java/forge/game/zone/MagicStack.java index 92db2192206..8e6b7f02cb1 100644 --- a/src/main/java/forge/game/zone/MagicStack.java +++ b/src/main/java/forge/game/zone/MagicStack.java @@ -392,7 +392,7 @@ public class MagicStack extends MyObservable implements Iterable input = new AtomicReference(); - 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() { diff --git a/src/main/java/forge/gui/match/nonsingleton/CField.java b/src/main/java/forge/gui/match/nonsingleton/CField.java index c5f536b26a8..40ee98a3486 100644 --- a/src/main/java/forge/gui/match/nonsingleton/CField.java +++ b/src/main/java/forge/gui/match/nonsingleton/CField.java @@ -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);