mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 12:48:00 +00:00
Added locking UI input, added guards to playAbility, playLand and discard to disallow their execution from EDT
merged trunk up to 20537
This commit is contained in:
3
.gitattributes
vendored
3
.gitattributes
vendored
@@ -13696,6 +13696,7 @@ src/main/java/forge/Command.java svneol=native#text/plain
|
|||||||
src/main/java/forge/CommandList.java svneol=native#text/plain
|
src/main/java/forge/CommandList.java svneol=native#text/plain
|
||||||
src/main/java/forge/Constant.java svneol=native#text/plain
|
src/main/java/forge/Constant.java svneol=native#text/plain
|
||||||
src/main/java/forge/CounterType.java svneol=native#text/plain
|
src/main/java/forge/CounterType.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/FThreads.java -text
|
||||||
src/main/java/forge/GameEntity.java -text
|
src/main/java/forge/GameEntity.java -text
|
||||||
src/main/java/forge/GameLog.java -text
|
src/main/java/forge/GameLog.java -text
|
||||||
src/main/java/forge/ImageCache.java svneol=native#text/plain
|
src/main/java/forge/ImageCache.java svneol=native#text/plain
|
||||||
@@ -14080,6 +14081,7 @@ src/main/java/forge/control/input/InputAttack.java svneol=native#text/plain
|
|||||||
src/main/java/forge/control/input/InputBlock.java svneol=native#text/plain
|
src/main/java/forge/control/input/InputBlock.java svneol=native#text/plain
|
||||||
src/main/java/forge/control/input/InputCleanup.java svneol=native#text/plain
|
src/main/java/forge/control/input/InputCleanup.java svneol=native#text/plain
|
||||||
src/main/java/forge/control/input/InputControl.java svneol=native#text/plain
|
src/main/java/forge/control/input/InputControl.java svneol=native#text/plain
|
||||||
|
src/main/java/forge/control/input/InputLockUI.java -text
|
||||||
src/main/java/forge/control/input/InputMulligan.java svneol=native#text/plain
|
src/main/java/forge/control/input/InputMulligan.java svneol=native#text/plain
|
||||||
src/main/java/forge/control/input/InputPassPriority.java svneol=native#text/plain
|
src/main/java/forge/control/input/InputPassPriority.java svneol=native#text/plain
|
||||||
src/main/java/forge/control/input/InputPayDiscardCost.java -text
|
src/main/java/forge/control/input/InputPayDiscardCost.java -text
|
||||||
@@ -14520,7 +14522,6 @@ src/main/java/forge/util/MyRandom.java svneol=native#text/plain
|
|||||||
src/main/java/forge/util/PredicateString.java -text
|
src/main/java/forge/util/PredicateString.java -text
|
||||||
src/main/java/forge/util/ReflectionUtil.java -text
|
src/main/java/forge/util/ReflectionUtil.java -text
|
||||||
src/main/java/forge/util/TextUtil.java -text
|
src/main/java/forge/util/TextUtil.java -text
|
||||||
src/main/java/forge/util/ThreadUtil.java svneol=native#text/plain
|
|
||||||
src/main/java/forge/util/XmlUtil.java -text
|
src/main/java/forge/util/XmlUtil.java -text
|
||||||
src/main/java/forge/util/package-info.java -text
|
src/main/java/forge/util/package-info.java -text
|
||||||
src/main/java/forge/util/storage/IStorage.java -text
|
src/main/java/forge/util/storage/IStorage.java -text
|
||||||
|
|||||||
94
src/main/java/forge/FThreads.java
Normal file
94
src/main/java/forge/FThreads.java
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package forge;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
import forge.control.input.InputLockUI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this type.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class FThreads {
|
||||||
|
|
||||||
|
private final static ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||||
|
public static ExecutorService getCachedPool() {
|
||||||
|
return threadPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This pool is designed to parallel CPU or IO intensive tasks like parse cards or download images, assuming a load factor of 0.5
|
||||||
|
public final static ExecutorService getComputingPool(float loadFactor) {
|
||||||
|
return Executors.newFixedThreadPool((int)(Runtime.getRuntime().availableProcessors() / (1-loadFactor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isMultiCoreSystem() {
|
||||||
|
return Runtime.getRuntime().availableProcessors() > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Checks if calling method uses event dispatch thread.
|
||||||
|
* Exception thrown if method is on "wrong" thread.
|
||||||
|
* A boolean is passed to indicate if the method must be EDT or not.
|
||||||
|
*
|
||||||
|
* @param methodName   String, part of the custom exception message.
|
||||||
|
* @param mustBeEDT   boolean: true = exception if not EDT, false = exception if EDT
|
||||||
|
*/
|
||||||
|
public static void checkEDT(final String methodName, final boolean mustBeEDT) {
|
||||||
|
boolean isEDT = SwingUtilities.isEventDispatchThread();
|
||||||
|
if ( isEDT != mustBeEDT ) {
|
||||||
|
String modalOperator = mustBeEDT ? " must be" : " may not be";
|
||||||
|
throw new IllegalStateException( methodName + modalOperator + " accessed from the event dispatch thread.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this method.
|
||||||
|
* @param runnable
|
||||||
|
*/
|
||||||
|
public static void invokeInEDT(Runnable runnable) {
|
||||||
|
SwingUtilities.invokeLater(runnable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoke the given Runnable in an Event Dispatch Thread and wait for it to
|
||||||
|
* finish; but <B>try to use SwingUtilities.invokeLater instead whenever
|
||||||
|
* feasible.</B>
|
||||||
|
*
|
||||||
|
* Exceptions generated by SwingUtilities.invokeAndWait (if used), are
|
||||||
|
* rethrown as RuntimeExceptions.
|
||||||
|
*
|
||||||
|
* @param proc
|
||||||
|
* the Runnable to run
|
||||||
|
* @see javax.swing.SwingUtilities#invokeLater(Runnable)
|
||||||
|
*/
|
||||||
|
public static void invokeInEDTAndWait(final Runnable proc) {
|
||||||
|
if (SwingUtilities.isEventDispatchThread()) {
|
||||||
|
// Just run in the current thread.
|
||||||
|
proc.run();
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
SwingUtilities.invokeAndWait(proc);
|
||||||
|
} catch (final InterruptedException exn) {
|
||||||
|
throw new RuntimeException(exn);
|
||||||
|
} catch (final InvocationTargetException exn) {
|
||||||
|
throw new RuntimeException(exn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void invokeInNewThread(Runnable proc) {
|
||||||
|
invokeInNewThread(proc, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static InputLockUI inpuptLock = new InputLockUI();
|
||||||
|
public static void invokeInNewThread(Runnable proc, boolean lockUI) {
|
||||||
|
getCachedPool().execute(proc);
|
||||||
|
if( lockUI ) {
|
||||||
|
Singletons.getModel().getMatch().getInput().setInput(inpuptLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -153,13 +153,21 @@ public class StaticEffects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (params.containsKey("AddColor")) {
|
if (params.containsKey("AddColor")) {
|
||||||
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(params.get("AddColor").split(
|
final String colors = params.get("AddColor");
|
||||||
" & "))));
|
if (colors.equals("ChosenColor")) {
|
||||||
|
addColors = CardUtil.getShortColorsString(se.getSource().getChosenColor());
|
||||||
|
} else {
|
||||||
|
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(" & "))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.containsKey("SetColor")) {
|
if (params.containsKey("SetColor")) {
|
||||||
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(params.get("SetColor").split(
|
final String colors = params.get("SetColor");
|
||||||
" & "))));
|
if (colors.equals("ChosenColor")) {
|
||||||
|
addColors = CardUtil.getShortColorsString(se.getSource().getChosenColor());
|
||||||
|
} else {
|
||||||
|
addColors = CardUtil.getShortColorsString(new ArrayList<String>(Arrays.asList(colors.split(" & "))));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify players
|
// modify players
|
||||||
|
|||||||
@@ -927,7 +927,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
final ZoneType origin = ZoneType.smartValueOf(sa.getParam("Origin"));
|
final ZoneType origin = ZoneType.listValueOf(sa.getParam("Origin")).get(0);
|
||||||
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
final ZoneType destination = ZoneType.smartValueOf(sa.getParam("Destination"));
|
||||||
final Target tgt = sa.getTarget();
|
final Target tgt = sa.getTarget();
|
||||||
|
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ public class DiscardEffect extends RevealEffectBase {
|
|||||||
} else if (mode.equals("RevealYouChoose") || mode.equals("RevealOppChoose") || mode.equals("TgtChoose")) {
|
} else if (mode.equals("RevealYouChoose") || mode.equals("RevealOppChoose") || mode.equals("TgtChoose")) {
|
||||||
// Is Reveal you choose right? I think the wrong player is
|
// Is Reveal you choose right? I think the wrong player is
|
||||||
// being used?
|
// being used?
|
||||||
List<Card> dPHand = p.getCardsIn(ZoneType.Hand);
|
List<Card> dPHand = new ArrayList<Card>(p.getCardsIn(ZoneType.Hand));
|
||||||
if (dPHand.isEmpty())
|
if (dPHand.isEmpty())
|
||||||
continue; // for loop over players
|
continue; // for loop over players
|
||||||
|
|
||||||
|
|||||||
@@ -5,18 +5,11 @@ import java.util.List;
|
|||||||
|
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.Singletons;
|
|
||||||
import forge.card.cost.Cost;
|
import forge.card.cost.Cost;
|
||||||
import forge.card.spellability.AbilityActivated;
|
import forge.card.spellability.AbilityActivated;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.control.input.Input;
|
|
||||||
import forge.control.input.InputSelectManyCards;
|
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.PlayerZone;
|
|
||||||
import forge.game.zone.Zone;
|
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.gui.GuiChoose;
|
|
||||||
import forge.gui.match.CMatchUI;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Write javadoc for this type.
|
* TODO: Write javadoc for this type.
|
||||||
@@ -102,96 +95,5 @@ class CardFactoryArtifacts {
|
|||||||
ab1.setStackDescription(sb.toString());
|
ab1.setStackDescription(sb.toString());
|
||||||
card.addSpellAbility(ab1);
|
card.addSpellAbility(ab1);
|
||||||
} // *************** END ************ END **************************
|
} // *************** END ************ END **************************
|
||||||
|
|
||||||
// *************** START *********** START **************************
|
|
||||||
else if (cardName.equals("Scroll Rack")) {
|
|
||||||
class AbilityScrollRack extends AbilityActivated {
|
|
||||||
public AbilityScrollRack(final Card ca, final Cost co, final Target t) {
|
|
||||||
super(ca, co, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AbilityActivated getCopy() {
|
|
||||||
AbilityActivated res = new AbilityScrollRack(getSourceCard(),
|
|
||||||
getPayCosts(), getTarget() == null ? null : new Target(getTarget()));
|
|
||||||
CardFactory.copySpellAbility(this, res);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final long serialVersionUID = -5588587187720068547L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void resolve() {
|
|
||||||
// not implemented for compy
|
|
||||||
if (card.getController().isHuman()) {
|
|
||||||
|
|
||||||
InputSelectManyCards inp = new InputSelectManyCards(0, Integer.MAX_VALUE) {
|
|
||||||
private static final long serialVersionUID = 806464726820739922L;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean isValidChoice(Card c) {
|
|
||||||
Zone zone = Singletons.getModel().getGame().getZoneOf(c);
|
|
||||||
return zone.is(ZoneType.Hand) && c.getController() == card.getController();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see forge.control.input.InputSelectManyCards#onDone()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected Input onDone() {
|
|
||||||
for (final Card c : selected) {
|
|
||||||
Singletons.getModel().getGame().getAction().exile(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Put that many cards from the top of your
|
|
||||||
// library into your hand.
|
|
||||||
// Ruling: This is not a draw...
|
|
||||||
final PlayerZone lib = card.getController().getZone(ZoneType.Library);
|
|
||||||
int numCards = 0;
|
|
||||||
while ((lib.size() > 0) && (numCards < selected.size())) {
|
|
||||||
Singletons.getModel().getGame().getAction().moveToHand(lib.get(0));
|
|
||||||
numCards++;
|
|
||||||
}
|
|
||||||
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append(card.getName()).append(" - Returning cards to top of library.");
|
|
||||||
CMatchUI.SINGLETON_INSTANCE.showMessage(sb.toString());
|
|
||||||
|
|
||||||
// Then look at the exiled cards and put them on
|
|
||||||
// top of your library in any order.
|
|
||||||
while (selected.size() > 0) {
|
|
||||||
final Card c1 = GuiChoose.one("Put a card on top of your library.", selected);
|
|
||||||
Singletons.getModel().getGame().getAction().moveToLibrary(c1);
|
|
||||||
selected.remove(c1);
|
|
||||||
}
|
|
||||||
return null; }
|
|
||||||
};
|
|
||||||
inp.setMessage(card.getName() + " - Exile cards from hand. Currently, %d selected. (Press OK when done.)");
|
|
||||||
|
|
||||||
Singletons.getModel().getMatch().getInput().setInput(inp);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canPlayAI() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final Cost abCost = new Cost(card, "1 T", true);
|
|
||||||
final AbilityActivated ability = new AbilityScrollRack(card, abCost, null);
|
|
||||||
|
|
||||||
final StringBuilder sbDesc = new StringBuilder();
|
|
||||||
sbDesc.append(abCost);
|
|
||||||
sbDesc.append("Exile any number of cards from your hand face down. Put that many cards ");
|
|
||||||
sbDesc.append("from the top of your library into your hand. Then look at the exiled cards ");
|
|
||||||
sbDesc.append("and put them on top of your library in any order.");
|
|
||||||
ability.setDescription(sbDesc.toString());
|
|
||||||
|
|
||||||
final StringBuilder sbStack = new StringBuilder();
|
|
||||||
sbStack.append(cardName).append(" - exile any number of cards from your hand.");
|
|
||||||
ability.setStackDescription(sbStack.toString());
|
|
||||||
card.addSpellAbility(ability);
|
|
||||||
} // *************** END ************ END **************************
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ import javax.swing.SwingUtilities;
|
|||||||
|
|
||||||
import org.apache.commons.lang.time.StopWatch;
|
import org.apache.commons.lang.time.StopWatch;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
import forge.card.CardRules;
|
import forge.card.CardRules;
|
||||||
import forge.card.CardRulesReader;
|
import forge.card.CardRulesReader;
|
||||||
import forge.control.FControl;
|
|
||||||
import forge.error.BugReporter;
|
import forge.error.BugReporter;
|
||||||
import forge.gui.toolbox.FProgressBar;
|
import forge.gui.toolbox.FProgressBar;
|
||||||
import forge.util.FileUtil;
|
import forge.util.FileUtil;
|
||||||
@@ -62,7 +62,7 @@ public class CardStorageReader {
|
|||||||
/** Default charset when loading from files. */
|
/** Default charset when loading from files. */
|
||||||
public static final String DEFAULT_CHARSET_NAME = "US-ASCII";
|
public static final String DEFAULT_CHARSET_NAME = "US-ASCII";
|
||||||
|
|
||||||
final private boolean useThreadPool = FControl.isMultiCoreSystem();
|
final private boolean useThreadPool = FThreads.isMultiCoreSystem();
|
||||||
final private int NUMBER_OF_PARTS = 25;
|
final private int NUMBER_OF_PARTS = 25;
|
||||||
|
|
||||||
final private CountDownLatch cdl = new CountDownLatch(NUMBER_OF_PARTS);
|
final private CountDownLatch cdl = new CountDownLatch(NUMBER_OF_PARTS);
|
||||||
@@ -209,7 +209,7 @@ public class CardStorageReader {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if ( useThreadPool ) {
|
if ( useThreadPool ) {
|
||||||
final ExecutorService executor = FControl.getComputingPool(0.5f);
|
final ExecutorService executor = FThreads.getComputingPool(0.5f);
|
||||||
final List<Future<List<CardRules>>> parts = executor.invokeAll(tasks);
|
final List<Future<List<CardRules>>> parts = executor.invokeAll(tasks);
|
||||||
executor.shutdown();
|
executor.shutdown();
|
||||||
cdl.await();
|
cdl.await();
|
||||||
|
|||||||
@@ -25,9 +25,6 @@ import java.awt.event.WindowEvent;
|
|||||||
import java.awt.event.WindowListener;
|
import java.awt.event.WindowListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JLayeredPane;
|
import javax.swing.JLayeredPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
@@ -85,8 +82,6 @@ public enum FControl {
|
|||||||
DRAFTING_PROCESS
|
DRAFTING_PROCESS
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ExecutorService threadPool = Executors.newCachedThreadPool();
|
|
||||||
|
|
||||||
private final SoundSystem soundSystem = new SoundSystem();
|
private final SoundSystem soundSystem = new SoundSystem();
|
||||||
|
|
||||||
|
|
||||||
@@ -317,21 +312,4 @@ public enum FControl {
|
|||||||
public SoundSystem getSoundSystem() {
|
public SoundSystem getSoundSystem() {
|
||||||
return soundSystem;
|
return soundSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutorService getThreadPool() {
|
|
||||||
return threadPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This pool is designed to parallel CPU or IO intensive tasks like parse cards or download images, assuming a load factor of 0.5
|
|
||||||
public final static ExecutorService getComputingPool(float loadFactor) {
|
|
||||||
return Executors.newFixedThreadPool((int)(Runtime.getRuntime().availableProcessors() / (1-loadFactor)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for this method.
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static boolean isMultiCoreSystem() {
|
|
||||||
return Runtime.getRuntime().availableProcessors() > 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/main/java/forge/control/input/InputLockUI.java
Normal file
18
src/main/java/forge/control/input/InputLockUI.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package forge.control.input;
|
||||||
|
|
||||||
|
import forge.gui.match.CMatchUI;
|
||||||
|
import forge.view.ButtonUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Write javadoc for this type.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class InputLockUI extends Input {
|
||||||
|
private static final long serialVersionUID = 5777143577098597374L;
|
||||||
|
|
||||||
|
public void showMessage() {
|
||||||
|
ButtonUtil.disableAll();
|
||||||
|
CMatchUI.SINGLETON_INSTANCE.showMessage("Waiting for actions...");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -18,10 +18,10 @@
|
|||||||
package forge.control.input;
|
package forge.control.input;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
import forge.FThreads;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.control.FControl;
|
import forge.control.FControl;
|
||||||
import forge.game.GameState;
|
|
||||||
import forge.game.phase.PhaseType;
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.gui.GuiDisplayUtil;
|
import forge.gui.GuiDisplayUtil;
|
||||||
@@ -80,11 +80,17 @@ public class InputPassPriority extends Input {
|
|||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void selectCard(final Card card) {
|
public final void selectCard(final Card card) {
|
||||||
Player player = Singletons.getControl().getPlayer();
|
final Player player = Singletons.getControl().getPlayer();
|
||||||
GameState game = Singletons.getModel().getGame();
|
final SpellAbility ab = player.getController().getAbilityToPlay(player.getGame().getAbilitesOfCard(card, player));
|
||||||
SpellAbility ab = player.getController().getAbilityToPlay(game.getAbilitesOfCard(card, player));
|
|
||||||
if ( null != ab) {
|
if ( null != ab) {
|
||||||
player.playSpellAbility(card, ab);
|
Runnable execAbility = new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
player.playSpellAbility(card, ab);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
FThreads.invokeInNewThread(execAbility, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE);
|
SDisplayUtil.remind(VMessage.SINGLETON_INSTANCE);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import forge.CardCharacteristicName;
|
|||||||
import forge.CardColor;
|
import forge.CardColor;
|
||||||
import forge.CardLists;
|
import forge.CardLists;
|
||||||
import forge.CardPredicates;
|
import forge.CardPredicates;
|
||||||
|
import forge.FThreads;
|
||||||
import forge.card.MagicColor;
|
import forge.card.MagicColor;
|
||||||
import forge.card.ability.AbilityUtils;
|
import forge.card.ability.AbilityUtils;
|
||||||
import forge.card.ability.ApiType;
|
import forge.card.ability.ApiType;
|
||||||
@@ -358,6 +359,7 @@ public class GameActionPlay {
|
|||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
* a {@link forge.card.spellability.SpellAbility} object.
|
||||||
*/
|
*/
|
||||||
public final void playSpellAbility(SpellAbility sa, Player activator) {
|
public final void playSpellAbility(SpellAbility sa, Player activator) {
|
||||||
|
FThreads.checkEDT("Player.playSpellAbility", false);
|
||||||
sa.setActivatingPlayer(activator);
|
sa.setActivatingPlayer(activator);
|
||||||
|
|
||||||
final Card source = sa.getSourceCard();
|
final Card source = sa.getSourceCard();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.util.Collections;
|
|||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.esotericsoftware.minlog.Log;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
@@ -44,6 +45,7 @@ import forge.card.spellability.SpellAbility;
|
|||||||
import forge.card.spellability.SpellPermanent;
|
import forge.card.spellability.SpellPermanent;
|
||||||
import forge.game.GameActionUtil;
|
import forge.game.GameActionUtil;
|
||||||
import forge.game.GameState;
|
import forge.game.GameState;
|
||||||
|
import forge.game.phase.PhaseType;
|
||||||
import forge.game.player.AIPlayer;
|
import forge.game.player.AIPlayer;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
@@ -762,5 +764,97 @@ public class AiController {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onPriorityRecieved() {
|
||||||
|
final PhaseType phase = game.getPhaseHandler().getPhase();
|
||||||
|
|
||||||
|
if (game.getStack().size() > 0) {
|
||||||
|
playSpellAbilities(game);
|
||||||
|
} else {
|
||||||
|
switch(phase) {
|
||||||
|
case CLEANUP:
|
||||||
|
if ( game.getPhaseHandler().getPlayerTurn() == player ) {
|
||||||
|
final int size = player.getCardsIn(ZoneType.Hand).size();
|
||||||
|
|
||||||
|
if (!player.isUnlimitedHandSize()) {
|
||||||
|
int max = Math.min(player.getZone(ZoneType.Hand).size(), size - player.getMaxHandSize());
|
||||||
|
final List<Card> toDiscard = player.getAi().getCardsToDiscard(max, (String[])null, null);
|
||||||
|
for (int i = 0; i < toDiscard.size(); i++) {
|
||||||
|
player.discard(toDiscard.get(i), null);
|
||||||
|
}
|
||||||
|
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COMBAT_DECLARE_ATTACKERS:
|
||||||
|
declareAttackers();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MAIN1:
|
||||||
|
case MAIN2:
|
||||||
|
Log.debug("Computer " + phase.toString());
|
||||||
|
playLands();
|
||||||
|
// fall through is intended
|
||||||
|
default:
|
||||||
|
playSpellAbilities(game);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.getController().passPriority();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void declareAttackers() {
|
||||||
|
// 12/2/10(sol) the decision making here has moved to getAttackers()
|
||||||
|
game.setCombat(new AiAttackController(player, player.getOpponent()).getAttackers());
|
||||||
|
|
||||||
|
final List<Card> att = game.getCombat().getAttackers();
|
||||||
|
if (!att.isEmpty()) {
|
||||||
|
game.getPhaseHandler().setCombat(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (final Card element : att) {
|
||||||
|
// tapping of attackers happens after Propaganda is paid for
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("Computer just assigned ").append(element.getName()).append(" as an attacker.");
|
||||||
|
Log.debug(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
player.getZone(ZoneType.Battlefield).updateObservers();
|
||||||
|
|
||||||
|
game.getPhaseHandler().setPlayersPriorityPermission(false);
|
||||||
|
|
||||||
|
// ai is about to attack, cancel all phase skipping
|
||||||
|
for (Player p : game.getPlayers()) {
|
||||||
|
p.getController().autoPassCancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playLands() {
|
||||||
|
final Player player = getPlayer();
|
||||||
|
List<Card> landsWannaPlay = getLandsToPlay();
|
||||||
|
|
||||||
|
while(landsWannaPlay != null && !landsWannaPlay.isEmpty() && player.canPlayLand(null)) {
|
||||||
|
Card land = chooseBestLandToPlay(landsWannaPlay);
|
||||||
|
landsWannaPlay.remove(land);
|
||||||
|
player.playLand(land);
|
||||||
|
game.getPhaseHandler().setPriority(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void playSpellAbilities(final GameState game)
|
||||||
|
{
|
||||||
|
SpellAbility sa;
|
||||||
|
do {
|
||||||
|
sa = getSpellAbilityToPlay();
|
||||||
|
if ( sa == null ) break;
|
||||||
|
//System.out.println("Playing sa: " + sa);
|
||||||
|
if (!ComputerUtil.handlePlayingSpellAbility(player, sa, game)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ( sa != null );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,18 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
package forge.game.ai;
|
package forge.game.ai;
|
||||||
|
|
||||||
import java.util.List;
|
import forge.FThreads;
|
||||||
|
|
||||||
import com.esotericsoftware.minlog.Log;
|
|
||||||
|
|
||||||
import forge.Card;
|
|
||||||
import forge.card.spellability.SpellAbility;
|
|
||||||
import forge.control.input.Input;
|
import forge.control.input.Input;
|
||||||
import forge.game.GameState;
|
|
||||||
import forge.game.phase.PhaseType;
|
|
||||||
import forge.game.player.AIPlayer;
|
|
||||||
import forge.game.player.Player;
|
|
||||||
import forge.game.zone.ZoneType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -43,8 +33,6 @@ public class AiInputCommon extends Input {
|
|||||||
private static final long serialVersionUID = -3091338639571662216L;
|
private static final long serialVersionUID = -3091338639571662216L;
|
||||||
|
|
||||||
private final AiController computer;
|
private final AiController computer;
|
||||||
private final AIPlayer player;
|
|
||||||
private final GameState game;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -56,15 +44,13 @@ public class AiInputCommon extends Input {
|
|||||||
*/
|
*/
|
||||||
public AiInputCommon(final AiController iComputer) {
|
public AiInputCommon(final AiController iComputer) {
|
||||||
this.computer = iComputer;
|
this.computer = iComputer;
|
||||||
player = computer.getPlayer();
|
|
||||||
this.game = computer.getGame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
@Override
|
@Override
|
||||||
public final void showMessage() {
|
public final void showMessage() {
|
||||||
// should not think when the game is over
|
// should not think when the game is over
|
||||||
if (game.isGameOver()) {
|
if (computer.getGame().isGameOver()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,100 +62,19 @@ public class AiInputCommon extends Input {
|
|||||||
* \"Detailed Error Trace\" to the Forge forum.");
|
* \"Detailed Error Trace\" to the Forge forum.");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
final PhaseType phase = game.getPhaseHandler().getPhase();
|
FThreads.invokeInNewThread(aiActions, true);
|
||||||
|
|
||||||
if (game.getStack().size() > 0) {
|
|
||||||
playSpellAbilities(game);
|
|
||||||
} else {
|
|
||||||
switch(phase) {
|
|
||||||
case CLEANUP:
|
|
||||||
if ( game.getPhaseHandler().getPlayerTurn() == player ) {
|
|
||||||
final int size = player.getCardsIn(ZoneType.Hand).size();
|
|
||||||
|
|
||||||
if (!player.isUnlimitedHandSize()) {
|
|
||||||
int max = Math.min(player.getZone(ZoneType.Hand).size(), size - player.getMaxHandSize());
|
|
||||||
final List<Card> toDiscard = player.getAi().getCardsToDiscard(max, (String[])null, null);
|
|
||||||
for (int i = 0; i < toDiscard.size(); i++) {
|
|
||||||
player.discard(toDiscard.get(i), null);
|
|
||||||
}
|
|
||||||
game.getStack().chooseOrderOfSimultaneousStackEntryAll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COMBAT_DECLARE_ATTACKERS:
|
|
||||||
declareAttackers();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MAIN1:
|
|
||||||
case MAIN2:
|
|
||||||
Log.debug("Computer " + phase.toString());
|
|
||||||
playLands();
|
|
||||||
// fall through is intended
|
|
||||||
default:
|
|
||||||
playSpellAbilities(game);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
player.getController().passPriority();
|
|
||||||
} // getMessage();
|
} // getMessage();
|
||||||
|
|
||||||
/**
|
final Runnable aiActions = new Runnable() {
|
||||||
* TODO: Write javadoc for this method.
|
|
||||||
*/
|
|
||||||
private void declareAttackers() {
|
|
||||||
// 12/2/10(sol) the decision making here has moved to getAttackers()
|
|
||||||
game.setCombat(new AiAttackController(player, player.getOpponent()).getAttackers());
|
|
||||||
|
|
||||||
final List<Card> att = game.getCombat().getAttackers();
|
@Override
|
||||||
if (!att.isEmpty()) {
|
public void run() {
|
||||||
game.getPhaseHandler().setCombat(true);
|
computer.onPriorityRecieved();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (final Card element : att) {
|
|
||||||
// tapping of attackers happens after Propaganda is paid for
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
sb.append("Computer just assigned ").append(element.getName()).append(" as an attacker.");
|
|
||||||
Log.debug(sb.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
player.getZone(ZoneType.Battlefield).updateObservers();
|
|
||||||
|
|
||||||
game.getPhaseHandler().setPlayersPriorityPermission(false);
|
|
||||||
|
|
||||||
// ai is about to attack, cancel all phase skipping
|
|
||||||
for (Player p : game.getPlayers()) {
|
|
||||||
p.getController().autoPassCancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Write javadoc for this method.
|
|
||||||
*/
|
|
||||||
private void playLands() {
|
|
||||||
final Player player = computer.getPlayer();
|
|
||||||
List<Card> landsWannaPlay = computer.getLandsToPlay();
|
|
||||||
|
|
||||||
while(landsWannaPlay != null && !landsWannaPlay.isEmpty() && player.canPlayLand(null)) {
|
|
||||||
Card land = computer.chooseBestLandToPlay(landsWannaPlay);
|
|
||||||
landsWannaPlay.remove(land);
|
|
||||||
player.playLand(land);
|
|
||||||
game.getPhaseHandler().setPriority(player);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void playSpellAbilities(final GameState game)
|
|
||||||
{
|
|
||||||
SpellAbility sa;
|
|
||||||
do {
|
|
||||||
sa = computer.getSpellAbilityToPlay();
|
|
||||||
if ( sa == null ) break;
|
|
||||||
//System.out.println("Playing sa: " + sa);
|
|
||||||
if (!ComputerUtil.handlePlayingSpellAbility(player, sa, game)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while ( sa != null );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import forge.CardPredicates.Presets;
|
|||||||
import forge.CardUtil;
|
import forge.CardUtil;
|
||||||
import forge.Constant.Preferences;
|
import forge.Constant.Preferences;
|
||||||
import forge.CounterType;
|
import forge.CounterType;
|
||||||
|
import forge.FThreads;
|
||||||
import forge.GameEntity;
|
import forge.GameEntity;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.card.ability.AbilityFactory;
|
import forge.card.ability.AbilityFactory;
|
||||||
@@ -1623,6 +1624,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
|||||||
* a {@link forge.card.spellability.SpellAbility} object.
|
* a {@link forge.card.spellability.SpellAbility} object.
|
||||||
*/
|
*/
|
||||||
protected final void doDiscard(final Card c, final SpellAbility sa) {
|
protected final void doDiscard(final Card c, final SpellAbility sa) {
|
||||||
|
FThreads.checkEDT("Player.doDiscard", false);
|
||||||
// TODO: This line should be moved inside CostPayment somehow
|
// TODO: This line should be moved inside CostPayment somehow
|
||||||
/*if (sa != null) {
|
/*if (sa != null) {
|
||||||
sa.addCostToHashList(c, "Discarded");
|
sa.addCostToHashList(c, "Discarded");
|
||||||
@@ -1845,6 +1847,7 @@ public abstract class Player extends GameEntity implements Comparable<Player> {
|
|||||||
* a {@link forge.Card} object.
|
* a {@link forge.Card} object.
|
||||||
*/
|
*/
|
||||||
public final void playLand(final Card land) {
|
public final void playLand(final Card land) {
|
||||||
|
FThreads.checkEDT("Player.playSpellAbility", false);
|
||||||
if (this.canPlayLand(land)) {
|
if (this.canPlayLand(land)) {
|
||||||
land.setController(this, 0);
|
land.setController(this, 0);
|
||||||
game.getAction().moveTo(this.getZone(ZoneType.Battlefield), land);
|
game.getAction().moveTo(this.getZone(ZoneType.Battlefield), land);
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import java.util.List;
|
|||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.KeyStroke;
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
import forge.gui.match.VMatchUI;
|
import forge.gui.match.VMatchUI;
|
||||||
@@ -89,26 +88,6 @@ public final class GuiUtils {
|
|||||||
return ttf;
|
return ttf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Checks if calling method uses event dispatch thread.
|
|
||||||
* Exception thrown if method is on "wrong" thread.
|
|
||||||
* A boolean is passed to indicate if the method must be EDT or not.
|
|
||||||
*
|
|
||||||
* @param methodName   String, part of the custom exception message.
|
|
||||||
* @param mustBeEDT   boolean: true = exception if not EDT, false = exception if EDT
|
|
||||||
*/
|
|
||||||
public static void checkEDT(final String methodName, final boolean mustBeEDT) {
|
|
||||||
boolean isEDT = SwingUtilities.isEventDispatchThread();
|
|
||||||
|
|
||||||
if (!isEDT && mustBeEDT) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
methodName + " must be accessed from the event dispatch thread.");
|
|
||||||
}
|
|
||||||
else if (isEDT && !mustBeEDT) {
|
|
||||||
throw new IllegalStateException(
|
|
||||||
methodName + " may not be accessed from the event dispatch thread.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all visually highlighted card panels on the battlefield.
|
* Clear all visually highlighted card panels on the battlefield.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import java.util.Observable;
|
|||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
|
||||||
import forge.Card;
|
import forge.Card;
|
||||||
|
import forge.FThreads;
|
||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.control.input.Input;
|
import forge.control.input.Input;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
@@ -58,7 +59,17 @@ public class InputProxy implements Observer {
|
|||||||
public final synchronized void setInput(final Input in) {
|
public final synchronized void setInput(final Input in) {
|
||||||
valid = true;
|
valid = true;
|
||||||
this.input = in;
|
this.input = in;
|
||||||
this.input.showMessage(); // this call may invalidate the input by the time it returns
|
|
||||||
|
if ( null == input ) {
|
||||||
|
throw new NullPointerException("input is null");
|
||||||
|
}
|
||||||
|
|
||||||
|
FThreads.invokeInEDT(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
InputProxy.this.input.showMessage(); // this call may invalidate the input by the time it returns
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public enum CPicture implements ICDoc {
|
|||||||
*/
|
*/
|
||||||
public void showCard(final Card c) {
|
public void showCard(final Card c) {
|
||||||
canFlip = c != null && (c.isDoubleFaced() || c.isFlipCard());
|
canFlip = c != null && (c.isDoubleFaced() || c.isFlipCard());
|
||||||
this.currentCard = c;
|
currentCard = c;
|
||||||
flipped = canFlip && (c.getCurState() == CardCharacteristicName.Transformed ||
|
flipped = canFlip && (c.getCurState() == CardCharacteristicName.Transformed ||
|
||||||
c.getCurState() == CardCharacteristicName.Flipped);
|
c.getCurState() == CardCharacteristicName.Flipped);
|
||||||
VPicture.SINGLETON_INSTANCE.getLblFlipcard().setVisible(canFlip);
|
VPicture.SINGLETON_INSTANCE.getLblFlipcard().setVisible(canFlip);
|
||||||
@@ -60,13 +60,15 @@ public enum CPicture implements ICDoc {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.currentCard = null;
|
canFlip = false;
|
||||||
|
flipped = false;
|
||||||
|
currentCard = null;
|
||||||
VPicture.SINGLETON_INSTANCE.getLblFlipcard().setVisible(false);
|
VPicture.SINGLETON_INSTANCE.getLblFlipcard().setVisible(false);
|
||||||
VPicture.SINGLETON_INSTANCE.getPnlPicture().setCard(item);
|
VPicture.SINGLETON_INSTANCE.getPnlPicture().setCard(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Card getCurrentCard() {
|
public Card getCurrentCard() {
|
||||||
return this.currentCard;
|
return currentCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -100,7 +102,8 @@ public enum CPicture implements ICDoc {
|
|||||||
} else if (currentCard.isFlipCard()) {
|
} else if (currentCard.isFlipCard()) {
|
||||||
newState = CardCharacteristicName.Flipped;
|
newState = CardCharacteristicName.Flipped;
|
||||||
} else {
|
} else {
|
||||||
// if this is hit, then there is a misalignment between this method and the showCard method above
|
// if this is hit, then then showCard has been modified to handle additional types, but
|
||||||
|
// this function is missing an else if statement above
|
||||||
throw new RuntimeException("unhandled flippable card");
|
throw new RuntimeException("unhandled flippable card");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import java.util.Date;
|
|||||||
import javax.swing.JProgressBar;
|
import javax.swing.JProgressBar;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import forge.gui.GuiUtils;
|
import forge.FThreads;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple progress bar component using the Forge skin.
|
* A simple progress bar component using the Forge skin.
|
||||||
@@ -37,7 +37,7 @@ public class FProgressBar extends JProgressBar {
|
|||||||
* @param s0   A description to prepend before statistics.
|
* @param s0   A description to prepend before statistics.
|
||||||
*/
|
*/
|
||||||
public void setDescription(final String s0) {
|
public void setDescription(final String s0) {
|
||||||
GuiUtils.checkEDT("FProgressBar$setDescription", true);
|
FThreads.checkEDT("FProgressBar$setDescription", true);
|
||||||
this.desc = s0;
|
this.desc = s0;
|
||||||
this.setString(s0);
|
this.setString(s0);
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ public class FProgressBar extends JProgressBar {
|
|||||||
|
|
||||||
/** Resets the various values required for this class. Must be called from EDT. */
|
/** Resets the various values required for this class. Must be called from EDT. */
|
||||||
public void reset() {
|
public void reset() {
|
||||||
GuiUtils.checkEDT("FProgressBar$reset", true);
|
FThreads.checkEDT("FProgressBar$reset", true);
|
||||||
this.setIndeterminate(true);
|
this.setIndeterminate(true);
|
||||||
this.setValue(0);
|
this.setValue(0);
|
||||||
this.tempVal = 0;
|
this.tempVal = 0;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import javax.swing.SwingUtilities;
|
|||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.LineBorder;
|
import javax.swing.border.LineBorder;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
import forge.gui.GuiUtils;
|
import forge.gui.GuiUtils;
|
||||||
import forge.view.FView;
|
import forge.view.FView;
|
||||||
|
|
||||||
@@ -419,7 +420,7 @@ public enum FSkin {
|
|||||||
*/
|
*/
|
||||||
public static void loadLight(final String skinName) {
|
public static void loadLight(final String skinName) {
|
||||||
// No need for this method to be loaded while on the EDT.
|
// No need for this method to be loaded while on the EDT.
|
||||||
GuiUtils.checkEDT("FSkin$constructor", false);
|
FThreads.checkEDT("FSkin$constructor", false);
|
||||||
|
|
||||||
// Non-default (preferred) skin name and dir.
|
// Non-default (preferred) skin name and dir.
|
||||||
FSkin.preferredName = skinName.toLowerCase().replace(' ', '_');
|
FSkin.preferredName = skinName.toLowerCase().replace(' ', '_');
|
||||||
@@ -479,7 +480,7 @@ public enum FSkin {
|
|||||||
*/
|
*/
|
||||||
public static void loadFull() {
|
public static void loadFull() {
|
||||||
// No need for this method to be loaded while on the EDT.
|
// No need for this method to be loaded while on the EDT.
|
||||||
GuiUtils.checkEDT("FSkin$load", false);
|
FThreads.checkEDT("FSkin$load", false);
|
||||||
|
|
||||||
// Preferred skin name must be called via loadLight() method,
|
// Preferred skin name must be called via loadLight() method,
|
||||||
// which does some cleanup and init work.
|
// which does some cleanup and init work.
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import forge.Constant;
|
import forge.Constant;
|
||||||
import forge.Constant.Preferences;
|
import forge.Constant.Preferences;
|
||||||
|
import forge.FThreads;
|
||||||
import forge.card.BoosterData;
|
import forge.card.BoosterData;
|
||||||
import forge.card.CardBlock;
|
import forge.card.CardBlock;
|
||||||
import forge.card.CardRulesReader;
|
import forge.card.CardRulesReader;
|
||||||
@@ -43,7 +44,6 @@ import forge.game.MatchController;
|
|||||||
import forge.game.limited.GauntletMini;
|
import forge.game.limited.GauntletMini;
|
||||||
import forge.game.player.LobbyPlayer;
|
import forge.game.player.LobbyPlayer;
|
||||||
import forge.gauntlet.GauntletData;
|
import forge.gauntlet.GauntletData;
|
||||||
import forge.gui.GuiUtils;
|
|
||||||
import forge.item.CardDb;
|
import forge.item.CardDb;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
@@ -161,7 +161,7 @@ public enum FModel {
|
|||||||
this.loadDynamicGamedata();
|
this.loadDynamicGamedata();
|
||||||
|
|
||||||
// Loads all cards (using progress bar).
|
// Loads all cards (using progress bar).
|
||||||
GuiUtils.checkEDT("CardFactory$constructor", false);
|
FThreads.checkEDT("CardFactory$constructor", false);
|
||||||
final CardStorageReader reader = new CardStorageReader(NewConstants.CARD_DATA_DIR, true);
|
final CardStorageReader reader = new CardStorageReader(NewConstants.CARD_DATA_DIR, true);
|
||||||
try {
|
try {
|
||||||
// this fills in our map of card names to Card instances.
|
// this fills in our map of card names to Card instances.
|
||||||
|
|||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
* The files in the directory "net/slightlymagic/braids" and in all subdirectories of it (the "Files") are
|
|
||||||
* Copyright 2011 Braids Cabal-Conjurer. They are available under either Forge's
|
|
||||||
* main license (the GNU Public License; see LICENSE.txt in Forge's top directory)
|
|
||||||
* or under the Apache License, as explained below.
|
|
||||||
*
|
|
||||||
* The Files are additionally licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "Apache License"); you may not use the files in this directory except in
|
|
||||||
* compliance with one of its two licenses. You may obtain a copy of the Apache
|
|
||||||
* License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the Apache License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the Apache License for the specific language governing permissions and
|
|
||||||
* limitations under the Apache License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package forge.util;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some general-purpose functions.
|
|
||||||
*/
|
|
||||||
public final class ThreadUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke the given Runnable in an Event Dispatch Thread and wait for it to
|
|
||||||
* finish; but <B>try to use SwingUtilities.invokeLater instead whenever
|
|
||||||
* feasible.</B>
|
|
||||||
*
|
|
||||||
* Exceptions generated by SwingUtilities.invokeAndWait (if used), are
|
|
||||||
* rethrown as RuntimeExceptions.
|
|
||||||
*
|
|
||||||
* @param proc
|
|
||||||
* the Runnable to run
|
|
||||||
* @see javax.swing.SwingUtilities#invokeLater(Runnable)
|
|
||||||
*/
|
|
||||||
public static void invokeInEventDispatchThreadAndWait(final Runnable proc) {
|
|
||||||
// by
|
|
||||||
// Braids
|
|
||||||
// on
|
|
||||||
// 8/18/11
|
|
||||||
// 11:19
|
|
||||||
// PM
|
|
||||||
if (SwingUtilities.isEventDispatchThread()) {
|
|
||||||
// Just run in the current thread.
|
|
||||||
proc.run();
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
SwingUtilities.invokeAndWait(proc);
|
|
||||||
} catch (final InterruptedException exn) {
|
|
||||||
throw new RuntimeException(exn);
|
|
||||||
// 11:19 PM
|
|
||||||
} catch (final InvocationTargetException exn) {
|
|
||||||
throw new RuntimeException(exn);
|
|
||||||
// 11:19 PM
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user