Lazy loading of forge.Card instances

This commit is contained in:
Maxmtg
2012-07-30 23:07:39 +00:00
parent 271029de96
commit 63b4fa1b16
18 changed files with 283 additions and 657 deletions

5
.gitattributes vendored
View File

@@ -11908,7 +11908,7 @@ src/main/java/forge/card/abilityfactory/AbilityFactoryToken.java svneol=native#t
src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryTurns.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/AbilityFactoryZoneAffecting.java svneol=native#text/plain
src/main/java/forge/card/abilityfactory/package-info.java svneol=native#text/plain src/main/java/forge/card/abilityfactory/package-info.java svneol=native#text/plain
src/main/java/forge/card/cardfactory/AbstractCardFactory.java svneol=native#text/plain src/main/java/forge/card/cardfactory/CardFactory.java svneol=native#text/plain
src/main/java/forge/card/cardfactory/CardFactoryArtifacts.java -text src/main/java/forge/card/cardfactory/CardFactoryArtifacts.java -text
src/main/java/forge/card/cardfactory/CardFactoryAuras.java svneol=native#text/plain src/main/java/forge/card/cardfactory/CardFactoryAuras.java svneol=native#text/plain
src/main/java/forge/card/cardfactory/CardFactoryCreatures.java svneol=native#text/plain src/main/java/forge/card/cardfactory/CardFactoryCreatures.java svneol=native#text/plain
@@ -11920,7 +11920,6 @@ src/main/java/forge/card/cardfactory/CardFactoryLands.java svneol=native#text/pl
src/main/java/forge/card/cardfactory/CardFactoryPlaneswalkers.java svneol=native#text/plain src/main/java/forge/card/cardfactory/CardFactoryPlaneswalkers.java svneol=native#text/plain
src/main/java/forge/card/cardfactory/CardFactorySorceries.java svneol=native#text/plain src/main/java/forge/card/cardfactory/CardFactorySorceries.java svneol=native#text/plain
src/main/java/forge/card/cardfactory/CardFactoryUtil.java svneol=native#text/plain src/main/java/forge/card/cardfactory/CardFactoryUtil.java svneol=native#text/plain
src/main/java/forge/card/cardfactory/PreloadingCardFactory.java svneol=native#text/plain
src/main/java/forge/card/cardfactory/package-info.java svneol=native#text/plain src/main/java/forge/card/cardfactory/package-info.java svneol=native#text/plain
src/main/java/forge/card/cost/Cost.java svneol=native#text/plain src/main/java/forge/card/cost/Cost.java svneol=native#text/plain
src/main/java/forge/card/cost/CostDiscard.java -text src/main/java/forge/card/cost/CostDiscard.java -text
@@ -12427,12 +12426,10 @@ src/site/apt/index.apt -text
src/test/java/forge/BoosterDraft1Test.java svneol=native#text/plain src/test/java/forge/BoosterDraft1Test.java svneol=native#text/plain
src/test/java/forge/BoosterDraftTest.java svneol=native#text/plain src/test/java/forge/BoosterDraftTest.java svneol=native#text/plain
src/test/java/forge/CardColorTest.java svneol=native#text/plain src/test/java/forge/CardColorTest.java svneol=native#text/plain
src/test/java/forge/CardReaderTest.java svneol=native#text/plain
src/test/java/forge/DeckWantsTest.java -text src/test/java/forge/DeckWantsTest.java -text
src/test/java/forge/GuiDownloadPicturesLQTest.java svneol=native#text/plain src/test/java/forge/GuiDownloadPicturesLQTest.java svneol=native#text/plain
src/test/java/forge/GuiDownloadSetPicturesLQTest.java svneol=native#text/plain src/test/java/forge/GuiDownloadSetPicturesLQTest.java svneol=native#text/plain
src/test/java/forge/GuiMigrateLocalMWSSetPicturesHQTest.java svneol=native#text/plain src/test/java/forge/GuiMigrateLocalMWSSetPicturesHQTest.java svneol=native#text/plain
src/test/java/forge/GuiMultipleBlockers4Test.java svneol=native#text/plain
src/test/java/forge/GuiProgressBarWindowTest.java svneol=native#text/plain src/test/java/forge/GuiProgressBarWindowTest.java svneol=native#text/plain
src/test/java/forge/PanelTest.java svneol=native#text/plain src/test/java/forge/PanelTest.java svneol=native#text/plain
src/test/java/forge/ReadDraftRankingsTest.java -text src/test/java/forge/ReadDraftRankingsTest.java -text

View File

@@ -20,8 +20,8 @@ package forge;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import forge.card.cardfactory.CardFactory;
import forge.card.cardfactory.CardFactoryInterface; import forge.card.cardfactory.CardFactoryInterface;
import forge.card.cardfactory.PreloadingCardFactory;
import forge.card.replacement.ReplacementHandler; import forge.card.replacement.ReplacementHandler;
import forge.card.trigger.TriggerHandler; import forge.card.trigger.TriggerHandler;
import forge.control.input.InputControl; import forge.control.input.InputControl;
@@ -205,7 +205,7 @@ public final class AllZone {
if (AllZone.cardFactory == null) { if (AllZone.cardFactory == null) {
// setCardFactory(new // setCardFactory(new
// LazyCardFactory(ForgeProps.getFile(CARDSFOLDER))); // LazyCardFactory(ForgeProps.getFile(CARDSFOLDER)));
AllZone.setCardFactory(new PreloadingCardFactory(ForgeProps.getFile(NewConstants.CARDSFOLDER))); AllZone.setCardFactory(new CardFactory(ForgeProps.getFile(NewConstants.CARDSFOLDER)));
} }
return AllZone.cardFactory; return AllZone.cardFactory;
} }

View File

