Made a base class for synchronized inputs, so their clients don't have to import any java.util.concurrent classes

Threw away GameInputUpdatesThread.java - it's no longer needed.
This commit is contained in:
Maxmtg
2013-03-23 18:03:41 +00:00
parent c859abcb93
commit 57c7a1af87
38 changed files with 237 additions and 483 deletions

View File

@@ -1,14 +1,12 @@
package forge;
import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.SwingUtilities;
import forge.control.input.InputBase;
import forge.error.BugReporter;
import forge.control.input.InputSynchronized;
/**
* TODO: Write javadoc for this type.
@@ -104,15 +102,10 @@ public class FThreads {
}
invokeInNewThread(toRun);
}
public static final void setInputAndWait(InputBase inp, CountDownLatch cdl) {
checkEDT("FThreads.setInputAndWait", false);
Singletons.getModel().getMatch().getInput().setInputInterrupt(inp);
try {
cdl.await();
} catch (InterruptedException e) {
BugReporter.reportException(e);
}
public static void setInputAndWait(InputSynchronized input) {
Singletons.getModel().getMatch().getInput().setInput(input);
input.awaitLatchRelease();
}
}

View File

@@ -23,8 +23,6 @@ import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.CountDownLatch;
import javax.swing.JOptionPane;
import com.google.common.collect.Iterables;
@@ -463,9 +461,8 @@ public class CardFactorySorceries {
game.getAction().moveToPlay(newArtifact[0]);
} else {
final String diffCost = String.valueOf(newCMC - baseCMC);
final CountDownLatch cdl = new CountDownLatch(1);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, "Pay difference in artifacts CMC", diffCost, cdl);
FThreads.setInputAndWait(inp, cdl);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, "Pay difference in artifacts CMC", diffCost);
FThreads.setInputAndWait(inp);
if ( inp.isPaid() )
Singletons.getModel().getGame().getAction().moveToPlay(newArtifact[0]);
else

View File

@@ -19,8 +19,6 @@ package forge.card.cost;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import com.google.common.base.Predicate;
import forge.Card;
@@ -30,7 +28,6 @@ import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputBase;
import forge.game.GameState;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
@@ -72,8 +69,8 @@ public class CostDiscard extends CostPartWithList {
* @param sp
* @param discType
*/
public InputPayCostDiscard(CountDownLatch cdl, SpellAbility sa, List<Card> handList, CostDiscard part, CostPayment payment, int nNeeded, String discType) {
super(cdl, payment);
public InputPayCostDiscard(SpellAbility sa, List<Card> handList, CostDiscard part, CostPayment payment, int nNeeded, String discType) {
super(payment);
this.sa = sa;
this.handList = handList;
this.part = part;
@@ -338,9 +335,7 @@ public class CostDiscard extends CostPartWithList {
}
}
CountDownLatch cdl = new CountDownLatch(1);
final InputBase inp = new InputPayCostDiscard(cdl, ability, handList, this, payment, c, discardType);
FThreads.setInputAndWait(inp, cdl);
FThreads.setInputAndWait(new InputPayCostDiscard(ability, handList, this, payment, c, discardType));
}
}
if ( !payment.isCanceled())

View File

