diff --git a/.gitattributes b/.gitattributes
index a85179bec6a..6d781277a61 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -19,8 +19,7 @@ forge-core/.settings/org.eclipse.core.resources.prefs -text
forge-core/.settings/org.eclipse.jdt.core.prefs -text
forge-core/.settings/org.eclipse.m2e.core.prefs -text
forge-core/pom.xml -text
-forge-core/src/main/java/forge/ICardStorageReader.java -text
-forge-core/src/main/java/forge/IProgressObserver.java -text
+forge-core/src/main/java/forge/CardStorageReader.java -text
forge-core/src/main/java/forge/StaticData.java -text
forge-core/src/main/java/forge/card/BoosterGenerator.java svneol=native#text/plain
forge-core/src/main/java/forge/card/BoosterSlots.java -text
@@ -98,6 +97,7 @@ forge-core/src/main/java/forge/util/Lang.java -text
forge-core/src/main/java/forge/util/MyRandom.java svneol=native#text/plain
forge-core/src/main/java/forge/util/PredicateString.java -text
forge-core/src/main/java/forge/util/TextUtil.java -text
+forge-core/src/main/java/forge/util/ThreadUtil.java -text
forge-core/src/main/java/forge/util/package-info.java -text
forge-core/src/main/java/forge/util/storage/IStorage.java -text
forge-core/src/main/java/forge/util/storage/StorageBase.java -text
@@ -14944,7 +14944,6 @@ forge-gui/src/main/java/forge/card/ability/package-info.java svneol=native#text/
forge-gui/src/main/java/forge/card/cardfactory/CardFactory.java svneol=native#text/plain
forge-gui/src/main/java/forge/card/cardfactory/CardFactoryCreatures.java svneol=native#text/plain
forge-gui/src/main/java/forge/card/cardfactory/CardFactoryUtil.java svneol=native#text/plain
-forge-gui/src/main/java/forge/card/cardfactory/CardStorageReader.java svneol=native#text/plain
forge-gui/src/main/java/forge/card/cardfactory/package-info.java svneol=native#text/plain
forge-gui/src/main/java/forge/card/cost/Cost.java svneol=native#text/plain
forge-gui/src/main/java/forge/card/cost/CostAddMana.java -text
diff --git a/forge-gui/src/main/java/forge/card/cardfactory/CardStorageReader.java b/forge-core/src/main/java/forge/CardStorageReader.java
similarity index 88%
rename from forge-gui/src/main/java/forge/card/cardfactory/CardStorageReader.java
rename to forge-core/src/main/java/forge/CardStorageReader.java
index 74c548fac0a..c9f454edcca 100644
--- a/forge-gui/src/main/java/forge/card/cardfactory/CardStorageReader.java
+++ b/forge-core/src/main/java/forge/CardStorageReader.java
@@ -1,344 +1,356 @@
-/*
- * Forge: Play Magic: the Gathering.
- * Copyright (C) 2011 Forge Team
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see .
- */
-package forge.card.cardfactory;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-import org.apache.commons.lang3.time.StopWatch;
-
-import forge.FThreads;
-import forge.ICardStorageReader;
-import forge.IProgressObserver;
-import forge.card.CardRules;
-import forge.util.FileUtil;
-
-/**
- *
- * CardReader class.
- *
- *
- * @author Forge
- * @version $Id$
- */
-
-public class CardStorageReader implements ICardStorageReader {
-
- private static final String CARD_FILE_DOT_EXTENSION = ".txt";
-
- /** Default charset when loading from files. */
- public static final String DEFAULT_CHARSET_NAME = "US-ASCII";
-
- private final boolean useThreadPool = FThreads.isMultiCoreSystem();
- public final static int NUMBER_OF_PARTS = 25;
-
- private final CountDownLatch cdl = new CountDownLatch(NUMBER_OF_PARTS);
- private final IProgressObserver progressObserver;
-
- private transient File cardsfolder;
-
- private transient ZipFile zip;
- private final transient Charset charset;
-
- private final Observer observer;
-
-
- // 8/18/11 10:56 PM
-
-
- /**
- *
- * Constructor for CardReader.
- *
- *
- * @param theCardsFolder
- * indicates location of the cardsFolder
- * @param useZip
- * if true, attempts to load cards from a zip file, if one
- * exists.
- */
- public CardStorageReader(String cardDataDir, final boolean useZip, IProgressObserver progressObserver, ICardStorageReader.Observer observer) {
- this.progressObserver = progressObserver != null ? progressObserver : IProgressObserver.emptyObserver;
- this.cardsfolder = new File(cardDataDir);
- this.observer = observer;
-
- // These read data for lightweight classes.
- if (!cardsfolder.exists()) {
- throw new RuntimeException("CardReader : constructor error -- " + cardsfolder.getAbsolutePath() + " file/folder not found.");
- }
-
- if (!cardsfolder.isDirectory()) {
- throw new RuntimeException("CardReader : constructor error -- not a directory -- " + cardsfolder.getAbsolutePath());
- }
-
- final File zipFile = new File(cardsfolder, "cardsfolder.zip");
-
- if (useZip && zipFile.exists()) {
- try {
- this.zip = new ZipFile(zipFile);
- } catch (final Exception exn) {
- System.err.printf("Error reading zip file \"%s\": %s. Defaulting to txt files in \"%s\".%n", zipFile.getAbsolutePath(), exn, cardsfolder.getAbsolutePath());
- }
- }
-
- this.charset = Charset.forName(CardStorageReader.DEFAULT_CHARSET_NAME);
-
- } // CardReader()
-
- private final List loadCardsInRange(final List files, int from, int to) {
- CardRules.Reader rulesReader = new CardRules.Reader();
-
- List result = new ArrayList();
- for(int i = from; i < to; i++) {
- File cardTxtFile = files.get(i);
- result.add(this.loadCard(rulesReader, cardTxtFile));
- }
- return result;
- }
-
- private final List loadCardsInRangeFromZip(final List files, int from, int to) {
- CardRules.Reader rulesReader = new CardRules.Reader();
-
- List result = new ArrayList();
- for(int i = from; i < to; i++) {
- ZipEntry ze = files.get(i);
- // if (ze.getName().endsWith(CardStorageReader.CARD_FILE_DOT_EXTENSION)) // already filtered!
- result.add(this.loadCard(rulesReader, ze));
- }
- return result;
- }
-
- /**
- * Starts reading cards into memory until the given card is found.
- *
- * After that, we save our place in the list of cards (on disk) in case we
- * need to load more.
- *
- * @return the Card or null if it was not found.
- */
- public final List loadCards() {
- progressObserver.setOperationName("Loading card data", true);
- progressObserver.report(0, NUMBER_OF_PARTS);
-
- final List>> tasks;
- long estimatedFilesRemaining;
-
- // Iterate through txt files or zip archive.
- // Report relevant numbers to progress monitor model.
- if (this.zip == null) {
- final List allFiles = collectCardFiles(new ArrayList(), this.cardsfolder);
- estimatedFilesRemaining = allFiles.size();
- tasks = makeTaskListForFiles(allFiles);
- } else {
- estimatedFilesRemaining = this.zip.size();
- ZipEntry entry;
- List entries = new ArrayList();
- // zipEnum was initialized in the constructor.
- Enumeration extends ZipEntry> zipEnum = this.zip.entries();
- while (zipEnum.hasMoreElements()) {
- entry = zipEnum.nextElement();
- if (entry.isDirectory() || !entry.getName().endsWith(CardStorageReader.CARD_FILE_DOT_EXTENSION))
- continue;
- entries.add(entry);
- }
-
- tasks = makeTaskListForZip(entries);
- } // endif
-
- StopWatch sw = new StopWatch();
- sw.start();
-
- List res = executeLoadTask(tasks);
-
- sw.stop();
- final long timeOnParse = sw.getTime();
- System.out.printf("Read cards: %s %s in %d ms (%d parts) %s%n", estimatedFilesRemaining, zip == null? "files" : "archived files", timeOnParse, NUMBER_OF_PARTS, useThreadPool ? "using thread pool" : "in same thread");
-// if ( null != barProgress )
-// barProgress.setPercentMode(false);
- return res;
- } // loadCardsUntilYouFind(String)
-
- private List executeLoadTask(final List>> tasks) {
- List result = new ArrayList();
-
- try {
- if ( useThreadPool ) {
- final ExecutorService executor = FThreads.getComputingPool(0.5f);
- final List>> parts = executor.invokeAll(tasks);
- executor.shutdown();
- cdl.await();
- for(Future> pp : parts) {
- result.addAll(pp.get());
- }
- } else {
- for(Callable> c : tasks) {
- result.addAll(c.call());
- }
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- } catch (ExecutionException e) {
- e.printStackTrace();
- } catch (Exception e) { // this clause comes from non-threaded branch
- throw new RuntimeException(e);
- }
-
- return result;
- }
-
- private List>> makeTaskListForZip(final List entries) {
- int totalFiles = entries.size();
- int filesPerPart = totalFiles / NUMBER_OF_PARTS;
- final List>> tasks = new ArrayList>>();
- for (int iPart = 0; iPart < NUMBER_OF_PARTS; iPart++) {
- final int from = iPart * filesPerPart;
- final int till = iPart == NUMBER_OF_PARTS - 1 ? totalFiles : from + filesPerPart;
- tasks.add(new Callable>() {
- @Override
- public List call() throws Exception{
- List res = loadCardsInRangeFromZip(entries, from, till);
- cdl.countDown();
- progressObserver.report(NUMBER_OF_PARTS - (int)cdl.getCount(), NUMBER_OF_PARTS);
- return res;
- }
- });
- }
- return tasks;
- }
-
- private List>> makeTaskListForFiles(final List allFiles) {
- int totalFiles = allFiles.size();
- int filesPerPart = totalFiles / NUMBER_OF_PARTS;
- final List>> tasks = new ArrayList>>();
- for (int iPart = 0; iPart < NUMBER_OF_PARTS; iPart++) {
- final int from = iPart * filesPerPart;
- final int till = iPart == NUMBER_OF_PARTS - 1 ? totalFiles : from + filesPerPart;
- tasks.add(new Callable>() {
- @Override
- public List call() throws Exception{
- List res = loadCardsInRange(allFiles, from, till);
- cdl.countDown();
- progressObserver.report(NUMBER_OF_PARTS - (int)cdl.getCount(), NUMBER_OF_PARTS);
- return res;
- }
- });
- }
- return tasks;
- }
-
- public static List collectCardFiles(List accumulator, File startDir) {
- String[] list = startDir.list();
- for (String filename : list) {
- File entry = new File(startDir, filename);
-
- if (!entry.isDirectory()) {
- if (entry.getName().endsWith(CardStorageReader.CARD_FILE_DOT_EXTENSION))
- accumulator.add(entry);
- continue;
- }
- if (filename.startsWith(".")) {
- continue;
- }
-
- collectCardFiles(accumulator, entry);
- }
- return accumulator;
- }
-
-
- private List readScript(final InputStream inputStream) {
- return FileUtil.readAllLines(new InputStreamReader(inputStream, this.charset), true);
- }
-
- /**
- * Load a card from a txt file.
- *
- * @param pathToTxtFile
- * the full or relative path to the file to load
- *
- * @return a new Card instance
- */
- protected final CardRules loadCard(final CardRules.Reader reader, final File file) {
- FileInputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream(file);
- reader.reset();
- List lines = readScript(fileInputStream);
- CardRules rules = reader.readCard(lines);
- if ( null != observer )
- observer.cardLoaded(rules, lines, file);
- return rules;
- } catch (final FileNotFoundException ex) {
- throw new RuntimeException("CardReader : run error -- file not found: " + file.getPath(), ex);
- } finally {
- try {
- fileInputStream.close();
- } catch (final IOException ignored) {
- // 11:08
- // PM
- }
- }
- }
-
- /**
- * Load a card from an entry in a zip file.
- *
- * @param entry
- * to load from
- *
- * @return a new Card instance
- */
- protected final CardRules loadCard(final CardRules.Reader rulesReader, final ZipEntry entry) {
- InputStream zipInputStream = null;
- try {
- zipInputStream = this.zip.getInputStream(entry);
- rulesReader.reset();
- CardRules rules = rulesReader.readCard(readScript(zipInputStream));
-
- return rules;
- } catch (final IOException exn) {
- throw new RuntimeException(exn);
- // PM
- } finally {
- try {
- if (zipInputStream != null) {
- zipInputStream.close();
- }
- } catch (final IOException ignored) {
- // 11:08
- // PM
- }
- }
- }
-
-}
+/*
+ * Forge: Play Magic: the Gathering.
+ * Copyright (C) 2011 Forge Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package forge;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import org.apache.commons.lang3.time.StopWatch;
+
+import forge.card.CardRules;
+import forge.util.FileUtil;
+import forge.util.ThreadUtil;
+
+/**
+ *
+ * CardReader class.
+ *
+ *
+ * @author Forge
+ * @version $Id: CardStorageReader.java 23742 2013-11-22 16:32:56Z Max mtg $
+ */
+
+public class CardStorageReader {
+ public interface Observer {
+ public void cardLoaded(CardRules rules, List lines, File fileOnDisk);
+ }
+
+ public interface ProgressObserver{
+ void setOperationName(String name, boolean usePercents);
+ void report(int current, int total);
+
+ // does nothing, used when they pass null instead of an instance
+ public final static ProgressObserver emptyObserver = new ProgressObserver() {
+ @Override public void setOperationName(String name, boolean usePercents) {}
+ @Override public void report(int current, int total) {}
+ };
+ }
+
+ private static final String CARD_FILE_DOT_EXTENSION = ".txt";
+
+ /** Default charset when loading from files. */
+ public static final String DEFAULT_CHARSET_NAME = "US-ASCII";
+
+ private final boolean useThreadPool = ThreadUtil.isMultiCoreSystem();
+ public final static int NUMBER_OF_PARTS = 25;
+
+ private final CountDownLatch cdl = new CountDownLatch(NUMBER_OF_PARTS);
+ private final ProgressObserver progressObserver;
+
+ private transient File cardsfolder;
+
+ private transient ZipFile zip;
+ private final transient Charset charset;
+
+ private final Observer observer;
+
+
+ // 8/18/11 10:56 PM
+
+
+ /**
+ *
+ * Constructor for CardReader.
+ *
+ *
+ * @param theCardsFolder
+ * indicates location of the cardsFolder
+ * @param useZip
+ * if true, attempts to load cards from a zip file, if one
+ * exists.
+ */
+ public CardStorageReader(String cardDataDir, final boolean useZip, CardStorageReader.ProgressObserver progressObserver, Observer observer) {
+ this.progressObserver = progressObserver != null ? progressObserver : CardStorageReader.ProgressObserver.emptyObserver;
+ this.cardsfolder = new File(cardDataDir);
+ this.observer = observer;
+
+ // These read data for lightweight classes.
+ if (!cardsfolder.exists()) {
+ throw new RuntimeException("CardReader : constructor error -- " + cardsfolder.getAbsolutePath() + " file/folder not found.");
+ }
+
+ if (!cardsfolder.isDirectory()) {
+ throw new RuntimeException("CardReader : constructor error -- not a directory -- " + cardsfolder.getAbsolutePath());
+ }
+
+ final File zipFile = new File(cardsfolder, "cardsfolder.zip");
+
+ if (useZip && zipFile.exists()) {
+ try {
+ this.zip = new ZipFile(zipFile);
+ } catch (final Exception exn) {
+ System.err.printf("Error reading zip file \"%s\": %s. Defaulting to txt files in \"%s\".%n", zipFile.getAbsolutePath(), exn, cardsfolder.getAbsolutePath());
+ }
+ }
+
+ this.charset = Charset.forName(CardStorageReader.DEFAULT_CHARSET_NAME);
+
+ } // CardReader()
+
+ private final List loadCardsInRange(final List files, int from, int to) {
+ CardRules.Reader rulesReader = new CardRules.Reader();
+
+ List result = new ArrayList();
+ for(int i = from; i < to; i++) {
+ File cardTxtFile = files.get(i);
+ result.add(this.loadCard(rulesReader, cardTxtFile));
+ }
+ return result;
+ }
+
+ private final List loadCardsInRangeFromZip(final List files, int from, int to) {
+ CardRules.Reader rulesReader = new CardRules.Reader();
+
+ List result = new ArrayList();
+ for(int i = from; i < to; i++) {
+ ZipEntry ze = files.get(i);
+ // if (ze.getName().endsWith(CardStorageReader.CARD_FILE_DOT_EXTENSION)) // already filtered!
+ result.add(this.loadCard(rulesReader, ze));
+ }
+ return result;
+ }
+
+ /**
+ * Starts reading cards into memory until the given card is found.
+ *
+ * After that, we save our place in the list of cards (on disk) in case we
+ * need to load more.
+ *
+ * @return the Card or null if it was not found.
+ */
+ public final List loadCards() {
+ progressObserver.setOperationName("Loading card data", true);
+ progressObserver.report(0, NUMBER_OF_PARTS);
+
+ final List>> tasks;
+ long estimatedFilesRemaining;
+
+ // Iterate through txt files or zip archive.
+ // Report relevant numbers to progress monitor model.
+ if (this.zip == null) {
+ final List allFiles = collectCardFiles(new ArrayList(), this.cardsfolder);
+ estimatedFilesRemaining = allFiles.size();
+ tasks = makeTaskListForFiles(allFiles);
+ } else {
+ estimatedFilesRemaining = this.zip.size();
+ ZipEntry entry;
+ List entries = new ArrayList();
+ // zipEnum was initialized in the constructor.
+ Enumeration extends ZipEntry> zipEnum = this.zip.entries();
+ while (zipEnum.hasMoreElements()) {
+ entry = zipEnum.nextElement();
+ if (entry.isDirectory() || !entry.getName().endsWith(CardStorageReader.CARD_FILE_DOT_EXTENSION))
+ continue;
+ entries.add(entry);
+ }
+
+ tasks = makeTaskListForZip(entries);
+ } // endif
+
+ StopWatch sw = new StopWatch();
+ sw.start();
+
+ List res = executeLoadTask(tasks);
+
+ sw.stop();
+ final long timeOnParse = sw.getTime();
+ System.out.printf("Read cards: %s %s in %d ms (%d parts) %s%n", estimatedFilesRemaining, zip == null? "files" : "archived files", timeOnParse, NUMBER_OF_PARTS, useThreadPool ? "using thread pool" : "in same thread");
+// if ( null != barProgress )
+// barProgress.setPercentMode(false);
+ return res;
+ } // loadCardsUntilYouFind(String)
+
+ private List executeLoadTask(final List>> tasks) {
+ List result = new ArrayList();
+
+ try {
+ if ( useThreadPool ) {
+ final ExecutorService executor = ThreadUtil.getComputingPool(0.5f);
+ final List>> parts = executor.invokeAll(tasks);
+ executor.shutdown();
+ cdl.await();
+ for(Future> pp : parts) {
+ result.addAll(pp.get());
+ }
+ } else {
+ for(Callable> c : tasks) {
+ result.addAll(c.call());
+ }
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (Exception e) { // this clause comes from non-threaded branch
+ throw new RuntimeException(e);
+ }
+
+ return result;
+ }
+
+ private List>> makeTaskListForZip(final List entries) {
+ int totalFiles = entries.size();
+ int filesPerPart = totalFiles / NUMBER_OF_PARTS;
+ final List>> tasks = new ArrayList>>();
+ for (int iPart = 0; iPart < NUMBER_OF_PARTS; iPart++) {
+ final int from = iPart * filesPerPart;
+ final int till = iPart == NUMBER_OF_PARTS - 1 ? totalFiles : from + filesPerPart;
+ tasks.add(new Callable>() {
+ @Override
+ public List call() throws Exception{
+ List res = loadCardsInRangeFromZip(entries, from, till);
+ cdl.countDown();
+ progressObserver.report(NUMBER_OF_PARTS - (int)cdl.getCount(), NUMBER_OF_PARTS);
+ return res;
+ }
+ });
+ }
+ return tasks;
+ }
+
+ private List>> makeTaskListForFiles(final List allFiles) {
+ int totalFiles = allFiles.size();
+ int filesPerPart = totalFiles / NUMBER_OF_PARTS;
+ final List>> tasks = new ArrayList>>();
+ for (int iPart = 0; iPart < NUMBER_OF_PARTS; iPart++) {
+ final int from = iPart * filesPerPart;
+ final int till = iPart == NUMBER_OF_PARTS - 1 ? totalFiles : from + filesPerPart;
+ tasks.add(new Callable>() {
+ @Override
+ public List call() throws Exception{
+ List res = loadCardsInRange(allFiles, from, till);
+ cdl.countDown();
+ progressObserver.report(NUMBER_OF_PARTS - (int)cdl.getCount(), NUMBER_OF_PARTS);
+ return res;
+ }
+ });
+ }
+ return tasks;
+ }
+
+ public static List collectCardFiles(List accumulator, File startDir) {
+ String[] list = startDir.list();
+ for (String filename : list) {
+ File entry = new File(startDir, filename);
+
+ if (!entry.isDirectory()) {
+ if (entry.getName().endsWith(CardStorageReader.CARD_FILE_DOT_EXTENSION))
+ accumulator.add(entry);
+ continue;
+ }
+ if (filename.startsWith(".")) {
+ continue;
+ }
+
+ collectCardFiles(accumulator, entry);
+ }
+ return accumulator;
+ }
+
+
+ private List readScript(final InputStream inputStream) {
+ return FileUtil.readAllLines(new InputStreamReader(inputStream, this.charset), true);
+ }
+
+ /**
+ * Load a card from a txt file.
+ *
+ * @param pathToTxtFile
+ * the full or relative path to the file to load
+ *
+ * @return a new Card instance
+ */
+ protected final CardRules loadCard(final CardRules.Reader reader, final File file) {
+ FileInputStream fileInputStream = null;
+ try {
+ fileInputStream = new FileInputStream(file);
+ reader.reset();
+ List lines = readScript(fileInputStream);
+ CardRules rules = reader.readCard(lines);
+ if ( null != observer )
+ observer.cardLoaded(rules, lines, file);
+ return rules;
+ } catch (final FileNotFoundException ex) {
+ throw new RuntimeException("CardReader : run error -- file not found: " + file.getPath(), ex);
+ } finally {
+ try {
+ fileInputStream.close();
+ } catch (final IOException ignored) {
+ // 11:08
+ // PM
+ }
+ }
+ }
+
+ /**
+ * Load a card from an entry in a zip file.
+ *
+ * @param entry
+ * to load from
+ *
+ * @return a new Card instance
+ */
+ protected final CardRules loadCard(final CardRules.Reader rulesReader, final ZipEntry entry) {
+ InputStream zipInputStream = null;
+ try {
+ zipInputStream = this.zip.getInputStream(entry);
+ rulesReader.reset();
+ CardRules rules = rulesReader.readCard(readScript(zipInputStream));
+
+ return rules;
+ } catch (final IOException exn) {
+ throw new RuntimeException(exn);
+ // PM
+ } finally {
+ try {
+ if (zipInputStream != null) {
+ zipInputStream.close();
+ }
+ } catch (final IOException ignored) {
+ // 11:08
+ // PM
+ }
+ }
+ }
+
+}
diff --git a/forge-core/src/main/java/forge/ICardStorageReader.java b/forge-core/src/main/java/forge/ICardStorageReader.java
deleted file mode 100644
index c705faf5506..00000000000
--- a/forge-core/src/main/java/forge/ICardStorageReader.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package forge;
-
-import java.io.File;
-import java.util.List;
-
-import forge.card.CardRules;
-
-public interface ICardStorageReader {
- List loadCards();
-
- public interface Observer {
- public void cardLoaded(CardRules rules, List lines, File fileOnDisk);
- }
-}
\ No newline at end of file
diff --git a/forge-core/src/main/java/forge/IProgressObserver.java b/forge-core/src/main/java/forge/IProgressObserver.java
deleted file mode 100644
index 4318e216ce9..00000000000
--- a/forge-core/src/main/java/forge/IProgressObserver.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package forge;
-
-public interface IProgressObserver{
- void setOperationName(String name, boolean usePercents);
- void report(int current, int total);
-
- // does nothing, used when they pass null instead of an instance
- public final static IProgressObserver emptyObserver = new IProgressObserver() {
- @Override public void setOperationName(String name, boolean usePercents) {}
- @Override public void report(int current, int total) {}
- };
-}
\ No newline at end of file
diff --git a/forge-core/src/main/java/forge/StaticData.java b/forge-core/src/main/java/forge/StaticData.java
index f30af6b4f6b..ecebe56244a 100644
--- a/forge-core/src/main/java/forge/StaticData.java
+++ b/forge-core/src/main/java/forge/StaticData.java
@@ -32,7 +32,7 @@ public class StaticData {
private static StaticData lastInstance = null;
- public StaticData(ICardStorageReader reader, String editionFolder, String blockDataFolder) {
+ public StaticData(CardStorageReader reader, String editionFolder, String blockDataFolder) {
this.editions = new CardEdition.Collection(new CardEdition.Reader(new File(editionFolder)));
lastInstance = this;
diff --git a/forge-core/src/main/java/forge/util/ThreadUtil.java b/forge-core/src/main/java/forge/util/ThreadUtil.java
new file mode 100644
index 00000000000..6e02ef9e794
--- /dev/null
+++ b/forge-core/src/main/java/forge/util/ThreadUtil.java
@@ -0,0 +1,54 @@
+package forge.util;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+public class ThreadUtil {
+
+ static {
+ System.out.printf("(ThreadUtil first call): Running on a machine with %d cpu core(s)%n", Runtime.getRuntime().availableProcessors() );
+ }
+
+ private static class WorkerThreadFactory implements ThreadFactory {
+ private int countr = 0;
+ private String prefix = "";
+
+ public WorkerThreadFactory(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public Thread newThread(Runnable r) {
+ return new Thread(r, prefix + "-" + countr++);
+ }
+ }
+
+
+
+ private final static ExecutorService gameThreadPool = Executors.newCachedThreadPool(new WorkerThreadFactory("Game"));
+ private static ExecutorService getGameThreadPool() { return gameThreadPool; }
+ private final static ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2, new WorkerThreadFactory("Delayed"));
+ private static ScheduledExecutorService getScheduledPool() { return scheduledPool; }
+
+ // 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;
+ }
+
+ public static void invokeInGameThread(Runnable toRun) {
+ getGameThreadPool().execute(toRun);
+ }
+ public static void delay(int milliseconds, Runnable inputUpdater) {
+ getScheduledPool().schedule(inputUpdater, milliseconds, TimeUnit.MILLISECONDS);
+ }
+
+ public static boolean isGameThread() {
+ return Thread.currentThread().getName().startsWith("Game");
+ }
+}
\ No newline at end of file
diff --git a/forge-gui/src/main/java/forge/FThreads.java b/forge-gui/src/main/java/forge/FThreads.java
index f279082e448..bb980772560 100644
--- a/forge-gui/src/main/java/forge/FThreads.java
+++ b/forge-gui/src/main/java/forge/FThreads.java
@@ -2,53 +2,18 @@ package forge;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
import javax.swing.SwingUtilities;
+import forge.util.ThreadUtil;
+
/**
* 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 static class WorkerThreadFactory implements ThreadFactory {
- private int countr = 0;
- private String prefix = "";
-
- public WorkerThreadFactory(String prefix) {
- this.prefix = prefix;
- }
-
- public Thread newThread(Runnable r) {
- return new Thread(r, prefix + "-" + countr++);
- }
- }
-
private FThreads() { } // no instances supposed
-
- private final static ExecutorService gameThreadPool = Executors.newCachedThreadPool(new WorkerThreadFactory("Game"));
- private static ExecutorService getGameThreadPool() { return gameThreadPool; }
- private final static ScheduledExecutorService scheduledPool = Executors.newScheduledThreadPool(2, new WorkerThreadFactory("Delayed"));
- private static ScheduledExecutorService getScheduledPool() { return scheduledPool; }
-
- // 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.
@@ -111,9 +76,7 @@ public class FThreads {
}
- public static void invokeInGameThread(Runnable toRun) {
- getGameThreadPool().execute(toRun);
- }
+
/**
* TODO: Write javadoc for this method.
@@ -124,17 +87,13 @@ public class FThreads {
}
- public static void delay(int milliseconds, Runnable inputUpdater) {
- getScheduledPool().schedule(inputUpdater, milliseconds, TimeUnit.MILLISECONDS);
- }
-
public static void delayInEDT(int milliseconds, final Runnable inputUpdater) {
Runnable runInEdt = new Runnable() {
@Override public void run() {
FThreads.invokeInEdtNowOrLater(inputUpdater);
}
};
- delay(milliseconds, runInEdt);
+ ThreadUtil.delay(milliseconds, runInEdt);
}
public static String debugGetCurrThreadId() {
@@ -171,9 +130,4 @@ public class FThreads {
public static String debugGetStackTraceItem(int depth) {
return debugGetStackTraceItem(depth, false);
}
-
- public static boolean isGameThread() {
- return Thread.currentThread().getName().startsWith("Game");
- }
-
}
diff --git a/forge-gui/src/main/java/forge/Singletons.java b/forge-gui/src/main/java/forge/Singletons.java
index cf40c270965..589f4293c1d 100644
--- a/forge-gui/src/main/java/forge/Singletons.java
+++ b/forge-gui/src/main/java/forge/Singletons.java
@@ -17,11 +17,9 @@
*/
package forge;
-import forge.card.cardfactory.CardStorageReader;
import forge.control.FControl;
import forge.gui.toolbox.FProgressBar;
import forge.gui.workshop.CardScriptInfo;
-import forge.gui.workshop.controllers.CCardScript;
import forge.model.FModel;
import forge.properties.NewConstants;
import forge.view.FView;
@@ -57,7 +55,8 @@ public final class Singletons {
if(withUi)
view = FView.SINGLETON_INSTANCE;
- IProgressObserver progressBarBridge = view == null ? IProgressObserver.emptyObserver : new IProgressObserver() {
+ CardStorageReader.ProgressObserver progressBarBridge = view == null
+ ? CardStorageReader.ProgressObserver.emptyObserver : new CardStorageReader.ProgressObserver() {
FProgressBar bar = view.getSplash().getProgressBar();
@Override
public void setOperationName(final String name, final boolean usePercents) {
diff --git a/forge-gui/src/main/java/forge/game/GameAction.java b/forge-gui/src/main/java/forge/game/GameAction.java
index 46c46c7119f..4a84ebd847f 100644
--- a/forge-gui/src/main/java/forge/game/GameAction.java
+++ b/forge-gui/src/main/java/forge/game/GameAction.java
@@ -75,6 +75,7 @@ import forge.game.zone.Zone;
import forge.game.zone.ZoneType;
import forge.util.Aggregates;
import forge.util.CollectionSuppliers;
+import forge.util.ThreadUtil;
import forge.util.maps.HashMapOfLists;
import forge.util.maps.MapOfLists;
@@ -1620,10 +1621,10 @@ public class GameAction {
// Invokes given runnable in Game thread pool - used to start game and perform actions from UI (when game-0 waits for input)
public void invoke(final Runnable proc) {
- if( FThreads.isGameThread() ) {
+ if( ThreadUtil.isGameThread() ) {
proc.run();
} else
- FThreads.invokeInGameThread(proc);
+ ThreadUtil.invokeInGameThread(proc);
}
}
diff --git a/forge-gui/src/main/java/forge/gui/framework/SLayoutIO.java b/forge-gui/src/main/java/forge/gui/framework/SLayoutIO.java
index 15b80f71f0f..41706368c47 100644
--- a/forge-gui/src/main/java/forge/gui/framework/SLayoutIO.java
+++ b/forge-gui/src/main/java/forge/gui/framework/SLayoutIO.java
@@ -26,12 +26,12 @@ import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
-import forge.FThreads;
import forge.Singletons;
import forge.gui.toolbox.FAbsolutePositioner;
import forge.properties.FileLocation;
import forge.properties.NewConstants;
import forge.util.CollectionSuppliers;
+import forge.util.ThreadUtil;
import forge.util.maps.HashMapOfLists;
import forge.util.maps.MapOfLists;
import forge.view.FFrame;
@@ -63,7 +63,7 @@ public final class SLayoutIO {
public static void saveWindowLayout() {
if (saveWindowRequested.getAndSet(true)) { return; }
- FThreads.delay(500, new Runnable() {
+ ThreadUtil.delay(500, new Runnable() {
@Override
public void run() {
finishSaveWindowLayout();
@@ -230,7 +230,7 @@ public final class SLayoutIO {
*/
public static void saveLayout(final File f0) {
if( saveRequested.getAndSet(true) ) return;
- FThreads.delay(100, new Runnable() {
+ ThreadUtil.delay(100, new Runnable() {
@Override
public void run() {
diff --git a/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java b/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java
index eb67ad89ae2..27e3438efc1 100644
--- a/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java
+++ b/forge-gui/src/main/java/forge/gui/input/InputConfirmMulligan.java
@@ -22,13 +22,13 @@ import java.util.ArrayList;
import java.util.List;
import forge.Card;
-import forge.FThreads;
import forge.game.Game;
import forge.game.player.Player;
import forge.game.zone.ZoneType;
import forge.gui.GuiDialog;
import forge.gui.match.CMatchUI;
import forge.util.Lang;
+import forge.util.ThreadUtil;
import forge.view.ButtonUtil;
/**
*
@@ -122,7 +122,7 @@ public class InputConfirmMulligan extends InputSyncronizedBase {
if ( isSerumPowder && GuiDialog.confirm(c0, "Use " + c0.getName() + "'s ability?")) {
cardSelectLocked = true;
- FThreads.invokeInGameThread(new Runnable() {
+ ThreadUtil.invokeInGameThread(new Runnable() {
public void run() {
List hand = new ArrayList(c0.getController().getCardsIn(ZoneType.Hand));
for (Card c : hand) {
diff --git a/forge-gui/src/main/java/forge/gui/input/InputLockUI.java b/forge-gui/src/main/java/forge/gui/input/InputLockUI.java
index cb5a4beeef0..2755398fad8 100644
--- a/forge-gui/src/main/java/forge/gui/input/InputLockUI.java
+++ b/forge-gui/src/main/java/forge/gui/input/InputLockUI.java
@@ -10,6 +10,7 @@ import forge.card.spellability.SpellAbility;
import forge.control.InputQueue;
import forge.game.player.Player;
import forge.gui.match.CMatchUI;
+import forge.util.ThreadUtil;
import forge.view.ButtonUtil;
/**
@@ -24,7 +25,7 @@ public class InputLockUI implements Input {
public void showMessageInitial() {
int ixCall = 1 + iCall.getAndIncrement();
- FThreads.delay(500, new InputUpdater(ixCall));
+ ThreadUtil.delay(500, new InputUpdater(ixCall));
}
@Override
diff --git a/forge-gui/src/main/java/forge/gui/workshop/CardScriptInfo.java b/forge-gui/src/main/java/forge/gui/workshop/CardScriptInfo.java
index 0635bdcf33f..70c72fc65b8 100644
--- a/forge-gui/src/main/java/forge/gui/workshop/CardScriptInfo.java
+++ b/forge-gui/src/main/java/forge/gui/workshop/CardScriptInfo.java
@@ -20,12 +20,11 @@ package forge.gui.workshop;
import java.io.File;
import java.util.List;
import java.util.Map;
-import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.StringUtils;
-import forge.ICardStorageReader;
+import forge.CardStorageReader;
import forge.card.CardRules;
public final class CardScriptInfo {
@@ -58,7 +57,7 @@ public final class CardScriptInfo {
return allScrips.get(name);
}
- public static ICardStorageReader.Observer readerObserver = new ICardStorageReader.Observer() {
+ public static CardStorageReader.Observer readerObserver = new CardStorageReader.Observer() {
@Override
public void cardLoaded(CardRules rules, List lines, File fileOnDisk) {
allScrips.put(rules.getName(), new CardScriptInfo(StringUtils.join(lines, '\n'), fileOnDisk));
diff --git a/forge-gui/src/main/java/forge/view/CardReaderExperiments.java b/forge-gui/src/main/java/forge/view/CardReaderExperiments.java
index bf1e610f072..262108b681e 100644
--- a/forge-gui/src/main/java/forge/view/CardReaderExperiments.java
+++ b/forge-gui/src/main/java/forge/view/CardReaderExperiments.java
@@ -11,8 +11,8 @@ import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import forge.CardStorageReader;
import forge.card.CardRules;
-import forge.card.cardfactory.CardStorageReader;
import forge.properties.NewConstants;
import forge.util.FileUtil;