@@ -28,7 +28,6 @@ import java.util.ArrayList;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
@@ -57,7 +56,7 @@ import forge.view.SplashFrame;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public class CardReader implements Runnable { public class CardReader {
// PM // PM
private static final String CARD_FILE_DOT_EXTENSION = ".txt"; private static final String CARD_FILE_DOT_EXTENSION = ".txt";
@@ -101,8 +100,6 @@ public class CardReader implements Runnable {
// 10:54 // 10:54
// PM // PM
private transient Map<String, Card> mapToFill;
private transient List<CardRules> listRulesToFill;
private transient File cardsfolder; private transient File cardsfolder;
private transient ZipFile zip; private transient ZipFile zip;
@@ -118,33 +115,6 @@ public class CardReader implements Runnable {
// 8/18/11 10:56 PM // 8/18/11 10:56 PM
/**
* Instantiates a new card reader.
*
* @param theCardsFolder
* the the cards folder
* @param theMapToFill
* the the map to fill
*/
public CardReader(final File theCardsFolder, final Map<String, Card> theMapToFill) {
this(theCardsFolder, theMapToFill, null, true);
}
/**
* This is a convenience for CardReader(cardsfolder, mapToFill, true); .
*
* @param theCardsFolder
* indicates location of the cardsFolder
* @param theMapToFill
* maps card names to Card instances; this is where we place the
* cards once read
* @param listRules2Fill
* List<CardRules>
*/
public CardReader(final File theCardsFolder, final Map<String, Card> theMapToFill,
final List<CardRules> listRules2Fill) {
this(theCardsFolder, theMapToFill, listRules2Fill, true);
}
/** /**
* <p> * <p>
@@ -163,20 +133,9 @@ public class CardReader implements Runnable {
* if true, attempts to load cards from a zip file, if one * if true, attempts to load cards from a zip file, if one
* exists. * exists.
*/ */
public CardReader(final File theCardsFolder, final Map<String, Card> theMapToFill, public CardReader(final File theCardsFolder, final boolean useZip) {
final List<CardRules> listRules2Fill, final boolean useZip) {
if (theMapToFill == null) {
throw new NullPointerException("theMapToFill must not be null.");
// by
// Braids
// on
// 8/18/11
// 10:53
// PM
}
this.mapToFill = theMapToFill;
// These read data for lightweight classes. // These read data for lightweight classes.
this.listRulesToFill = listRules2Fill == null ? new ArrayList<CardRules>() : listRules2Fill;
this.rulesReader = new CardRulesReader(); this.rulesReader = new CardRulesReader();
if (!theCardsFolder.exists()) { if (!theCardsFolder.exists()) {
@@ -206,24 +165,16 @@ public class CardReader implements Runnable {
+ theCardsFolder.getAbsolutePath() + "\"."); + theCardsFolder.getAbsolutePath() + "\".");
} }
} if (this.zip != null) {
if (useZip && (this.zip != null)) {
this.zipEnum = this.zip.entries(); this.zipEnum = this.zip.entries();
this.estimatedFilesRemaining = this.zip.size(); this.estimatedFilesRemaining = this.zip.size();
} }
}
this.setEncoding(CardReader.DEFAULT_CHARSET_NAME); this.setEncoding(CardReader.DEFAULT_CHARSET_NAME);
} // CardReader() } // CardReader()
/**
* Reads the rest of ALL the cards into memory. This is not lazy.
*/
@Override
public final void run() {
this.loadCards();
}
/** /**
* Starts reading cards into memory until the given card is found. * Starts reading cards into memory until the given card is found.
@@ -236,8 +187,9 @@ public class CardReader implements Runnable {
* *
* @return the Card or null if it was not found. * @return the Card or null if it was not found.
*/ */
protected final Card loadCards() { public final List<CardRules> loadCards() {
Card result = null;
List<CardRules> result = new ArrayList<CardRules>();
final FProgressBar barProgress = SplashFrame.PROGRESS_BAR; final FProgressBar barProgress = SplashFrame.PROGRESS_BAR;
// Iterate through txt files or zip archive. // Iterate through txt files or zip archive.
@@ -266,7 +218,7 @@ public class CardReader implements Runnable {
continue; continue;
} }
result = this.loadCard(cardTxtFile); result.add(this.loadCard(cardTxtFile));
barProgress.increment(); barProgress.increment();
} // endfor } // endfor
@@ -283,7 +235,7 @@ public class CardReader implements Runnable {
continue; continue;
} }
result = this.loadCard(entry); result.add(this.loadCard(entry));
barProgress.increment(); barProgress.increment();
} }
} // endif } // endif
@@ -338,30 +290,15 @@ public class CardReader implements Runnable {
* *
* @return the card loaded from the stream * @return the card loaded from the stream
*/ */
protected final Card loadCard(final InputStream inputStream) { protected final CardRules loadCard(final InputStream inputStream) {
this.rulesReader.reset(); this.rulesReader.reset();
InputStreamReader isr = new InputStreamReader(inputStream, this.charset); InputStreamReader isr = new InputStreamReader(inputStream, this.charset);
List<String> allLines = FileUtil.readAllLines(isr, true); List<String> allLines = FileUtil.readAllLines(isr, true);
final Card card = CardReader.readCard(allLines, this.rulesReader, this.mapToFill); CardReader.loadCard(allLines, this.rulesReader);
return this.rulesReader.getCard();
if (card.isInAlternateState()) {
card.setState(CardCharactersticName.Original);
}
this.listRulesToFill.add(this.rulesReader.getCard());
this.mapToFill.put(card.getName(), card);
return card;
}
/**
* Read card.
*
* @param lines the lines
* @return the card
*/
public static Card readCard(final Iterable<String> lines) {
return CardReader.readCard(lines, null, null);
} }
/** /**
@@ -372,19 +309,42 @@ public class CardReader implements Runnable {
* @param mapToFill is used to eliminate duplicates * @param mapToFill is used to eliminate duplicates
* @return the card * @return the card
*/ */
public static Card readCard(final Iterable<String> lines, final CardRulesReader rulesReader, final Map<String, Card> mapToFill) { public static void loadCard(final Iterable<String> lines, final CardRulesReader rulesReader) {
final Card card = new Card();
boolean ignoreTheRest = false;
for (String line : lines) { for (String line : lines) {
if (ignoreTheRest || line.isEmpty()) { if (line.isEmpty() || line.charAt(0) == '#') {
continue; continue;
} }
switch(line.charAt(0)) { // this is a simple state machine to gain some performance rulesReader.parseLine(line);
case '#': }
continue; }
public static Card readCard(final Iterable<String> lines)
{
final Card card = new Card();
for (String line : lines) {
if (line.isEmpty() || line.charAt(0) == '#') {
continue;
}
parseCardLine(card, line);
} // while !End
if (card.isInAlternateState()) {
card.setState(CardCharactersticName.Original);
}
return card;
}
private static void parseCardLine(Card card, String line) {
char firstCh = line.charAt(0);
switch(firstCh) { // this is a simple state machine to gain some performance
case 'A': case 'A':
if (line.equals("ALTERNATE")) { if (line.equals("ALTERNATE")) {
CardCharactersticName mode; CardCharactersticName mode;
@@ -428,14 +388,6 @@ public class CardReader implements Runnable {
} }
break; break;
case 'E':
if ("End".equals(line)) {
ignoreTheRest = true; // have to deplete the iterator
continue;
// otherwise the underlying class would close its stream on finalize only
}
break;
case 'K': case 'K':
if (line.startsWith("K:")) { if (line.startsWith("K:")) {
final String value = line.substring(2); final String value = line.substring(2);
@@ -464,13 +416,8 @@ public class CardReader implements Runnable {
case 'N': case 'N':
if (line.startsWith("Name")) { if (line.startsWith("Name")) {
final String value = line.substring(5); final String value = line.substring(5);
// System.out.println(s);
if ((mapToFill != null) && mapToFill.containsKey(value)) {
break; // this card has already been loaded.
} else {
card.setName(value); card.setName(value);
} }
}
break; break;
case 'P': case 'P':
@@ -533,14 +480,7 @@ public class CardReader implements Runnable {
break; break;
} }
if (null != rulesReader) {
rulesReader.parseLine(line);
} }
} // while !End
return card;
}
/** /**
* Set the character encoding to use when loading cards. * Set the character encoding to use when loading cards.
* *
@@ -559,7 +499,7 @@ public class CardReader implements Runnable {
* *
* @return a new Card instance * @return a new Card instance
*/ */
protected final Card loadCard(final File pathToTxtFile) { protected final CardRules loadCard(final File pathToTxtFile) {
FileInputStream fileInputStream = null; FileInputStream fileInputStream = null;
try { try {
fileInputStream = new FileInputStream(pathToTxtFile); fileInputStream = new FileInputStream(pathToTxtFile);
@@ -586,12 +526,11 @@ public class CardReader implements Runnable {
* *
* @return a new Card instance * @return a new Card instance
*/ */
protected final Card loadCard(final ZipEntry entry) { protected final CardRules loadCard(final ZipEntry entry) {
InputStream zipInputStream = null; InputStream zipInputStream = null;
try { try {
zipInputStream = this.zip.getInputStream(entry); zipInputStream = this.zip.getInputStream(entry);
return this.loadCard(zipInputStream); return this.loadCard(zipInputStream);
} catch (final IOException exn) { } catch (final IOException exn) {
throw new RuntimeException(exn); throw new RuntimeException(exn);
// PM // PM

View File

@@ -59,6 +59,8 @@ public final class CardRules {
private final boolean hasOtherFace; private final boolean hasOtherFace;
private List<String> originalScript;
// Ctor and builders are needed here // Ctor and builders are needed here
/** /**
* Gets the name. * Gets the name.
@@ -234,14 +236,14 @@ public final class CardRules {
* @param removedFromAIDecks * @param removedFromAIDecks
* the removed from ai decks * the removed from ai decks
*/ */
public CardRules(final CardRuleCharacteristics chars, final boolean isDoubleFacedCard, final CardRules otherPart, public CardRules(final CardRuleCharacteristics chars, List<String> forgeScript, final boolean isDoubleFacedCard, final CardRules otherPart,
final boolean removedFromRandomDecks, final boolean removedFromAIDecks) { final boolean removedFromRandomDecks, final boolean removedFromAIDecks) {
this.characteristics = chars; this.characteristics = chars;
this.slavePart = otherPart; this.slavePart = otherPart;
this.hasOtherFace = isDoubleFacedCard; this.hasOtherFace = isDoubleFacedCard;
this.isRemovedFromAIDecks = removedFromAIDecks; this.isRemovedFromAIDecks = removedFromAIDecks;
this.isRemovedFromRandomDecks = removedFromRandomDecks; this.isRemovedFromRandomDecks = removedFromRandomDecks;
this.originalScript = forgeScript == null ? null : new ArrayList<String>(forgeScript);
// System.out.println(cardName); // System.out.println(cardName);
if (this.getType().isCreature()) { if (this.getType().isCreature()) {
@@ -897,4 +899,12 @@ public final class CardRules {
CardRarity.Special); CardRarity.Special);
} }
} }
/**
* TODO: Write javadoc for this method.
* @return
*/
public Iterable<String> getCardScript() {
return originalScript;
}
} }

View File

@@ -17,6 +17,8 @@
*/ */
package forge.card; package forge.card;
import java.util.ArrayList;
import java.util.List;
import java.util.Map; import java.util.Map;
import forge.card.mana.ManaCostShard; import forge.card.mana.ManaCostShard;
@@ -43,6 +45,7 @@ public class CardRulesReader {
private boolean removedFromAIDecks = false; private boolean removedFromAIDecks = false;
private boolean removedFromRandomDecks = false; private boolean removedFromRandomDecks = false;
private List<String> originalScript = new ArrayList<String>();
// Reset all fields to parse next card (to avoid allocating new // Reset all fields to parse next card (to avoid allocating new
// CardRulesReader N times) // CardRulesReader N times)
@@ -54,6 +57,7 @@ public class CardRulesReader {
this.curCharacteristics = 0; this.curCharacteristics = 0;
this.removedFromAIDecks = false; this.removedFromAIDecks = false;
this.removedFromRandomDecks = false; this.removedFromRandomDecks = false;
originalScript.clear();
// this.isDoubleFacedCard = false; // this.isDoubleFacedCard = false;
// this.isFlipCard = false; // this.isFlipCard = false;
} }
@@ -65,10 +69,10 @@ public class CardRulesReader {
*/ */
public final CardRules getCard() { public final CardRules getCard() {
final boolean hasOtherPart = this.characteristics[1] != null; final boolean hasOtherPart = this.characteristics[1] != null;
final CardRules otherPart = hasOtherPart ? new CardRules(this.characteristics[1], true, null, final CardRules otherPart = hasOtherPart ? new CardRules(this.characteristics[1], null, true, null,
this.removedFromRandomDecks, this.removedFromAIDecks) : null; this.removedFromRandomDecks, this.removedFromAIDecks) : null;
return new CardRules(this.characteristics[0], hasOtherPart, otherPart, this.removedFromRandomDecks, return new CardRules(this.characteristics[0], originalScript, hasOtherPart, otherPart, this.removedFromRandomDecks,
this.removedFromAIDecks); this.removedFromAIDecks);
} }
@@ -79,6 +83,9 @@ public class CardRulesReader {
* the line * the line
*/ */
public final void parseLine(final String line) { public final void parseLine(final String line) {
originalScript.add(line);
switch( line.charAt(0)){ switch( line.charAt(0)){
case 'A': case 'A':
if (line.startsWith("AlternateMode:")) { if (line.startsWith("AlternateMode:")) {

View File

@@ -149,9 +149,9 @@ public final class MtgDataParser implements Iterator<CardRules> {
return null; return null;
} }
final CardRules otherPart = hasOtherPart ? new CardRules(this.chars[1], hasOtherPart, null, false, false) final CardRules otherPart = hasOtherPart ? new CardRules(this.chars[1], null, hasOtherPart, null, false, false)
: null; : null;
return new CardRules(this.chars[0], hasOtherPart, otherPart, false, false); return new CardRules(this.chars[0], null, hasOtherPart, otherPart, false, false);
} }
private String readSingleCard(final CardRuleCharacteristics ret) { private String readSingleCard(final CardRuleCharacteristics ret) {

View File

@@ -1623,7 +1623,7 @@ public final class AbilityFactoryChoose {
// still missing a listener to display the card preview // still missing a listener to display the card preview
// in the right // in the right
name = choice.getSelectedValue(); name = choice.getSelectedValue();
if (AllZone.getCardFactory().getCard(name, p).isValid(valid, host.getController(), host)) { if (AllZone.getCardFactory().getCard(CardDb.instance().getCard(name), p).isValid(valid, host.getController(), host)) {
host.setNamedCard(choice.getSelectedValue()); host.setNamedCard(choice.getSelectedValue());
ok = true; ok = true;
} }

View File

@@ -44,6 +44,7 @@ import forge.game.player.ComputerUtil;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.gui.GuiUtils; import forge.gui.GuiUtils;
import forge.item.CardDb;
import forge.util.MyRandom; import forge.util.MyRandom;
/** /**
@@ -408,7 +409,8 @@ public final class AbilityFactoryCopy {
Card copy; Card copy;
if (!c.isToken()) { if (!c.isToken()) {
// copy creature and put it onto the battlefield // copy creature and put it onto the battlefield
copy = AllZone.getCardFactory().getCard(c.getName(), sa.getActivatingPlayer());
copy = AllZone.getCardFactory().getCard(CardDb.instance().getCard(c), sa.getActivatingPlayer());
// when copying something stolen: // when copying something stolen:
copy.addController(sa.getActivatingPlayer()); copy.addController(sa.getActivatingPlayer());

View File

@@ -20,24 +20,24 @@ package forge.card.cardfactory;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import forge.AllZone; import forge.AllZone;
import forge.Card; import forge.Card;
import forge.CardCharactersticName; import forge.CardCharactersticName;
import forge.CardList; import forge.CardReader;
import forge.CardUtil;
import forge.Singletons; import forge.Singletons;
import forge.card.CardRules;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.card.spellability.SpellPermanent; import forge.card.spellability.SpellPermanent;
import forge.card.spellability.Target; import forge.card.spellability.Target;
import forge.error.ErrorViewer;
import forge.game.player.ComputerUtil; import forge.game.player.ComputerUtil;
import forge.game.player.Player; import forge.game.player.Player;
import forge.gui.GuiUtils;
import forge.item.CardDb;
import forge.item.CardPrinted;
import forge.properties.ForgeProps; import forge.properties.ForgeProps;
import forge.properties.NewConstants; import forge.properties.NewConstants;
import forge.util.FileUtil;
/** /**
* <p> * <p>
@@ -57,22 +57,7 @@ import forge.util.FileUtil;
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
public abstract class AbstractCardFactory implements CardFactoryInterface { public class CardFactory implements CardFactoryInterface {
/**
* This maps card name Strings to Card instances. The Card instances have no
* owner, and lack abilities.
*
* To get a full-fledged card, see allCards field or the iterator method.
*/
private final Map<String, Card> map = new TreeMap<String, Card>();
/** This is a special list of cards, with all abilities attached. */
protected List<Card> allCardsReadOnly;
private Set<String> removedCardList;
private final Card blankCard = new Card(); // new code
private final CardList copiedList = new CardList();
/** /**
* <p> * <p>
@@ -82,45 +67,23 @@ public abstract class AbstractCardFactory implements CardFactoryInterface {
* @param file * @param file
* a {@link java.io.File} object. * a {@link java.io.File} object.
*/ */
protected AbstractCardFactory(final File file) { private final CardReader reader;
final SpellAbility spell = new SpellAbility(SpellAbility.getSpell(), this.blankCard) {
// neither computer nor human play can play this card public CardFactory(final File file) {
@Override
public boolean canPlay() { GuiUtils.checkEDT("CardFactory$constructor", false);
return false; reader = new CardReader(ForgeProps.getFile(NewConstants.CARDSFOLDER), true);
try {
// this fills in our map of card names to Card instances.
final List<CardRules> listCardRules = reader.loadCards();
CardDb.setup(listCardRules.iterator());
} catch (final Exception ex) {
ErrorViewer.showError(ex);
} }
@Override
public void resolve() {
}
};
this.blankCard.addSpellAbility(spell);
spell.setManaCost("1");
this.blankCard.setName("Removed Card");
// owner and controller will be wrong sometimes
// but I don't think it will matter
// theoretically blankCard will go to the wrong graveyard
this.blankCard.setOwner(AllZone.getHumanPlayer());
this.removedCardList = new TreeSet<String>(FileUtil.readFile(ForgeProps.getFile(NewConstants.REMOVED)));
} // constructor } // constructor
/**
* Getter for allCards.
*
* @return allCards
*/
/**
* Getter for map.
*
* @return map
*/
protected final Map<String, Card> getMap() {
return this.map;
}
/** /**
* <p> * <p>
@@ -137,9 +100,8 @@ public abstract class AbstractCardFactory implements CardFactoryInterface {
if (in.isInAlternateState()) { if (in.isInAlternateState()) {
in.setState(CardCharactersticName.Original); in.setState(CardCharactersticName.Original);
} }
final Card out = this.getCard(in.getName(), in.getOwner()); final Card out = this.getCard(CardDb.instance().getCard(in), in.getOwner());
out.setUniqueNumber(in.getUniqueNumber()); out.setUniqueNumber(in.getUniqueNumber());
out.setCurSetCode(in.getCurSetCode());
CardFactoryUtil.copyCharacteristics(in, out); CardFactoryUtil.copyCharacteristics(in, out);
if (in.hasAlternateState()) { if (in.hasAlternateState()) {
@@ -244,25 +206,37 @@ public abstract class AbstractCardFactory implements CardFactoryInterface {
* blankCard * blankCard
*/ */
@Override @Override
public final Card getCard(final String cardName, final Player owner) { public final Card getCard(final CardPrinted cp, final Player owner) {
if (this.removedCardList.contains(cardName) || cardName.equals(this.blankCard.getName())) {
return this.blankCard;
}
//System.out.println(cardName); //System.out.println(cardName);
return this.getCard2(cardName, owner); Card c = this.getCard2(cp.getCard().getCardScript(), owner);
if (c != null) {
c.setCurSetCode(cp.getEdition());
c.setRandomPicture(cp.getArtIndex() + 1);
c.setImageFilename(cp.getImageFilename());
if (c.hasAlternateState()) {
if (c.isFlipCard()) {
c.setState(CardCharactersticName.Flipped);
}
if (c.isDoubleFaced()) {
c.setState(CardCharactersticName.Transformed);
}
c.setImageFilename(CardUtil.buildFilename(c));
c.setState(CardCharactersticName.Original);
}
}
// else throw "Unsupported card";
return c;
} }
protected Card getCard2(final String cardName, final Player owner) { protected Card getCard2(final Iterable<String> script, final Player owner) {
// o should be Card object // o should be Card object
final Card o = this.map.get(cardName); final Card o = CardReader.readCard(script);
if (o == null) { o.setOwner(owner);
final StringBuilder sb = new StringBuilder(); return buildAbilities(o);
sb.append("CardFactory : getCard() invalid card name - ").append(cardName);
throw new RuntimeException(sb.toString());
}
return getCard2(o, owner);
} }
public static Card getCard2(final Card o, final Player owner) { public static Card getCard2(final Card o, final Player owner) {

View File

@@ -21,6 +21,7 @@ package forge.card.cardfactory;
import forge.Card; import forge.Card;
import forge.card.spellability.SpellAbility; import forge.card.spellability.SpellAbility;
import forge.game.player.Player; import forge.game.player.Player;
import forge.item.CardPrinted;
/** /**
* The Interface CardFactoryInterface. * The Interface CardFactoryInterface.
@@ -65,5 +66,5 @@ public interface CardFactoryInterface {
* @return a {@link forge.Card} instance, owned by owner; or the special * @return a {@link forge.Card} instance, owned by owner; or the special
* blankCard * blankCard
*/ */
Card getCard(String cardName, Player owner); Card getCard(CardPrinted card, Player owner);
} }

View File

@@ -1,113 +0,0 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package forge.card.cardfactory;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.swing.SwingUtilities;
import forge.AllZone;
import forge.Card;
import forge.CardReader;
import forge.card.CardRules;
import forge.error.ErrorViewer;
import forge.gui.GuiUtils;
import forge.gui.toolbox.FProgressBar;
import forge.item.CardDb;
import forge.properties.ForgeProps;
import forge.properties.NewConstants;
import forge.view.SplashFrame;
/**
* <p>
* CardFactory class.
* </p>
*
* TODO The map field contains Card instances that have not gone through
* getCard2, and thus lack abilities. However, when a new Card is requested via
* getCard, it is this map's values that serve as the templates for the values
* it returns. This class has another field, allCards, which is another copy of
* the card database. These cards have abilities attached to them, and are owned
* by the human player by default. <b>It would be better memory-wise if we had
* only one or the other.</b> We may experiment in the future with using
* allCard-type values for the map instead of the less complete ones that exist
* there today.
*
* @author Forge
* @version $Id$
*/
public class PreloadingCardFactory extends AbstractCardFactory {
/**
* <p>
* Constructor for CardFactory.
* </p>
*
* @param filename
* a {@link java.lang.String} object.
*/
public PreloadingCardFactory(final String filename) {
this(new File(filename));
}
/**
* <p>
* Constructor for CardFactory.
* </p>
*
* @param file
* a {@link java.io.File} object.
*/
public PreloadingCardFactory(final File file) {
super(file);
GuiUtils.checkEDT("PreloadingCardFactory$constructor", false);
try {
this.readCards(file);
} catch (final Exception ex) {
ErrorViewer.showError(ex);
}
} // constructor
/**
* <p>
* readCards.
* </p>
*
* @param file
* a {@link java.io.File} object.
*/
protected final void readCards(final File file) {
this.getMap().clear();
final List<CardRules> listCardRules = new ArrayList<CardRules>();
final CardReader read = new CardReader(ForgeProps.getFile(NewConstants.CARDSFOLDER), this.getMap(),
listCardRules);
// this fills in our map of card names to Card instances.
read.run();
CardDb.setup(listCardRules.iterator());
} // readCard()
} // end class PreloadingCardFactory

View File

@@ -3,7 +3,6 @@ package forge.game.limited;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import forge.AllZone;
import forge.Card; import forge.Card;
import forge.CardList; import forge.CardList;
import forge.CardListFilter; import forge.CardListFilter;
@@ -14,6 +13,8 @@ import forge.card.CardManaCost;
import forge.card.DeckWants; import forge.card.DeckWants;
import forge.card.mana.ManaCostShard; import forge.card.mana.ManaCostShard;
import forge.deck.Deck; import forge.deck.Deck;
import forge.item.CardDb;
import forge.item.CardPrinted;
import forge.util.MyRandom; import forge.util.MyRandom;
/** /**
@@ -130,9 +131,8 @@ public class LimitedDeck extends Deck {
// if no playable cards remain fill up with basic lands // if no playable cards remain fill up with basic lands
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
if (clrCnts[i].getCount() > 0) { if (clrCnts[i].getCount() > 0) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(), AllZone.getComputerPlayer()); final CardPrinted cp = CardDb.instance().getCard(clrCnts[i].getColor(), IBoosterDraft.LAND_SET_CODE[0]);
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]); deckList.add(cp.toForgeCard());
deckList.add(c);
break; break;
} }
} }
@@ -207,9 +207,8 @@ public class LimitedDeck extends Deck {
} }
for (int j = 0; j <= nLand; j++) { for (int j = 0; j <= nLand; j++) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[i].getColor(), AllZone.getComputerPlayer()); final CardPrinted cp = CardDb.instance().getCard(clrCnts[i].getColor(), IBoosterDraft.LAND_SET_CODE[0]);
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]); deckList.add(cp.toForgeCard());
deckList.add(c);
landsAdded++; landsAdded++;
} }
} }
@@ -219,13 +218,12 @@ public class LimitedDeck extends Deck {
int n = 0; int n = 0;
while (landsNeeded > 0) { while (landsNeeded > 0) {
if (clrCnts[n].getCount() > 0) { if (clrCnts[n].getCount() > 0) {
final Card c = AllZone.getCardFactory().getCard(clrCnts[n].getColor(), AllZone.getComputerPlayer()); CardPrinted cp = CardDb.instance().getCard(clrCnts[n].getColor(), IBoosterDraft.LAND_SET_CODE[0]);
c.setCurSetCode(IBoosterDraft.LAND_SET_CODE[0]); deckList.add(cp.toForgeCard());
deckList.add(c);
landsNeeded--; landsNeeded--;
if (Constant.Runtime.DEV_MODE[0]) { if (Constant.Runtime.DEV_MODE[0]) {
System.out.println("AddBasics: " + c.getName()); System.out.println("AddBasics: " + cp.getName());
} }
} }
if (++n > 4) { if (++n > 4) {

View File

@@ -580,7 +580,7 @@ public final class GuiDisplayUtil {
for (final String element : data) { for (final String element : data) {
final String[] cardinfo = element.trim().split("\\|"); final String[] cardinfo = element.trim().split("\\|");
final Card c = AllZone.getCardFactory().getCard(cardinfo[0], player); final Card c = AllZone.getCardFactory().getCard(CardDb.instance().getCard(cardinfo[0]), player);
boolean hasSetCurSet = false; boolean hasSetCurSet = false;
for (final String info : cardinfo) { for (final String info : cardinfo) {

View File

@@ -25,12 +25,10 @@ import org.apache.commons.lang3.ArrayUtils;
import forge.AllZone; import forge.AllZone;
import forge.Card; import forge.Card;
import forge.CardCharactersticName;
import forge.CardUtil; import forge.CardUtil;
import forge.card.CardRarity; import forge.card.CardRarity;
import forge.card.CardRules; import forge.card.CardRules;
import forge.game.player.Player; import forge.game.player.Player;
import forge.util.MyRandom;
import forge.util.closures.Lambda1; import forge.util.closures.Lambda1;
import forge.util.closures.Predicate; import forge.util.closures.Predicate;
import forge.util.closures.PredicateString; import forge.util.closures.PredicateString;
@@ -291,30 +289,7 @@ public final class CardPrinted implements Comparable<CardPrinted>, InventoryItem
* @return the card * @return the card
*/ */
public Card toForgeCard(Player owner) { public Card toForgeCard(Player owner) {
final Card c = AllZone.getCardFactory().getCard(this.name, owner); final Card c = AllZone.getCardFactory().getCard(this, owner);
if (c != null) {
c.setCurSetCode(this.getEdition());
c.setRandomPicture(this.artIndex + 1);
c.setImageFilename(this.getImageFilename());
if (c.hasAlternateState()) {
if (c.isFlipCard()) {
c.setState(CardCharactersticName.Flipped);
}
if (c.isDoubleFaced()) {
c.setState(CardCharactersticName.Transformed);
}
c.setImageFilename(CardUtil.buildFilename(c));
c.setState(CardCharactersticName.Original);
}
}
final int cntVariants = getCard().getEditionInfo(getEdition()).getCopiesCount();
if (cntVariants > 1) {
c.setRandomPicture(MyRandom.getRandom().nextInt(cntVariants - 1) + 1);
c.setImageFilename(CardUtil.buildFilename(c));
}
// else throw "Unsupported card";
return c; return c;
} }

View File

@@ -21,8 +21,9 @@ import forge.AllZone;
import forge.Card; import forge.Card;
import forge.CardList; import forge.CardList;
import forge.CardUtil; import forge.CardUtil;
import forge.card.cardfactory.AbstractCardFactory; import forge.card.cardfactory.CardFactory;
import forge.game.player.Player; import forge.game.player.Player;
import forge.item.CardDb;
import forge.quest.bazaar.QuestPetController; import forge.quest.bazaar.QuestPetController;
import java.util.List; import java.util.List;
@@ -96,7 +97,7 @@ public class QuestUtil {
if (pet != null) { if (pet != null) {
Card c = pet.getPetCard(qc.getAssets()); Card c = pet.getPetCard(qc.getAssets());
if (c != null) { if (c != null) {
Card copy = AbstractCardFactory.getCard2(c, AllZone.getHumanPlayer()); Card copy = CardFactory.getCard2(c, AllZone.getHumanPlayer());
copy.setSickness(true); copy.setSickness(true);
copy.addController(AllZone.getHumanPlayer()); copy.addController(AllZone.getHumanPlayer());
copy.setImageName(c.getImageName()); copy.setImageName(c.getImageName());
@@ -190,9 +191,7 @@ public class QuestUtil {
} }
// Standard card creation // Standard card creation
else { else {
tempcard = AllZone.getCardFactory().getCard(name, owner); tempcard = CardDb.instance().getCard(name, true).toForgeCard(owner);
tempcard.setCurSetCode(tempcard.getMostRecentSet());
tempcard.setImageFilename(CardUtil.buildFilename(tempcard));
} }
return tempcard; return tempcard;
} }

View File

@@ -1,128 +0,0 @@
package forge;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import net.slightlymagic.braids.util.testng.BraidsAssertFunctions;
import net.slightlymagic.braids.util.testng.ClumsyRunnable;
import org.testng.Assert;
import org.testng.annotations.Test;
import forge.properties.ForgeProps;
import forge.properties.NewConstants;
/**
* Created by hand to test the CardReader class.
*/
@Test(groups = { "UnitTest" }, enabled = false)
public class CardReaderTest {
/** The default test-timeout. */
public static final int TEST_TIMEOUT = 1000;
/** The estimated number of cards in the cardsfolder. */
public static final int ESTIMATED_CARDS_IN_FOLDER = 9001;
/**
* Test_ read card_null map.
*/
@Test(groups = { "UnitTest", "fast" }, timeOut = CardReaderTest.TEST_TIMEOUT)
public final void test_ReadCard_nullMap() {
final ClumsyRunnable withScissors = new ClumsyRunnable() {
@Override
public void run() throws Exception {
new CardReader(ForgeProps.getFile(NewConstants.CARDSFOLDER), null);
}
};
BraidsAssertFunctions.assertThrowsException(NullPointerException.class, withScissors);
}
/**
* Test_ read card_null cards folder.
*/
@Test(groups = { "UnitTest", "fast" }, timeOut = CardReaderTest.TEST_TIMEOUT)
public final void test_ReadCard_nullCardsFolder() {
final ClumsyRunnable withScissors = new ClumsyRunnable() {
@Override
public void run() throws Exception {
final Map<String, Card> map = new HashMap<String, Card>();
new CardReader(null, map);
}
};
BraidsAssertFunctions.assertThrowsException(NullPointerException.class, withScissors);
}
/**
* Test_ read card_nonexistent cards folder.
*/
@Test(groups = { "UnitTest", "fast" }, timeOut = CardReaderTest.TEST_TIMEOUT)
public final void test_ReadCard_nonexistentCardsFolder() {
final ClumsyRunnable withScissors = new ClumsyRunnable() {
@Override
public void run() throws Exception {
final Map<String, Card> map = new HashMap<String, Card>();
new CardReader(
new File(
"this_does_not_exist_fjksdjfsdjfkdjslkfksdlajfikajfklsdhfksdalfhjklsdahfeakslfdsfdsfdsfdsfdssfc"),
map);
}
};
BraidsAssertFunctions.assertThrowsException(RuntimeException.class, withScissors);
}
/**
* Test_ read card_file not folder.
*
* @throws IOException
* Signals that an I/O exception has occurred.
*/
@Test(groups = { "UnitTest", "fast" }, timeOut = CardReaderTest.TEST_TIMEOUT)
public final void test_ReadCard_fileNotFolder() throws IOException {
final File tmpFile = File.createTempFile("just-a-file", ".testng.tmp");
tmpFile.deleteOnExit(); // request VM to delete later
final ClumsyRunnable withScissors = new ClumsyRunnable() {
@Override
public void run() throws Exception {
final Map<String, Card> map = new HashMap<String, Card>();
new CardReader(tmpFile, map);
}
};
BraidsAssertFunctions.assertThrowsException(RuntimeException.class, withScissors);
}
/**
* Test_ read card_run_nonzip.
*/
@Test(groups = { "slow" }, enabled = false)
public final void test_ReadCard_run_nonzip() {
final Map<String, Card> map = new HashMap<String, Card>(2 * CardReaderTest.ESTIMATED_CARDS_IN_FOLDER);
final File cardsfolder = ForgeProps.getFile(NewConstants.CARDSFOLDER);
final CardReader cardReader = new CardReader(cardsfolder, map, null, false);
cardReader.run();
Assert.assertNotNull(map.get("Elvish Warrior"), "Elvish Warrior was loaded");
Assert.assertNotNull(map.get("Savannah Lions"), "Savannah Lions were loaded");
}
/**
* Test_ read card_run_zip.
*/
@Test(groups = { "slow" }, enabled = false)
public final void test_ReadCard_run_zip() {
final Map<String, Card> map = new HashMap<String, Card>(2 * CardReaderTest.ESTIMATED_CARDS_IN_FOLDER);
final File cardsfolder = ForgeProps.getFile(NewConstants.CARDSFOLDER);
final CardReader cardReader = new CardReader(cardsfolder, map);
cardReader.run();
Assert.assertNotNull(map.get("Elvish Warrior"), "Elvish Warrior was loaded");
Assert.assertNotNull(map.get("Savannah Lions"), "Savannah Lions were loaded");
}
}

View File

@@ -1,28 +0,0 @@
package forge;
import org.testng.annotations.Test;
import forge.gui.GuiMultipleBlockers;
/**
* Created by IntelliJ IDEA. User: dhudson
*/
@Test(groups = { "UnitTest" }, timeOut = 1000, enabled = false)
public class GuiMultipleBlockers4Test {
/**
* Gui multiple blockers4 test1.
*/
@Test(timeOut = 1000, enabled = false)
public void guiMultipleBlockers4Test1() {
final CardList list = new CardList();
list.add(AllZone.getCardFactory().getCard("Elvish Piper", null));
list.add(AllZone.getCardFactory().getCard("Lantern Kami", null));
list.add(AllZone.getCardFactory().getCard("Frostling", null));
list.add(AllZone.getCardFactory().getCard("Frostling", null));
for (int i = 0; i < 2; i++) {
new GuiMultipleBlockers(null, list, i + 1);
}
}
}

View File

@@ -1,17 +1,8 @@
package forge; package forge;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import forge.card.CardManaCost;
import forge.card.cardfactory.CardFactoryInterface; import forge.card.cardfactory.CardFactoryInterface;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostParser;
import forge.control.input.InputPayManaCostUtil;
import forge.game.phase.CombatUtil; import forge.game.phase.CombatUtil;
/** /**
@@ -36,6 +27,7 @@ public class RunTest {
Card c; Card c;
final CardFactoryInterface cf = AllZone.getCardFactory(); final CardFactoryInterface cf = AllZone.getCardFactory();
// ********* test Card // ********* test Card
/*
c = cf.getCard("Elvish Warrior", AllZone.getComputerPlayer()); c = cf.getCard("Elvish Warrior", AllZone.getComputerPlayer());
this.check("1", c.getOwner().isComputer()); this.check("1", c.getOwner().isComputer());
this.check("1.1", c.getName().equals("Elvish Warrior")); this.check("1.1", c.getName().equals("Elvish Warrior"));
@@ -221,7 +213,7 @@ public class RunTest {
// test Input_PayManaCostUtil // test Input_PayManaCostUtil
this.check("98", InputPayManaCostUtil.getLongColorString("G").equals(Constant.Color.GREEN)); this.check("98", InputPayManaCostUtil.getLongColorString("G").equals(Constant.Color.GREEN));
this.check("99", InputPayManaCostUtil.getLongColorString("1").equals(Constant.Color.COLORLESS)); this.check("99", InputPayManaCostUtil.getLongColorString("1").equals(Constant.Color.COLORLESS));
*/
/* /*
* check("101", Input_PayManaCostUtil.isManaNeeded(Constant.Color.Green, * check("101", Input_PayManaCostUtil.isManaNeeded(Constant.Color.Green,
* new ManaCost("5")) == true); check("102", * new ManaCost("5")) == true); check("102",
@@ -255,7 +247,7 @@ public class RunTest {
c2.addIntrinsicKeyword("Flying"); c2.addIntrinsicKeyword("Flying");
this.check("109", CombatUtil.canBlock(c, c2)); this.check("109", CombatUtil.canBlock(c, c2));
this.check("110", !CombatUtil.canBlock(c2, c)); this.check("110", !CombatUtil.canBlock(c2, c));
/*
c = cf.getCard("Fyndhorn Elves", null); c = cf.getCard("Fyndhorn Elves", null);
c2 = cf.getCard("Talas Warrior", null); c2 = cf.getCard("Talas Warrior", null);
this.check("110a", !CombatUtil.canBlock(c2, c)); this.check("110a", !CombatUtil.canBlock(c2, c));
@@ -326,6 +318,7 @@ public class RunTest {
this.check("125", CardUtil.getConvertedManaCost("R R R") == 3); this.check("125", CardUtil.getConvertedManaCost("R R R") == 3);
this.check("126", CardUtil.getConvertedManaCost("1") == 1); this.check("126", CardUtil.getConvertedManaCost("1") == 1);
this.check("127", CardUtil.getConvertedManaCost("2/R 2/G 2/W 2/B 2/U") == 10); this.check("127", CardUtil.getConvertedManaCost("2/R 2/G 2/W 2/B 2/U") == 10);
*/
} // test() } // test()
/** /**