@@ -20,17 +20,14 @@ package forge.card.cost;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates;
import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance;
import forge.control.input.InputBase;
import forge.control.input.InputSynchronized;
import forge.game.GameState;
import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer;
@@ -68,8 +65,8 @@ public class CostExile extends CostPartWithList {
* @param payment
* @param part
*/
private InputExileFrom(CountDownLatch cdl, SpellAbility sa, String type, int nNeeded, CostPayment payment, CostExile part) {
super(cdl, payment);
private InputExileFrom(SpellAbility sa, String type, int nNeeded, CostPayment payment, CostExile part) {
super(payment);
this.sa = sa;
this.type = type;
this.nNeeded = nNeeded;
@@ -128,8 +125,8 @@ public class CostExile extends CostPartWithList {
* @param nNeeded
* @param payableZone
*/
private InputExileFromSame(CountDownLatch cdl, List<Card> list, CostExile part, CostPayment payment, int nNeeded, List<Player> payableZone) {
super(cdl, payment);
private InputExileFromSame(List<Card> list, CostExile part, CostPayment payment, int nNeeded, List<Player> payableZone) {
super(payment);
this.list = list;
this.part = part;
this.nNeeded = nNeeded;
@@ -198,8 +195,8 @@ public class CostExile extends CostPartWithList {
* @param nNeeded
* @param part
*/
private InputExileFromStack(CountDownLatch cdl, CostPayment payment, SpellAbility sa, String type, int nNeeded, CostExile part) {
super(cdl, payment);
private InputExileFromStack(CostPayment payment, SpellAbility sa, String type, int nNeeded, CostExile part) {
super(payment);
this.sa = sa;
this.type = type;
this.nNeeded = nNeeded;
@@ -278,8 +275,8 @@ public class CostExile extends CostPartWithList {
* @param nNeeded
* @param sa
*/
private InputExileType(CountDownLatch cdl, CostExile part, CostPayment payment, String type, int nNeeded, SpellAbility sa) {
super(cdl, payment);
private InputExileType(CostExile part, CostPayment payment, String type, int nNeeded, SpellAbility sa) {
super(payment);
this.part = part;
this.type = type;
this.nNeeded = nNeeded;
@@ -346,8 +343,8 @@ public class CostExile extends CostPartWithList {
* @param part
* @param sa
*/
private InputExileThis(CountDownLatch cdl, CostPayment payment, CostExile part, SpellAbility sa) {
super(cdl, payment);
private InputExileThis(CostPayment payment, CostExile part, SpellAbility sa) {
super(payment);
this.part = part;
this.sa = sa;
}
@@ -359,14 +356,12 @@ public class CostExile extends CostPartWithList {
if (choice) {
Singletons.getModel().getGame().getAction().exile(card);
part.addToList(card);
this.stop();
part.addListToHash(sa, "Exiled");
done();
} else {
cancel();
return;
}
}
else cancel();
cancel();
}
}
@@ -576,15 +571,13 @@ public class CostExile extends CostPartWithList {
}
}
final CountDownLatch cdl = new CountDownLatch(1);
InputBase target = null;
InputSynchronized target = null;
if (this.payCostFromSource()) {
target = new InputExileThis(cdl, payment, this, ability);
target = new InputExileThis(payment, this, ability);
} else if (this.from.equals(ZoneType.Battlefield) || this.from.equals(ZoneType.Hand)) {
target = new InputExileType(cdl, this, payment, this.getType(), c, ability);
target = new InputExileType(this, payment, this.getType(), c, ability);
} else if (this.from.equals(ZoneType.Stack)) {
target = new InputExileFromStack(cdl,payment, ability, this.getType(), c, this);
target = new InputExileFromStack(payment, ability, this.getType(), c, this);
} else if (this.from.equals(ZoneType.Library)) {
// this does not create input
CostExile.exileFromTop(ability, this, payment, c);
@@ -599,11 +592,11 @@ public class CostExile extends CostPartWithList {
payableZone.add(p);
}
}
target = new InputExileFromSame(cdl, list, this, payment, c, payableZone);
target = new InputExileFromSame(list, this, payment, c, payableZone);
} else {
target = new InputExileFrom(cdl,ability, this.getType(), c, payment, this);
target = new InputExileFrom(ability, this.getType(), c, payment, this);
}
FThreads.setInputAndWait(target, cdl);
target.awaitLatchRelease();
if(!payment.isCanceled())
addListToHash(ability, "Exiled");
}

View File

@@ -17,15 +17,12 @@
*/
package forge.card.cost;
import java.util.concurrent.CountDownLatch;
import com.google.common.base.Strings;
import forge.Card;
import forge.FThreads;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputBase;
import forge.control.input.InputPayManaOfCostPayment;
import forge.control.input.InputPayManaX;
import forge.game.GameState;
@@ -218,18 +215,15 @@ public class CostPartMana extends CostPart {
}
}
CountDownLatch cdl = new CountDownLatch(1);
final InputBase inp;
if (!"0".equals(this.getManaToPay()) || manaToAdd > 0) {
inp = new InputPayManaOfCostPayment(game, this, ability, payment, manaToAdd, cdl);
} else if (this.getXMana() > 0) {
inp = new InputPayManaX(game, ability, payment, this, cdl);
}
else inp = null;
if ( null != inp) {
FThreads.setInputAndWait(inp, cdl);
FThreads.setInputAndWait(new InputPayManaOfCostPayment(game, this, ability, payment, manaToAdd));
}
if (this.getXMana() > 0) {
source.setXManaCostPaid(0);
FThreads.setInputAndWait(new InputPayManaX(game, ability, payment, this));
}
}
/*

View File

@@ -18,14 +18,12 @@
package forge.card.cost;
import java.util.List;
import java.util.concurrent.CountDownLatch;
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.InputSynchronized;
import forge.game.GameState;
import forge.game.ai.ComputerUtilCard;
import forge.game.player.AIPlayer;
@@ -59,8 +57,8 @@ public class CostPutCounter extends CostPartWithList {
* @param payment
* @param sa
*/
public InputPayCostPutCounter(CountDownLatch cdl, String type, CostPutCounter costPutCounter, int nNeeded, CostPayment payment, SpellAbility sa) {
super(cdl, payment);
public InputPayCostPutCounter(String type, CostPutCounter costPutCounter, int nNeeded, CostPayment payment, SpellAbility sa) {
super(payment);
this.type = type;
this.costPutCounter = costPutCounter;
this.nNeeded = nNeeded;
@@ -255,8 +253,8 @@ public class CostPutCounter extends CostPartWithList {
source.addCounter(this.getCounter(), c, false);
this.addToList(source);
} else {
CountDownLatch cdl = new CountDownLatch(1);
FThreads.setInputAndWait(new InputPayCostPutCounter(cdl, this.getType(), this, c, payment, ability), cdl);
InputSynchronized inp = new InputPayCostPutCounter(this.getType(), this, c, payment, ability);
inp.awaitLatchRelease();
}
if ( !payment.isCanceled())
addListToHash(ability, "CounterPut");

View File

@@ -19,15 +19,13 @@ package forge.card.cost;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
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.InputBase;
import forge.control.input.InputSynchronized;
import forge.game.GameState;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
@@ -68,9 +66,8 @@ public class CostRemoveCounter extends CostPartWithList {
* @param type
* @param costRemoveCounter
*/
public InputPayCostRemoveCounterType(CountDownLatch cdl, CostPayment payment, int nNeeded, SpellAbility sa, String type,
CostRemoveCounter costRemoveCounter) {
super(cdl, payment);
public InputPayCostRemoveCounterType(CostPayment payment, int nNeeded, SpellAbility sa, String type, CostRemoveCounter costRemoveCounter) {
super(payment);
this.nNeeded = nNeeded;
this.sa = sa;
this.type = type;
@@ -136,9 +133,9 @@ public class CostRemoveCounter extends CostPartWithList {
* @param nNeeded
* @param payment
*/
public InputPayCostRemoveCounterFrom(CountDownLatch cdl, CostRemoveCounter costRemoveCounter, String type, SpellAbility sa,
public InputPayCostRemoveCounterFrom(CostRemoveCounter costRemoveCounter, String type, SpellAbility sa,
int nNeeded, CostPayment payment) {
super(cdl, payment);
super(payment);
this.costRemoveCounter = costRemoveCounter;
this.type = type;
this.sa = sa;
@@ -380,15 +377,13 @@ public class CostRemoveCounter extends CostPartWithList {
}
}
final InputBase inp;
CountDownLatch cdl = new CountDownLatch(1);
final InputSynchronized inp;
if (this.getZone().equals(ZoneType.Battlefield)) {
inp = new InputPayCostRemoveCounterType(cdl, payment, c, ability, this.getType(), this);
inp = new InputPayCostRemoveCounterType(payment, c, ability, this.getType(), this);
} else {
inp = new InputPayCostRemoveCounterFrom(cdl, this, this.getType(), ability, c, payment);
inp = new InputPayCostRemoveCounterFrom(this, this.getType(), ability, c, payment);
}
FThreads.setInputAndWait(inp, cdl);
FThreads.setInputAndWait(inp);
if ( !payment.isCanceled() )
addListToHash(ability, "CounterRemove");
return;

View File

@@ -19,15 +19,12 @@ package forge.card.cost;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputBase;
import forge.game.GameState;
import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer;
@@ -47,16 +44,14 @@ public class CostReturn extends CostPartWithList {
* TODO: Write javadoc for this type.
*
*/
public static final class InputPayReturnType extends InputBase {
public static final class InputPayReturnType extends InputPayCostBase {
private final SpellAbility sa;
private final CostReturn part;
private final int nNeeded;
private final String type;
private final CostPayment payment;
private static final long serialVersionUID = 2685832214519141903L;
private List<Card> typeList;
private int nReturns = 0;
private final CountDownLatch cdlDone;
/**
* TODO: Write javadoc for Constructor.
@@ -67,14 +62,12 @@ public class CostReturn extends CostPartWithList {
* @param type
* @param payment
*/
public InputPayReturnType(CountDownLatch cdl, SpellAbility sa, CostReturn part, int nNeeded, String type,
CostPayment payment) {
public InputPayReturnType( SpellAbility sa, CostReturn part, int nNeeded, String type, CostPayment payment) {
super(payment);
this.sa = sa;
this.part = part;
this.nNeeded = nNeeded;
this.type = type;
this.payment = payment;
cdlDone = cdl;
}
@Override
@@ -97,11 +90,6 @@ public class CostReturn extends CostPartWithList {
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
this.cancel();
}
@Override
public void selectCard(final Card card) {
if (this.typeList.contains(card)) {
@@ -120,17 +108,6 @@ public class CostReturn extends CostPartWithList {
}
}
}
public void done() {
this.stop();
cdlDone.countDown();
}
public void cancel() {
this.stop();
payment.cancelCost();
cdlDone.countDown();
}
}
/**
@@ -252,10 +229,7 @@ public class CostReturn extends CostPartWithList {
}
}
} else {
CountDownLatch cdl = new CountDownLatch(1);
final InputBase target = new InputPayReturnType(cdl, ability, this, c, this.getType(), payment);
final InputBase inp = target;
FThreads.setInputAndWait(inp, cdl);
FThreads.setInputAndWait(new InputPayReturnType(ability, this, c, this.getType(), payment));
}
if (!payment.isCanceled())

View File

@@ -19,15 +19,12 @@ package forge.card.cost;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputBase;
import forge.game.GameState;
import forge.game.player.AIPlayer;
import forge.game.player.Player;
@@ -47,16 +44,15 @@ public class CostReveal extends CostPartWithList {
* TODO: Write javadoc for this type.
*
*/
public static final class InputPayReveal extends InputBase {
public static final class InputPayReveal extends InputPayCostBase {
private final CostReveal part;
private final String discType;
private final List<Card> handList;
private final SpellAbility sa;
private final CostPayment payment;
private final int nNeeded;
private static final long serialVersionUID = -329993322080934435L;
private int nReveal = 0;
private final CountDownLatch cdlDone;
/**
* TODO: Write javadoc for Constructor.
@@ -67,14 +63,13 @@ public class CostReveal extends CostPartWithList {
* @param payment
* @param nNeeded
*/
public InputPayReveal(CountDownLatch cdl, CostReveal part, String discType, List<Card> handList, SpellAbility sa,
public InputPayReveal(CostReveal part, String discType, List<Card> handList, SpellAbility sa,
CostPayment payment, int nNeeded) {
this.cdlDone = cdl;
super(payment);
this.part = part;
this.discType = discType;
this.handList = handList;
this.sa = sa;
this.payment = payment;
this.nNeeded = nNeeded;
}
@@ -104,11 +99,6 @@ public class CostReveal extends CostPartWithList {
ButtonUtil.enableOnlyCancel();
}
@Override
public void selectButtonCancel() {
this.cancel();
}
@Override
public void selectCard(final Card card) {
Zone zone = Singletons.getModel().getGame().getZoneOf(card);
@@ -131,18 +121,6 @@ public class CostReveal extends CostPartWithList {
}
}
}
public void cancel() {
this.stop();
payment.cancelCost();
cdlDone.countDown();
}
public void done() {
this.stop();
// "Inform" AI of the revealed cards
cdlDone.countDown();
}
}
/**
@@ -278,9 +256,7 @@ public class CostReveal extends CostPartWithList {
}
}
if (num > 0) {
final CountDownLatch cdl = new CountDownLatch(1);
final InputBase inp = new InputPayReveal(cdl, this, this.getType(), handList, ability, payment, num);;
FThreads.setInputAndWait(inp, cdl);
FThreads.setInputAndWait(new InputPayReveal(this, this.getType(), handList, ability, payment, num));
}
}
if ( !payment.isCanceled())

View File

@@ -19,8 +19,6 @@ package forge.card.cost;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.FThreads;
@@ -61,9 +59,9 @@ public class CostSacrifice extends CostPartWithList {
* @param payment
* @param typeList
*/
public InputPayCostSacrificeFromList(CountDownLatch cdl, CostSacrifice part, SpellAbility sa, int nNeeded, CostPayment payment,
public InputPayCostSacrificeFromList(CostSacrifice part, SpellAbility sa, int nNeeded, CostPayment payment,
List<Card> typeList) {
super(cdl, payment);
super(payment);
this.part = part;
this.sa = sa;
this.nNeeded = nNeeded;
@@ -252,8 +250,7 @@ public class CostSacrifice extends CostPartWithList {
if (0 == c.intValue()) {
return;
}
final CountDownLatch cdl = new CountDownLatch(1);
FThreads.setInputAndWait(new InputPayCostSacrificeFromList(cdl, this, ability, c, payment, list), cdl);
FThreads.setInputAndWait(new InputPayCostSacrificeFromList(this, ability, c, payment, list));
}
if( !payment.isCanceled())
addListToHash(ability, "Sacrificed");

View File

@@ -19,8 +19,6 @@ package forge.card.cost;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates.Presets;
@@ -28,7 +26,6 @@ import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.spellability.SpellAbility;
import forge.control.input.InputBase;
import forge.game.GameState;
import forge.game.ai.ComputerUtil;
import forge.game.player.AIPlayer;
@@ -47,14 +44,12 @@ public class CostTapType extends CostPartWithList {
* TODO: Write javadoc for this type.
*
*/
public static final class InputPayCostTapType extends InputBase {
public static final class InputPayCostTapType extends InputPayCostBase {
private final CostTapType tapType;
private final int nCards;
private final List<Card> cardList;
private final CostPayment payment;
private static final long serialVersionUID = 6438988130447851042L;
private int nTapped = 0;
private final CountDownLatch cdlDone;
/**
* TODO: Write javadoc for Constructor.
@@ -64,13 +59,11 @@ public class CostTapType extends CostPartWithList {
* @param cardList
* @param payment
*/
public InputPayCostTapType(CountDownLatch cdl, CostTapType tapType, int nCards, List<Card> cardList,
CostPayment payment) {
cdlDone = cdl;
public InputPayCostTapType(CostTapType tapType, int nCards, List<Card> cardList, CostPayment payment) {
super(payment);
this.tapType = tapType;
this.nCards = nCards;
this.cardList = cardList;
this.payment = payment;
}
@Override
@@ -85,10 +78,7 @@ public class CostTapType extends CostPartWithList {
}
}
@Override
public void selectButtonCancel() {
this.cancel();
}
@Override
public void selectCard(final Card card) {
@@ -111,18 +101,6 @@ public class CostTapType extends CostPartWithList {
}
}
}
public void cancel() {
this.stop();
payment.cancelCost();
cdlDone.countDown();
}
public void done() {
this.stop();
cdlDone.countDown();
}
}
/**
@@ -248,8 +226,7 @@ public class CostTapType extends CostPartWithList {
c = AbilityUtils.calculateAmount(source, amount, ability);
}
}
CountDownLatch cdl = new CountDownLatch(1);
FThreads.setInputAndWait(new InputPayCostTapType(cdl, this, c, typeList, payment), cdl);
FThreads.setInputAndWait(new InputPayCostTapType(this, c, typeList, payment));
if( !payment.isCanceled())
addListToHash(ability, "Tapped");
}

View File

@@ -18,8 +18,6 @@
package forge.card.cost;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.CardPredicates.Presets;
@@ -61,8 +59,8 @@ public class CostUntapType extends CostPartWithList {
* @param sa
* @param payment
*/
public InputPayCostUntapY(CountDownLatch cdl, int nCards, List<Card> cardList, CostUntapType untapType, CostPayment payment) {
super(cdl, payment);
public InputPayCostUntapY(int nCards, List<Card> cardList, CostUntapType untapType, CostPayment payment) {
super(payment);
this.nCards = nCards;
this.cardList = cardList;
this.untapType = untapType;
@@ -249,8 +247,7 @@ public class CostUntapType extends CostPartWithList {
c = AbilityUtils.calculateAmount(source, amount, ability);
}
}
CountDownLatch cdl = new CountDownLatch(1);
FThreads.setInputAndWait(new InputPayCostUntapY(cdl, c, typeList, this, payment), cdl);
FThreads.setInputAndWait(new InputPayCostUntapY(c, typeList, this, payment));
if ( !payment.isCanceled() )
addListToHash(ability, "Untapped");

View File

@@ -1,25 +1,21 @@
package forge.card.cost;
import java.util.concurrent.CountDownLatch;
import forge.control.input.InputBase;
import forge.control.input.InputSyncronizedBase;
/**
* TODO: Write javadoc for this type.
*
*/
abstract class InputPayCostBase extends InputBase {
abstract class InputPayCostBase extends InputSyncronizedBase {
private static final long serialVersionUID = -2967434867139585579L;
private final CountDownLatch cdlDone;
private final CostPayment payment;
/**
* TODO: Write javadoc for Constructor.
* @param cdl
* @param payment
*/
public InputPayCostBase(CountDownLatch cdl, CostPayment payment0) {
cdlDone = cdl;
public InputPayCostBase(CostPayment payment0) {
payment = payment0;
}
@@ -30,12 +26,10 @@ abstract class InputPayCostBase extends InputBase {
final protected void done() {
this.stop();
cdlDone.countDown();
}
final public void cancel() {
this.stop();
payment.cancelCost();
cdlDone.countDown();
this.stop();
}
}

View File

@@ -20,8 +20,6 @@ package forge.card.spellability;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import com.google.common.base.Predicate;
import forge.Card;
@@ -30,7 +28,8 @@ import forge.FThreads;
import forge.Singletons;
import forge.card.ability.AbilityUtils;
import forge.card.ability.ApiType;
import forge.control.input.InputBase;
import forge.control.input.InputSynchronized;
import forge.control.input.InputSyncronizedBase;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.GuiChoose;
@@ -50,7 +49,7 @@ public class TargetSelection {
* TODO: Write javadoc for this type.
*
*/
public final class InputSelectTargets extends InputBase {
public final class InputSelectTargets extends InputSyncronizedBase {
private final TargetSelection select;
private final List<Card> choices;
private final ArrayList<Object> alreadyTargeted;
@@ -58,7 +57,6 @@ public class TargetSelection {
private final Target tgt;
private final SpellAbility sa;
private final boolean mandatory;
private final CountDownLatch cdlDone;
private static final long serialVersionUID = -1091595663541356356L;
/**
@@ -72,8 +70,7 @@ public class TargetSelection {
* @param sa
* @param mandatory
*/
public InputSelectTargets(CountDownLatch cdl, TargetSelection select, List<Card> choices, ArrayList<Object> alreadyTargeted, boolean targeted, Target tgt, SpellAbility sa, boolean mandatory) {
cdlDone = cdl;
public InputSelectTargets(TargetSelection select, List<Card> choices, ArrayList<Object> alreadyTargeted, boolean targeted, Target tgt, SpellAbility sa, boolean mandatory) {
this.select = select;
this.choices = choices;
this.alreadyTargeted = alreadyTargeted;
@@ -213,7 +210,6 @@ public class TargetSelection {
void done() {
this.stop();
cdlDone.countDown();
}
}
@@ -524,9 +520,8 @@ public class TargetSelection {
}
if (zone.contains(ZoneType.Battlefield) && zone.size() == 1) {
CountDownLatch cdl = new CountDownLatch(1);
InputBase inp = new InputSelectTargets(cdl, this, choices, objects, true, this.target, this.ability, mandatory);
FThreads.setInputAndWait(inp, cdl);
InputSynchronized inp = new InputSelectTargets(this, choices, objects, true, this.target, this.ability, mandatory);
FThreads.setInputAndWait(inp);
bTargetingDone = !bCancel;
} else {
this.chooseCardFromList(choices, true, mandatory);

View File

@@ -24,9 +24,9 @@ import com.google.common.collect.Iterables;
import forge.Card;
import forge.CardPredicates;
import forge.Singletons;
import forge.game.GameState;
import forge.game.phase.CombatUtil;
import forge.game.player.Player;
import forge.game.zone.PlayerZone;
import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.gui.framework.SDisplayUtil;
@@ -46,6 +46,12 @@ public class InputAttack extends InputBase {
/** Constant <code>serialVersionUID=7849903731842214245L</code>. */
private static final long serialVersionUID = 7849903731842214245L;
private final GameState game;
public InputAttack(GameState game0) {
game = game0;
}
/** {@inheritDoc} */
@Override
public final void showMessage() {
@@ -53,7 +59,7 @@ public class InputAttack extends InputBase {
ButtonUtil.enableOnlyOk();
final Object o = Singletons.getModel().getGame().getCombat().nextDefender();
final Object o = game.getCombat().nextDefender();
if (o == null) {
return;
}
@@ -64,13 +70,13 @@ public class InputAttack extends InputBase {
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
if (Singletons.getModel().getGame().getCombat().getRemainingDefenders() == 0) {
if (game.getCombat().getRemainingDefenders() == 0) {
// Nothing left to attack, has to attack this defender
List<Card> possibleAttackers = Singletons.getControl().getPlayer().getCardsIn(ZoneType.Battlefield);
for (Card c : Iterables.filter(possibleAttackers, CardPredicates.Presets.CREATURES)) {
if (c.hasKeyword("CARDNAME attacks each turn if able.") && CombatUtil.canAttack(c, Singletons.getModel().getGame().getCombat())
if (c.hasKeyword("CARDNAME attacks each turn if able.") && CombatUtil.canAttack(c, game.getCombat())
&& !c.isAttacking()) {
Singletons.getModel().getGame().getCombat().addAttacker(c);
game.getCombat().addAttacker(c);
}
}
}
@@ -79,36 +85,36 @@ public class InputAttack extends InputBase {
/** {@inheritDoc} */
@Override
public final void selectButtonOK() {
if (!Singletons.getModel().getGame().getCombat().getAttackers().isEmpty()) {
Singletons.getModel().getGame().getPhaseHandler().setCombat(true);
if (!game.getCombat().getAttackers().isEmpty()) {
game.getPhaseHandler().setCombat(true);
}
if (Singletons.getModel().getGame().getCombat().getRemainingDefenders() != 0) {
Singletons.getModel().getGame().getPhaseHandler().repeatPhase();
if (game.getCombat().getRemainingDefenders() != 0) {
game.getPhaseHandler().repeatPhase();
}
Singletons.getModel().getGame().getPhaseHandler().setPlayersPriorityPermission(false);
Singletons.getModel().getMatch().getInput().resetInput();
game.getPhaseHandler().setPlayersPriorityPermission(false);
Singletons.getModel().getMatch().getInput().updateObservers();
}
/** {@inheritDoc} */
@Override
public final void selectCard(final Card card) {
if (card.isAttacking() || card.getController().isComputer()) {
if (card.isAttacking() || card.getController() != Singletons.getControl().getPlayer()) {
return;
}
final Player human = Singletons.getControl().getPlayer();
Zone zone = Singletons.getModel().getGame().getZoneOf(card);
Zone zone = game.getZoneOf(card);
if (zone.is(ZoneType.Battlefield, human)
&& CombatUtil.canAttack(card, Singletons.getModel().getGame().getCombat())) {
&& CombatUtil.canAttack(card, game.getCombat())) {
// TODO add the propaganda code here and remove it in
// Phase.nextPhase()
// if (!CombatUtil.checkPropagandaEffects(card))
// return;
Singletons.getModel().getGame().getCombat().addAttacker(card);
game.getCombat().addAttacker(card);
// just to make sure the attack symbol is marked
human.getZone(ZoneType.Battlefield).updateObservers();
@@ -118,18 +124,4 @@ public class InputAttack extends InputBase {
SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE);
}
} // selectCard()
/**
* <p>
* unselectCard.
* </p>
*
* @param card
* a {@link forge.Card} object.
* @param zone
* a {@link forge.game.zone.PlayerZone} object.
*/
public void unselectCard(final Card card, final PlayerZone zone) {
}
}

View File

@@ -52,12 +52,12 @@ public abstract class InputBase implements java.io.Serializable, Input {
CMatchUI.SINGLETON_INSTANCE.showMessage(message);
}
// called by input to cleanup.
// 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.getModel().getMatch().getInput().resetInput();
Singletons.getModel().getMatch().getInput().removeInput(this);
afterStop(); // sync inputs will release their latch there
}
protected void afterStop() { }
}
}

View File

@@ -25,7 +25,6 @@ import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerController;
import forge.game.zone.MagicStack;
import forge.gui.match.controllers.CMessage;
import forge.util.MyObservable;
/**
@@ -57,22 +56,6 @@ public class InputControl extends MyObservable implements java.io.Serializable {
this.updateObservers();
}
/**
* <p>
* Setter for the field <code>input</code>.
* </p>
*
* @param in
* a {@link forge.control.input.InputBase} object.
* @param bAddToResolving
* a boolean.
*/
public final void setInputInterrupt(final Input in) {
// Make this
this.inputStack.push(in);
this.updateObservers();
}
/**
* <p>
* Getter for the field <code>input</code>.
@@ -91,6 +74,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
*/
public final void clearInput() {
this.inputStack.clear();
this.updateObservers();
}
@@ -102,9 +86,11 @@ public class InputControl extends MyObservable implements java.io.Serializable {
* @param update
* a boolean.
*/
public final void resetInput() {
if ( !this.inputStack.isEmpty() )
this.inputStack.pop();
public final void removeInput(Input inp) {
Input topMostInput = inputStack.isEmpty() ? null : inputStack.pop();
if( topMostInput != inp )
throw new RuntimeException("Inputs adding/removal into stack is imbalanced! Check your code again!");
this.updateObservers();
}
@@ -154,7 +140,7 @@ public class InputControl extends MyObservable implements java.io.Serializable {
stack.freezeStack();
if (playerTurn.isHuman() && !playerTurn.getController().mayAutoPass(phase)) {
game.getCombat().initiatePossibleDefenders(playerTurn.getOpponents());
return new InputAttack();
return new InputAttack(game);
}
break;
@@ -194,34 +180,23 @@ public class InputControl extends MyObservable implements java.io.Serializable {
return pc.getDefaultInput();
} // getInput()
public final void setNewInput(GameState game) {
PhaseHandler ph = game.getPhaseHandler();
final Input tmp = getActualInput(game);
String message = String.format("%s's %s, priority of %s [%sP] input is %s \t stack:%s", ph.getPlayerTurn(), ph.getPhase(), ph.getPriorityPlayer(), ph.isPlayerPriorityAllowed() ? "+" : "-", tmp == null ? "null" : tmp.getClass().getSimpleName(), inputStack);
System.out.println(message);
if (tmp != null) {
//System.out.println(ph.getPlayerTurn() + "'s " + ph.getPhase() + ", priority of " + ph.getPriorityPlayer() + " @ input is " + tmp.getClass().getName() );
CMessage.SINGLETON_INSTANCE.getInputControl().setInput(tmp);
} else if (!ph.isPlayerPriorityAllowed()) {
// System.out.println("cannot have priority, forced to pass");
ph.getPriorityPlayer().getController().passPriority();
}
}
/**
* TODO: Write javadoc for this method.
*/
private final static InputLockUI inpuptLock = new InputLockUI();
private final static InputLockUI inputLock = new InputLockUI();
public void lock() {
setInput(inpuptLock);
setInput(inputLock);
}
public void unlock() {
if ( inputStack.isEmpty() || inputStack.peek() != inpuptLock )
if ( inputStack.isEmpty() || inputStack.peek() != inputLock )
throw new RuntimeException("Trying to unlock input which is not locked! Do check when your threads terminate!");
resetInput();
removeInput(inputLock);
}
// only for debug purposes
public String printInputStack() {
return inputStack.toString();
}
} // InputControl

View File

@@ -174,7 +174,6 @@ public class InputMulligan extends InputBase {
game.setMulliganned(true);
Singletons.getModel().getMatch().getInput().clearInput();
Singletons.getModel().getMatch().getInput().resetInput();
}
@Override

View File

@@ -18,8 +18,6 @@
package forge.control.input;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.Singletons;
@@ -42,7 +40,7 @@ import forge.view.ButtonUtil;
* @author Forge
* @version $Id: InputPayManaCostAbility.java 15673 2012-05-23 14:01:35Z ArsenalNut $
*/
public class InputPayDiscardCostWithCommands extends InputBase implements InputPayment {
public class InputPayDiscardCostWithCommands extends InputSyncronizedBase implements InputPayment {
/**
* Constant <code>serialVersionUID=2685832214529141991L</code>.
*/
@@ -54,8 +52,6 @@ public class InputPayDiscardCostWithCommands extends InputBase implements InputP
private CostDiscard discardCost;
private SpellAbility ability;
private boolean bPaid;
private final CountDownLatch cdlDone;
public final boolean isPaid() { return bPaid; }
/**
@@ -72,10 +68,9 @@ public class InputPayDiscardCostWithCommands extends InputBase implements InputP
* @param unpaidCommand
* a {@link forge.Command} object.
*/
public InputPayDiscardCostWithCommands(final CostDiscard cost, final SpellAbility sa, final CountDownLatch cdl) {
public InputPayDiscardCostWithCommands(final CostDiscard cost, final SpellAbility sa) {
final Card source = sa.getSourceCard();
final Player human = Singletons.getControl().getPlayer();
this.cdlDone = cdl;
this.ability = sa;
this.discardCost = cost;
this.choiceList = CardLists.getValidCards(human.getCardsIn(ZoneType.Hand), cost.getType().split(";"), human, source);
@@ -161,16 +156,13 @@ public class InputPayDiscardCostWithCommands extends InputBase implements InputP
*
*/
public void done() {
this.stop();
for (Card selected : this.discardCost.getList()) {
selected.setUsedToPay(false);
Singletons.getControl().getPlayer().discard(selected, this.ability);
}
this.discardCost.addListToHash(ability, "Discarded");
bPaid = true;
cdlDone.countDown();
this.stop();
}
/**
@@ -180,11 +172,10 @@ public class InputPayDiscardCostWithCommands extends InputBase implements InputP
*
*/
public void cancel() {
this.stop();
for (Card selected : this.discardCost.getList()) {
selected.setUsedToPay(false);
}
bPaid = false;
cdlDone.countDown();
this.stop();
}
}

View File

@@ -28,7 +28,7 @@ import forge.gui.match.views.VMessage;
* TODO: Write javadoc for this type.
*
*/
public abstract class InputPayManaBase extends InputBase {
public abstract class InputPayManaBase extends InputSyncronizedBase {
private static final long serialVersionUID = -9133423708688480255L;
@@ -297,7 +297,7 @@ public abstract class InputPayManaBase extends InputBase {
// save off color needed for use by any mana and reflected mana
subchosen.getManaPart().setExpressChoice(colorsNeeded);
System.out.println("Chosen sa=" + chosen + " of " + chosen.getSourceCard() + " to pay mana");
// System.out.println("Chosen sa=" + chosen + " of " + chosen.getSourceCard() + " to pay mana");
Player p = chosen.getActivatingPlayer();
p.getGame().getActionPlay().playManaAbilityAsPayment(chosen, p, this);
}

View File

@@ -17,8 +17,6 @@
*/
package forge.control.input;
import java.util.concurrent.CountDownLatch;
import forge.Singletons;
import forge.card.mana.ManaCostBeingPaid;
import forge.card.spellability.SpellAbility;
@@ -43,8 +41,6 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
*/
private static final long serialVersionUID = 3836655722696348713L;
final private CountDownLatch cdlDone;
private String originalManaCost;
private String message = "";
@@ -69,8 +65,8 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
* @param unpaidCommand2
* a {@link forge.Command} object.
*/
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2, final CountDownLatch cdl) {
this(game, prompt, manaCost2, cdl, false);
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2) {
this(game, prompt, manaCost2, false);
}
/**
@@ -89,7 +85,7 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
* @param showOKButton
* a boolean.
*/
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2, final CountDownLatch cdl, final boolean showOKButton) {
public InputPayManaExecuteCommands(final GameState game, final String prompt, final String manaCost2, final boolean showOKButton) {
super(game, new SpellAbility(null) {
@Override
public void resolve() {}
@@ -100,7 +96,6 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
this.originalManaCost = manaCost2;
this.phyLifeToLose = 0;
this.message = prompt;
this.cdlDone = cdl;
this.manaCost = new ManaCostBeingPaid(this.originalManaCost);
this.showOnlyOKButton = showOKButton;
@@ -139,7 +134,6 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
Singletons.getControl().getPlayer().getManaPool().clearManaPaid(this.saPaidFor, false);
bPaid = true;
this.stop();
cdlDone.countDown();
}
/** {@inheritDoc} */
@@ -150,17 +144,14 @@ public class InputPayManaExecuteCommands extends InputPayManaBase implements Inp
Singletons.getControl().getPlayer().getManaPool().refundManaPaid(this.saPaidFor, true);
bPaid = false;
this.stop();
cdlDone.countDown();
}
/** {@inheritDoc} */
@Override
public final void selectButtonOK() {
if (this.showOnlyOKButton) {
this.stop();
bPaid = false;
cdlDone.countDown();
this.stop();
}
}

View File

@@ -1,7 +1,5 @@
package forge.control.input;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.Singletons;
import forge.card.cost.CostPartMana;
@@ -21,9 +19,8 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
private final String originalManaCost;
private final int manaToAdd;
private final CostPayment payment;
private final CountDownLatch cdlFinished;
public InputPayManaOfCostPayment(final GameState game, CostPartMana costMana, SpellAbility spellAbility, final CostPayment payment, int toAdd, CountDownLatch cdl) {
public InputPayManaOfCostPayment(final GameState game, CostPartMana costMana, SpellAbility spellAbility, final CostPayment payment, int toAdd) {
super(game, spellAbility);
manaCost = new ManaCostBeingPaid(costMana.getManaToPay());
manaCost.increaseColorlessMana(toAdd);
@@ -32,7 +29,6 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
originalManaCost = costMana.getMana();
manaToAdd = toAdd;
this.payment = payment;
cdlFinished = cdl;
}
private static final long serialVersionUID = 3467312982164195091L;
@@ -66,14 +62,9 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
source.setColorsPaid(this.manaCost.getColorsPaid());
source.setSunburstValue(this.manaCost.getSunburst());
this.resetManaCost();
this.stop();
if (costMana.hasNoXManaCost() || (manaToAdd > 0)) {
payment.setPaidPart(costMana);
} else {
source.setXManaCostPaid(0);
final InputBase inp = new InputPayManaX(game, saPaidFor, payment, costMana, cdlFinished);
Singletons.getModel().getMatch().getInput().setInputInterrupt(inp);
}
// If this is a spell with convoke, re-tap all creatures used for it.
@@ -82,17 +73,16 @@ public class InputPayManaOfCostPayment extends InputPayManaBase {
// any mana tapabilities can't be used in payment as well as being tapped for convoke)
handleConvokedCards(false);
cdlFinished.countDown();
stop();
}
@Override
public void selectButtonCancel() {
handleConvokedCards(true);
this.stop();
this.resetManaCost();
payment.cancelCost();
cdlFinished.countDown();
stop();
}
@Override

View File

@@ -17,9 +17,7 @@
*/
package forge.control.input;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.Singletons;
import forge.card.mana.ManaCostBeingPaid;
import forge.card.spellability.SpellAbility;
import forge.game.GameState;
@@ -38,9 +36,8 @@ public class InputPayManaSimple extends InputPayManaBase {
private final Card originalCard;
private final String originalManaCost;
private final CountDownLatch cdlNotify;
public InputPayManaSimple(final GameState game, final SpellAbility sa, final ManaCostBeingPaid manaCostToPay, final CountDownLatch callOnDone) {
public InputPayManaSimple(final GameState game, final SpellAbility sa, final ManaCostBeingPaid manaCostToPay) {
super(game, sa);
this.originalManaCost = manaCostToPay.toString(); // Change
this.originalCard = sa.getSourceCard();
@@ -52,7 +49,6 @@ public class InputPayManaSimple extends InputPayManaBase {
this.manaCost = manaCostToPay;
}
cdlNotify = callOnDone;
}
/**
@@ -106,8 +102,7 @@ public class InputPayManaSimple extends InputPayManaBase {
handleConvokedCards(false);
}
Singletons.getModel().getMatch().getInput().resetInput();
cdlNotify.countDown();
stop();
}
/** {@inheritDoc} */

View File

@@ -1,7 +1,5 @@
package forge.control.input;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.card.cost.CostPartMana;
import forge.card.cost.CostPayment;
@@ -19,10 +17,9 @@ public class InputPayManaX extends InputPayManaBase {
private String colorsPaid;
private final CostPartMana costMana;
private final CostPayment payment;
private final CountDownLatch cdlFinished;
public InputPayManaX(final GameState game, final SpellAbility sa0, final CostPayment payment0, final CostPartMana costMana0, final CountDownLatch cdl)
public InputPayManaX(final GameState game, final SpellAbility sa0, final CostPayment payment0, final CostPartMana costMana0)
{
super(game, sa0);
@@ -33,7 +30,6 @@ public class InputPayManaX extends InputPayManaBase {
costMana = costMana0;
strX = Integer.toString(costMana.getXMana());
manaCost = new ManaCostBeingPaid(strX);
cdlFinished = cdl;
}
@Override
@@ -76,14 +72,12 @@ public class InputPayManaX extends InputPayManaBase {
@Override
public void selectButtonCancel() {
this.stop();
payment.cancelCost();
cdlFinished.countDown();
this.stop();
}
@Override
public void selectButtonOK() {
this.stop();
done();
}
@@ -99,6 +93,6 @@ public class InputPayManaX extends InputPayManaBase {
payment.setPaidPart(costMana);
payment.getCard().setColorsPaid(this.colorsPaid);
payment.getCard().setSunburstValue(this.colorsPaid.length());
cdlFinished.countDown();
this.stop();
}
}

View File

@@ -18,8 +18,6 @@
package forge.control.input;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import forge.Card;
import forge.CardLists;
import forge.Singletons;
@@ -41,7 +39,7 @@ import forge.view.ButtonUtil;
* @author Forge
* @version $Id: InputPayManaCostAbility.java 15673 2012-05-23 14:01:35Z ArsenalNut $
*/
public class InputPayReturnCost extends InputBase implements InputPayment {
public class InputPayReturnCost extends InputSyncronizedBase implements InputPayment {
/**
* Constant <code>serialVersionUID=2685832214529141991L</code>.
*/
@@ -56,8 +54,6 @@ public class InputPayReturnCost extends InputBase implements InputPayment {
private boolean bPaid;
public boolean isPaid() { return bPaid; }
private final CountDownLatch cdlDone;
/**
* <p>
* Constructor for InputPayReturnCost.
@@ -72,10 +68,10 @@ public class InputPayReturnCost extends InputBase implements InputPayment {
* @param unpaidCommand
* a {@link forge.Command} object.
*/
public InputPayReturnCost(final CostReturn cost, final SpellAbility sa, final CountDownLatch cdl) {
public InputPayReturnCost(final CostReturn cost, final SpellAbility sa) {
final Card source = sa.getSourceCard();
this.cdlDone = cdl;
this.ability = sa;
this.returnCost = cost;
this.choiceList = CardLists.getValidCards(Singletons.getControl().getPlayer().getCardsIn(ZoneType.Battlefield), cost.getType().split(";"), Singletons.getControl().getPlayer(), source);
@@ -162,7 +158,7 @@ public class InputPayReturnCost extends InputBase implements InputPayment {
*
*/
public void done() {
this.stop();
// actually sacrifice the cards
for (Card selected : this.returnCost.getList()) {
selected.setUsedToPay(false);
@@ -170,7 +166,7 @@ public class InputPayReturnCost extends InputBase implements InputPayment {
}
this.returnCost.addListToHash(ability, "Returned");
bPaid = true;
cdlDone.countDown();
this.stop();
}
/**
@@ -180,11 +176,10 @@ public class InputPayReturnCost extends InputBase implements InputPayment {
*
*/
public void cancel() {
this.stop();
for (Card selected : this.returnCost.getList()) {
selected.setUsedToPay(false);
}
bPaid = false;
cdlDone.countDown();
this.stop();
}
}

View File

@@ -0,0 +1,6 @@
package forge.control.input;
public interface InputSynchronized extends Input {
public void awaitLatchRelease();
}

View File

@@ -0,0 +1,31 @@
package forge.control.input;
import java.util.concurrent.CountDownLatch;
import forge.FThreads;
import forge.error.BugReporter;
public abstract class InputSyncronizedBase extends InputBase implements InputSynchronized {
private static final long serialVersionUID = 8756177361251703052L;
private final CountDownLatch cdlDone;
public InputSyncronizedBase() {
cdlDone = new CountDownLatch(1);
}
public void awaitLatchRelease() {
FThreads.checkEDT("InputSyncronizedBase.awaitLatchRelease", false);
try{
cdlDone.await();
} catch (InterruptedException e) {
BugReporter.reportException(e);
}
}
@Override
protected void afterStop() {
cdlDone.countDown();
}
}

View File

@@ -2,7 +2,6 @@ package forge.game;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import com.google.common.collect.Lists;
import forge.Card;
@@ -24,10 +23,8 @@ import forge.card.spellability.SpellAbilityRequirements;
import forge.card.spellability.Target;
import forge.card.spellability.TargetSelection;
import forge.card.staticability.StaticAbility;
import forge.control.input.InputControl;
import forge.control.input.InputPayManaBase;
import forge.control.input.InputPayManaSimple;
import forge.error.BugReporter;
import forge.game.ai.ComputerUtilCard;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
@@ -40,12 +37,10 @@ import forge.gui.GuiChoose;
public class GameActionPlay {
private final GameState game;
private final InputControl matchInput;
public GameActionPlay(final GameState game0, InputControl input) {
public GameActionPlay(final GameState game0) {
game = game0;
this.matchInput = input;
}
public final void playCardWithoutManaCost(final Card c, Player player) {
@@ -407,13 +402,7 @@ public class GameActionPlay {
}
if (!manaCost.isPaid()) {
CountDownLatch cdlWaitForPayment = new CountDownLatch(1);
matchInput.setInput(new InputPayManaSimple(game, sa, manaCost, cdlWaitForPayment));
try {
cdlWaitForPayment.await();
} catch (Exception e) {
BugReporter.reportException(e);
}
FThreads.setInputAndWait(new InputPayManaSimple(game, sa, manaCost));
}
@@ -458,16 +447,9 @@ public class GameActionPlay {
} else {
manaCost = this.getSpellCostChange(sa, new ManaCostBeingPaid(sa.getManaCost()));
}
final CountDownLatch cdlWaitForPayment = new CountDownLatch(1);
if( !manaCost.isPaid() ) {
matchInput.setInput(new InputPayManaSimple(game, sa, getSpellCostChange(sa, new ManaCostBeingPaid(sa.getManaCost())), cdlWaitForPayment));
try {
cdlWaitForPayment.await();
} catch (Exception e) {
BugReporter.reportException(e);
}
FThreads.setInputAndWait(new InputPayManaSimple(game, sa, getSpellCostChange(sa, new ManaCostBeingPaid(sa.getManaCost()))));
}
if (manaCost.isPaid()) {

View File

@@ -20,8 +20,6 @@ package forge.game;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.Iterables;
@@ -59,11 +57,11 @@ import forge.card.spellability.AbilityManaPart;
import forge.card.spellability.AbilitySub;
import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityRestriction;
import forge.control.input.InputBase;
import forge.control.input.InputPayDiscardCostWithCommands;
import forge.control.input.InputPayManaExecuteCommands;
import forge.control.input.InputPayReturnCost;
import forge.control.input.InputPayment;
import forge.control.input.InputSynchronized;
import forge.game.event.CardDamagedEvent;
import forge.game.event.LifeLossEvent;
import forge.game.player.AIPlayer;
@@ -577,21 +575,20 @@ public final class GameActionUtil {
//the following costs need inputs and can't be combined at the moment
InputBase toSet = null;
CountDownLatch cdl = new CountDownLatch(1);
InputSynchronized toSet = null;
if (costPart instanceof CostReturn) {
toSet = new InputPayReturnCost((CostReturn) costPart, ability, cdl);
toSet = new InputPayReturnCost((CostReturn) costPart, ability);
}
else if (costPart instanceof CostDiscard) {
toSet = new InputPayDiscardCostWithCommands((CostDiscard) costPart, ability, cdl);
toSet = new InputPayDiscardCostWithCommands((CostDiscard) costPart, ability);
}
else if (costPart instanceof CostPartMana) {
toSet = new InputPayManaExecuteCommands(game, source + "\r\n", ability.getManaCost().toString(), cdl);
toSet = new InputPayManaExecuteCommands(game, source + "\r\n", ability.getManaCost().toString());
}
if (toSet != null) {
FThreads.setInputAndWait(toSet, cdl);
FThreads.setInputAndWait(toSet);
if (((InputPayment)toSet).isPaid() ) {
paid.execute();
} else {

View File

@@ -1,41 +0,0 @@
package forge.game;
import forge.error.BugReporter;
import forge.gui.match.controllers.CMessage;
/**
* TODO: Write javadoc for this type.
*
*/
public final class GameInputUpdatesThread extends Thread {
private final MatchController match;
private final GameState game;
private boolean wasChangedRecently;
/**
* TODO: Write javadoc for Constructor.
* @param match
* @param game
*/
public GameInputUpdatesThread(MatchController match, GameState game) {
this.match = match;
this.game = game;
}
public void run(){
while(!game.isGameOver()) {
boolean needsNewInput = CMessage.SINGLETON_INSTANCE.getInputControl().isValid() == false;
if ( needsNewInput ) {
match.getInput().setNewInput(game);
wasChangedRecently = true;
}
try {
Thread.sleep(wasChangedRecently ? 2 : 40);
wasChangedRecently = false;
} catch (InterruptedException e) {
BugReporter.reportException(e);
break;
}
}
}
}

View File

@@ -37,7 +37,6 @@ import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellAbilityStackInstance;
import forge.card.trigger.TriggerHandler;
import forge.card.trigger.TriggerType;
import forge.control.input.InputControl;
import forge.game.phase.Cleanup;
import forge.game.phase.Combat;
import forge.game.phase.EndOfCombat;
@@ -98,7 +97,7 @@ public class GameState {
* @param match0
* @param input
*/
public GameState(Iterable<LobbyPlayer> players2, GameType t, MatchController match0, InputControl input) { /* no more zones to map here */
public GameState(Iterable<LobbyPlayer> players2, GameType t, MatchController match0) { /* no more zones to map here */
type = t;
List<Player> players = new ArrayList<Player>();
for (LobbyPlayer p : players2) {
@@ -110,7 +109,7 @@ public class GameState {
allPlayers = Collections.unmodifiableList(players);
roIngamePlayers = Collections.unmodifiableList(ingamePlayers);
action = new GameAction(this);
actionPlay = new GameActionPlay(this, input);
actionPlay = new GameActionPlay(this);
stack = new MagicStack(this);
phaseHandler = new PhaseHandler(this);

View File

@@ -130,7 +130,7 @@ public class MatchController {
// Deal with circular dependencies here
input = new InputControl();
currentGame = Singletons.getModel().newGame(players.keySet(),gameType, this, input);
currentGame = Singletons.getModel().newGame(players.keySet(),gameType, this);
Map<Player, PlayerStartConditions> startConditions = new HashMap<Player, PlayerStartConditions>();
for (Player p : currentGame.getPlayers()) {
@@ -165,9 +165,11 @@ public class MatchController {
SDisplayUtil.showTab(EDocID.REPORT_LOG.getDoc());
InputProxy inputControl = CMessage.SINGLETON_INSTANCE.getInputControl();
inputControl.setMatch(this);
input.addObserver(inputControl);
currentGame.getStack().addObserver(inputControl);
currentGame.getPhaseHandler().addObserver(inputControl);
currentGame.getGameLog().addObserver(CLog.SINGLETON_INSTANCE);
currentGame.getStack().addObserver(CStack.SINGLETON_INSTANCE);
// some observers are set in CMatchUI.initMatch
@@ -176,7 +178,6 @@ public class MatchController {
GameNew.newGame(this, startConditions, currentGame, canRandomFoil);
getInput().clearInput();
getInput().resetInput();
//getInput().setNewInput(currentGame);

View File

@@ -816,5 +816,10 @@ public class PhaseHandler extends MyObservable implements java.io.Serializable {
public void incPlanarDiceRolledthisTurn() {
this.planarDiceRolledthisTurn++;
}
public String debugPrintState() {
return String.format("%s's %s, priority of %s [%sP]", getPlayerTurn(), getPhase(), getPriorityPlayer(), isPlayerPriorityAllowed() ? "+" : "-");
}
}

View File

@@ -21,8 +21,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import com.google.common.base.Predicate;
import forge.Card;
@@ -288,9 +286,8 @@ public class Upkeep extends Phase {
public void resolve() {
final boolean isUpkeepPaid;
if (controller.isHuman()) {
CountDownLatch cdl = new CountDownLatch(1);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, sb, upkeepCost.toString(), cdl);
FThreads.setInputAndWait(inp, cdl);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, sb, upkeepCost.toString());
FThreads.setInputAndWait(inp);
isUpkeepPaid = inp.isPaid();
} else { // computer
Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
@@ -386,9 +383,8 @@ public class Upkeep extends Phase {
public void resolve() {
boolean isUpkeepPaid = false;
if (controller.isHuman()) {
CountDownLatch cdl = new CountDownLatch(1);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, sb, upkeepCost.toString(), cdl);
FThreads.setInputAndWait(inp, cdl);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, sb, upkeepCost.toString());
FThreads.setInputAndWait(inp);
isUpkeepPaid = inp.isPaid();
} else { // computers
final Ability aiPaid = Upkeep.BlankAbility(c, upkeepCost.toString());
@@ -635,9 +631,8 @@ public class Upkeep extends Phase {
@Override
public void resolve() {
if (game.getZoneOf(c).is(ZoneType.Battlefield)) {
CountDownLatch cdl = new CountDownLatch(1);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, "Pay Demonic Hordes upkeep cost", cost.getManaCost().toString(), cdl/*, true */);
FThreads.setInputAndWait(inp, cdl);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, "Pay Demonic Hordes upkeep cost", cost.getManaCost().toString() /*, true */);
FThreads.setInputAndWait(inp);
if ( !inp.isPaid() )
unpaidHordesAb.resolve();
}

View File

@@ -22,8 +22,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Stack;
import java.util.concurrent.CountDownLatch;
import com.esotericsoftware.minlog.Log;
import forge.Card;
@@ -489,9 +487,8 @@ public class MagicStack extends MyObservable {
final Card crd = sa.getSourceCard();
String message = "Pay X cost for " + crd.getName() + " (X=" + crd.getXManaCostPaid() + ")\r\n";
CountDownLatch cdl = new CountDownLatch(1);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, message, String.valueOf(xCost), cdl, true);
FThreads.setInputAndWait(inp, cdl);
InputPayManaExecuteCommands inp = new InputPayManaExecuteCommands(game, message, String.valueOf(xCost), true);
FThreads.setInputAndWait(inp);
if ( inp.isPaid() ) {
crd.addXManaCostPaid(1);
this.run();
@@ -565,9 +562,8 @@ public class MagicStack extends MyObservable {
prompt = String.format("Multikicker for %s\r\nMana in Reserve: %s %s\r\nTimes Kicked: %d", sa.getSourceCard(),
(mkCostPaid != 0) ? Integer.toString(mkCostPaid) : "", mkCostPaidColored, mkMagnitude);
}
CountDownLatch cdl = new CountDownLatch(1);
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString(), cdl);
FThreads.setInputAndWait(toSet, cdl);
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString());
FThreads.setInputAndWait(toSet);
if ( toSet.isPaid() ) {
this.execute();
} else
@@ -613,9 +609,8 @@ public class MagicStack extends MyObservable {
this.run();
} else {
String prompt = String.format("Replicate for %s\r\nTimes Replicated: %d\r\n", sa.getSourceCard(), sa.getSourceCard().getReplicateMagnitude());
CountDownLatch cdl = new CountDownLatch(1);
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString(), cdl);
FThreads.setInputAndWait(toSet, cdl);
InputPayManaExecuteCommands toSet = new InputPayManaExecuteCommands(game, prompt, manaCost.toString());
FThreads.setInputAndWait(toSet);
if ( toSet.isPaid() ) {
this.run();
} else {

View File

@@ -22,8 +22,10 @@ import java.util.Observer;
import forge.Card;
import forge.FThreads;
import forge.Singletons;
import forge.control.input.Input;
import forge.game.GameState;
import forge.game.MatchController;
import forge.game.phase.PhaseHandler;
import forge.game.player.Player;
import forge.view.ButtonUtil;
@@ -39,39 +41,29 @@ public class InputProxy implements Observer {
/** The input. */
private Input input;
private boolean valid = false;
private MatchController match = null;
public void setMatch(MatchController matchController) {
match = matchController;
}
@Override
public final synchronized void update(final Observable observable, final Object obj) {
ButtonUtil.disableAll();
valid = false;
GameState game = match.getCurrentGame();
PhaseHandler ph = game.getPhaseHandler();
Singletons.getModel().getMatch().getInput().setNewInput(Singletons.getModel().getGame());
}
/**
* <p>
* Setter for the field <code>input</code>.
* </p>
*
* @param in
* a {@link forge.control.input.InputBase} object.
*/
public final synchronized void setInput(final Input in) {
valid = true;
this.input = in;
final Input nextInput = match.getInput().getActualInput(game);
System.out.print(ph.debugPrintState());
System.out.printf(" input is %s \t stack = %s%n", nextInput == null ? "null" : nextInput.getClass().getSimpleName(), match.getInput().printInputStack());
if ( null == input ) {
throw new NullPointerException("input is null");
if (nextInput != null) {
this.input = nextInput;
FThreads.invokeInEDT(new Runnable() { @Override public void run() { nextInput.showMessage(); } });
} else if (!ph.isPlayerPriorityAllowed()) {
ph.getPriorityPlayer().getController().passPriority();
}
FThreads.invokeInEDT(new Runnable() {
@Override
public void run() {
InputProxy.this.input.showMessage(); // this call may invalidate the input by the time it returns
}
});
}
/**
* <p>
* selectButtonOK.
@@ -126,9 +118,4 @@ public class InputProxy implements Observer {
public Input getInput() {
return this.input;
}
public synchronized boolean isValid() {
return valid;
}
}

View File

@@ -35,7 +35,6 @@ import forge.card.EditionCollection;
import forge.card.FatPackData;
import forge.card.FormatCollection;
import forge.card.cardfactory.CardStorageReader;
import forge.control.input.InputControl;
import forge.deck.CardCollections;
import forge.error.BugReporter;
import forge.error.ExceptionHandler;
@@ -404,8 +403,8 @@ public enum FModel {
* @param players
* @param input
*/
public GameState newGame(Iterable<LobbyPlayer> players, GameType type, final MatchController match0, InputControl input) {
gameState = new GameState(players,type, match0, input);
public GameState newGame(Iterable<LobbyPlayer> players, GameType type, final MatchController match0) {
gameState = new GameState(players,type, match0);
return gameState;
}