mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Thread-related routines moved from FControl to FThreads
This commit is contained in:
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -13699,6 +13699,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/Constant.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/GameLog.java -text
|
||||
src/main/java/forge/ImageCache.java svneol=native#text/plain
|
||||
@@ -14083,6 +14084,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/InputCleanup.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/InputPassPriority.java svneol=native#text/plain
|
||||
src/main/java/forge/control/input/InputPayDiscardCost.java -text
|
||||
|
||||
109
src/main/java/forge/FThreads.java
Normal file
109
src/main/java/forge/FThreads.java
Normal file
@@ -0,0 +1,109 @@
|
||||
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 {
|
||||
|
||||
static {
|
||||
System.out.printf("(FThreads static ctor): Running on a machine with %d cpu core(s)%n", Runtime.getRuntime().availableProcessors() );
|
||||
}
|
||||
|
||||
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(final Runnable proc, boolean lockUI) {
|
||||
Runnable toRun = proc;
|
||||
if( lockUI ) {
|
||||
// checkEDT("FThreads.invokeInNewthread", true)
|
||||
Singletons.getModel().getMatch().getInput().setInput(inpuptLock);
|
||||
toRun = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
proc.run();
|
||||
// may try special unlock method here
|
||||
Singletons.getModel().getMatch().getInput().resetInput();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getCachedPool().execute(toRun);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,9 +39,9 @@ import javax.swing.SwingUtilities;
|
||||
|
||||
import org.apache.commons.lang.time.StopWatch;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.card.CardRules;
|
||||
import forge.card.CardRulesReader;
|
||||
import forge.control.FControl;
|
||||
import forge.error.BugReporter;
|
||||
import forge.gui.toolbox.FProgressBar;
|
||||
import forge.util.FileUtil;
|
||||
@@ -62,7 +62,7 @@ public class CardStorageReader {
|
||||
/** Default charset when loading from files. */
|
||||
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 CountDownLatch cdl = new CountDownLatch(NUMBER_OF_PARTS);
|
||||
@@ -209,7 +209,7 @@ public class CardStorageReader {
|
||||
|
||||
try {
|
||||
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);
|
||||
executor.shutdown();
|
||||
cdl.await();
|
||||
|
||||
@@ -25,9 +25,6 @@ import java.awt.event.WindowEvent;
|
||||
import java.awt.event.WindowListener;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
@@ -85,14 +82,8 @@ public enum FControl {
|
||||
DRAFTING_PROCESS
|
||||
}
|
||||
|
||||
private final ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||
|
||||
private final SoundSystem soundSystem = new SoundSystem();
|
||||
|
||||
|
||||
static {
|
||||
System.out.printf("(FControl static ctor): Running on a machine with %d cpu core(s)%n", Runtime.getRuntime().availableProcessors() );
|
||||
}
|
||||
/**
|
||||
* <p>
|
||||
* FControl.
|
||||
@@ -317,21 +308,4 @@ public enum FControl {
|
||||
public SoundSystem getSoundSystem() {
|
||||
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...");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,7 +31,6 @@ import java.util.List;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.Card;
|
||||
import forge.gui.match.VMatchUI;
|
||||
@@ -89,26 +88,6 @@ public final class GuiUtils {
|
||||
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.
|
||||
*/
|
||||
|
||||
@@ -5,7 +5,7 @@ import java.util.Date;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.FThreads;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
public void setDescription(final String s0) {
|
||||
GuiUtils.checkEDT("FProgressBar$setDescription", true);
|
||||
FThreads.checkEDT("FProgressBar$setDescription", true);
|
||||
this.desc = 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. */
|
||||
public void reset() {
|
||||
GuiUtils.checkEDT("FProgressBar$reset", true);
|
||||
FThreads.checkEDT("FProgressBar$reset", true);
|
||||
this.setIndeterminate(true);
|
||||
this.setValue(0);
|
||||
this.tempVal = 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.LineBorder;
|
||||
|
||||
import forge.FThreads;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.view.FView;
|
||||
|
||||
@@ -419,7 +420,7 @@ public enum FSkin {
|
||||
*/
|
||||
public static void loadLight(final String skinName) {
|
||||
// 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.
|
||||
FSkin.preferredName = skinName.toLowerCase().replace(' ', '_');
|
||||
@@ -479,7 +480,7 @@ public enum FSkin {
|
||||
*/
|
||||
public static void loadFull() {
|
||||
// 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,
|
||||
// which does some cleanup and init work.
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.List;
|
||||
|
||||
import forge.Constant;
|
||||
import forge.Constant.Preferences;
|
||||
import forge.FThreads;
|
||||
import forge.card.BoosterData;
|
||||
import forge.card.CardBlock;
|
||||
import forge.card.CardRulesReader;
|
||||
@@ -43,7 +44,6 @@ import forge.game.MatchController;
|
||||
import forge.game.limited.GauntletMini;
|
||||
import forge.game.player.LobbyPlayer;
|
||||
import forge.gauntlet.GauntletData;
|
||||
import forge.gui.GuiUtils;
|
||||
import forge.item.CardDb;
|
||||
import forge.properties.ForgePreferences;
|
||||
import forge.properties.ForgePreferences.FPref;
|
||||
@@ -161,7 +161,7 @@ public enum FModel {
|
||||
this.loadDynamicGamedata();
|
||||
|
||||
// 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);
|
||||
try {
|
||||
// this fills in our map of card names to Card instances.
|
||||
|
||||
Reference in New Issue
Block a user