mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'patch-carddb-performance' into 'master'
CardDb Optimisations See merge request core-developers/forge!5258
This commit is contained in:
@@ -2,13 +2,11 @@ package forge;
|
|||||||
|
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.util.FileUtil;
|
import forge.util.FileUtil;
|
||||||
import forge.util.ImageUtil;
|
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public final class ImageKeys {
|
public final class ImageKeys {
|
||||||
public static final String CARD_PREFIX = "c:";
|
public static final String CARD_PREFIX = "c:";
|
||||||
@@ -68,9 +66,8 @@ public final class ImageKeys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static File getImageFile(String key) {
|
public static File getImageFile(String key) {
|
||||||
if (StringUtils.isEmpty(key)) {
|
if (StringUtils.isEmpty(key))
|
||||||
return null;
|
return null;
|
||||||
}
|
|
||||||
|
|
||||||
final String dir;
|
final String dir;
|
||||||
final String filename;
|
final String filename;
|
||||||
@@ -220,14 +217,35 @@ public final class ImageKeys {
|
|||||||
|
|
||||||
//shortcut for determining if a card image exists for a given card
|
//shortcut for determining if a card image exists for a given card
|
||||||
//should only be called from PaperCard.hasImage()
|
//should only be called from PaperCard.hasImage()
|
||||||
|
static HashMap<String, HashSet<String>> cachedContent=new HashMap<>();
|
||||||
public static boolean hasImage(PaperCard pc) {
|
public static boolean hasImage(PaperCard pc) {
|
||||||
Boolean editionHasImage = editionImageLookup.get(pc.getEdition());
|
Boolean editionHasImage = editionImageLookup.get(pc.getEdition());
|
||||||
if (editionHasImage == null) {
|
if (editionHasImage == null) {
|
||||||
String setFolder = getSetFolder(pc.getEdition());
|
String setFolder = getSetFolder(pc.getEdition());
|
||||||
editionHasImage = FileUtil.isDirectoryWithFiles(CACHE_CARD_PICS_DIR + setFolder);
|
editionHasImage = FileUtil.isDirectoryWithFiles(CACHE_CARD_PICS_DIR + setFolder);
|
||||||
editionImageLookup.put(pc.getEdition(), editionHasImage);
|
editionImageLookup.put(pc.getEdition(), editionHasImage);
|
||||||
|
if (editionHasImage){
|
||||||
|
File f = new File(CACHE_CARD_PICS_DIR + setFolder); // no need to check this, otherwise editionHasImage would be false!
|
||||||
|
HashSet<String> setFolderContent = new HashSet<>();
|
||||||
|
for (String filename : Arrays.asList(f.list())) {
|
||||||
|
// TODO: should this use FILE_EXTENSIONS ?
|
||||||
|
if (!filename.endsWith(".jpg") && !filename.endsWith(".png"))
|
||||||
|
continue; // not image - not interested
|
||||||
|
setFolderContent.add(filename.split("\\.")[0]); // get rid of any full or fullborder
|
||||||
}
|
}
|
||||||
|
cachedContent.put(setFolder, setFolderContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String[] keyParts = pc.getImageKeyFromSet().split(File.separator);
|
||||||
|
HashSet<String> content = cachedContent.getOrDefault(keyParts[0], null);
|
||||||
//avoid checking for file if edition doesn't have any images
|
//avoid checking for file if edition doesn't have any images
|
||||||
return editionHasImage && getImageFile(ImageUtil.getImageKey(pc, false, true)) != null;
|
return editionHasImage && hitCache(content, keyParts[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean hitCache(HashSet<String> cache, String filename){
|
||||||
|
if (cache == null || cache.isEmpty())
|
||||||
|
return false;
|
||||||
|
final String keyPrefix = filename.split("\\.")[0];
|
||||||
|
return cache.contains(keyPrefix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -90,6 +90,12 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
this.collectorNumber = collectorNumber;
|
this.collectorNumber = collectorNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String compose(String cardName, boolean isFoil){
|
||||||
|
if (isFoil)
|
||||||
|
return cardName+foilSuffix;
|
||||||
|
return cardName;
|
||||||
|
}
|
||||||
|
|
||||||
public static String compose(String cardName, String setCode) {
|
public static String compose(String cardName, String setCode) {
|
||||||
setCode = setCode != null ? setCode : "";
|
setCode = setCode != null ? setCode : "";
|
||||||
cardName = cardName != null ? cardName : "";
|
cardName = cardName != null ? cardName : "";
|
||||||
@@ -135,7 +141,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isArtIndex(String s) {
|
private static boolean isArtIndex(String s) {
|
||||||
return StringUtils.isNumeric(s) && s.length() == 1;
|
return StringUtils.isNumeric(s) && s.length() <= 2 ; // only artIndex between 1-99
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSetCode(String s) {
|
private static boolean isSetCode(String s) {
|
||||||
@@ -462,15 +468,15 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. Card lookup in edition with specified filter didn't work.
|
// 2. Card lookup in edition with specified filter didn't work.
|
||||||
// So now check whether the cards exists in the DB first,
|
// So now check whether the cards exist in the DB first,
|
||||||
// and select pick the card based on current SetPreference policy as a fallback
|
// and select pick the card based on current SetPreference policy as a fallback
|
||||||
Collection<PaperCard> cards = getAllCards(request.cardName);
|
Collection<PaperCard> cards = getAllCards(request.cardName);
|
||||||
if (cards == null)
|
if (cards.isEmpty()) // Never null being this a view in MultiMap
|
||||||
return null;
|
return null;
|
||||||
// Either No Edition has been specified OR as a fallback in case of any error!
|
// Either No Edition has been specified OR as a fallback in case of any error!
|
||||||
// get card using the default card art preference
|
// get card using the default card art preference
|
||||||
result = getCardFromEditions(request.cardName, this.defaultCardArtPreference, request.artIndex);
|
String cardRequest = CardRequest.compose(request.cardName, request.isFoil);
|
||||||
return result != null && request.isFoil ? result.getFoiled() : result;
|
return getCardFromEditions(cardRequest, this.defaultCardArtPreference, request.artIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -510,9 +516,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
cardName = cardNameRequest.cardName;
|
cardName = cardNameRequest.cardName;
|
||||||
isFoil = isFoil || cardNameRequest.isFoil;
|
isFoil = isFoil || cardNameRequest.isFoil;
|
||||||
|
|
||||||
List<PaperCard> cards = getAllCards(cardName);
|
List<PaperCard> candidates = getAllCards(cardName, new Predicate<PaperCard>() {
|
||||||
// Look for Code or Code2 to make the retrieval more robust
|
|
||||||
List<PaperCard> candidates = Lists.newArrayList(Iterables.filter(cards, new Predicate<PaperCard>() {
|
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(PaperCard c) {
|
public boolean apply(PaperCard c) {
|
||||||
boolean artIndexFilter = true;
|
boolean artIndexFilter = true;
|
||||||
@@ -526,21 +530,17 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
collectorNumberFilter = (c.getCollectorNumber().equals(collectorNumber));
|
collectorNumberFilter = (c.getCollectorNumber().equals(collectorNumber));
|
||||||
return setFilter && artIndexFilter && collectorNumberFilter;
|
return setFilter && artIndexFilter && collectorNumberFilter;
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
if (candidates.isEmpty())
|
if (candidates.isEmpty())
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
PaperCard candidate = candidates.get(0);
|
Iterator<PaperCard> candidatesIterator = candidates.iterator();
|
||||||
|
PaperCard candidate = candidatesIterator.next();
|
||||||
// Before returning make sure that actual candidate has Image.
|
// Before returning make sure that actual candidate has Image.
|
||||||
// If not, try to replace current candidate with one having image,
|
// If not, try to replace current candidate with one having image,
|
||||||
// so to align this implementation with old one.
|
// so to align this implementation with old one.
|
||||||
if (!candidate.hasImage()) {
|
while (!candidate.hasImage() && candidatesIterator.hasNext()) {
|
||||||
for (PaperCard card : candidates) {
|
candidate = candidatesIterator.next();
|
||||||
if (card.hasImage()) {
|
|
||||||
candidate = card;
|
|
||||||
break; // found, ready to go
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return isFoil ? candidate.getFoiled() : candidate;
|
return isFoil ? candidate.getFoiled() : candidate;
|
||||||
}
|
}
|
||||||
@@ -567,8 +567,8 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PaperCard getCardFromEditions(final String cardName, final CardArtPreference artPreference, int artIndex) {
|
public PaperCard getCardFromEditions(final String cardInfo, final CardArtPreference artPreference, int artIndex) {
|
||||||
return this.tryToGetCardFromEditions(cardName, artPreference, artIndex);
|
return this.tryToGetCardFromEditions(cardInfo, artPreference, artIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -634,38 +634,52 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
if (cr.artIndex != artIndex && artIndex > IPaperCard.DEFAULT_ART_INDEX )
|
if (cr.artIndex != artIndex && artIndex > IPaperCard.DEFAULT_ART_INDEX )
|
||||||
cr.artIndex = artIndex; // 2nd cond. is to verify that some actual value has been passed in.
|
cr.artIndex = artIndex; // 2nd cond. is to verify that some actual value has been passed in.
|
||||||
|
|
||||||
List<PaperCard> cards = getAllCards(cr.cardName);
|
List<PaperCard> cards;
|
||||||
if (releaseDate != null) {
|
if (releaseDate != null) {
|
||||||
cards = Lists.newArrayList(Iterables.filter(cards, new Predicate<PaperCard>() {
|
cards = getAllCards(cr.cardName, new Predicate<PaperCard>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(PaperCard c) {
|
public boolean apply(PaperCard c) {
|
||||||
|
if (c.getArtIndex() != cr.artIndex)
|
||||||
|
return false; // not interested anyway!
|
||||||
CardEdition ed = editions.get(c.getEdition());
|
CardEdition ed = editions.get(c.getEdition());
|
||||||
|
if (ed == null) return false;
|
||||||
if (releasedBeforeFlag)
|
if (releasedBeforeFlag)
|
||||||
return ed.getDate().before(releaseDate);
|
return ed.getDate().before(releaseDate);
|
||||||
else
|
else
|
||||||
return ed.getDate().after(releaseDate);
|
return ed.getDate().after(releaseDate);
|
||||||
}
|
}
|
||||||
}));
|
});
|
||||||
|
} else // filter candidates based on requested artIndex
|
||||||
|
cards = getAllCards(cr.cardName, new Predicate<PaperCard>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(PaperCard card) {
|
||||||
|
return card.getArtIndex() == cr.artIndex;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (cards.size() == 0) // Don't bother continuing! No card has been found!
|
if (cards.size() == 1) // if only one candidate, there much else we should do
|
||||||
return null;
|
return cr.isFoil ? cards.get(0).getFoiled() : cards.get(0);
|
||||||
|
|
||||||
/* 2. Retrieve cards based of [Frame]Set Preference
|
/* 2. Retrieve cards based of [Frame]Set Preference
|
||||||
================================================ */
|
================================================ */
|
||||||
|
|
||||||
// Collect the list of all editions found for target card
|
// Collect the list of all editions found for target card
|
||||||
LinkedHashSet<CardEdition> cardEditions = new LinkedHashSet<>();
|
List<CardEdition> cardEditions = new ArrayList<>();
|
||||||
|
Map<String, PaperCard> candidatesCard = new HashMap<>();
|
||||||
for (PaperCard card : cards) {
|
for (PaperCard card : cards) {
|
||||||
String setCode = card.getEdition();
|
String setCode = card.getEdition();
|
||||||
|
CardEdition ed;
|
||||||
if (setCode.equals(CardEdition.UNKNOWN.getCode()))
|
if (setCode.equals(CardEdition.UNKNOWN.getCode()))
|
||||||
cardEditions.add(CardEdition.UNKNOWN);
|
ed = CardEdition.UNKNOWN;
|
||||||
else {
|
else
|
||||||
CardEdition ed = editions.get(card.getEdition());
|
ed = editions.get(card.getEdition());
|
||||||
if (ed != null)
|
if (ed != null) {
|
||||||
cardEditions.add(ed);
|
cardEditions.add(ed);
|
||||||
|
candidatesCard.put(setCode, card);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cardEditions.isEmpty())
|
||||||
|
return null; // nothing to do
|
||||||
|
|
||||||
// Filter Cards Editions based on set preferences
|
// Filter Cards Editions based on set preferences
|
||||||
List<CardEdition> acceptedEditions = Lists.newArrayList(Iterables.filter(cardEditions, new Predicate<CardEdition>() {
|
List<CardEdition> acceptedEditions = Lists.newArrayList(Iterables.filter(cardEditions, new Predicate<CardEdition>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -681,26 +695,24 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
If this happens, we won't try to iterate over an empty list. Instead, we will fall back
|
If this happens, we won't try to iterate over an empty list. Instead, we will fall back
|
||||||
to original lists of editions (unfiltered, of course) AND STILL sorted according to chosen art preference.
|
to original lists of editions (unfiltered, of course) AND STILL sorted according to chosen art preference.
|
||||||
*/
|
*/
|
||||||
if (acceptedEditions.size() == 0)
|
if (acceptedEditions.isEmpty())
|
||||||
acceptedEditions.addAll(cardEditions);
|
acceptedEditions.addAll(cardEditions);
|
||||||
|
|
||||||
|
if (acceptedEditions.size() > 1) {
|
||||||
Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date
|
Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date
|
||||||
if (artPref.latestFirst)
|
if (artPref.latestFirst)
|
||||||
Collections.reverse(acceptedEditions); // newest editions first
|
Collections.reverse(acceptedEditions); // newest editions first
|
||||||
PaperCard candidate = null;
|
}
|
||||||
for (CardEdition ed : acceptedEditions) {
|
|
||||||
PaperCard cardFromSet = getCardFromSet(cr.cardName, ed, cr.artIndex, cr.isFoil);
|
|
||||||
if (candidate == null && cardFromSet != null)
|
|
||||||
// save the first card found, as the last backup in case no other candidate *with image* will be found
|
|
||||||
candidate = cardFromSet;
|
|
||||||
|
|
||||||
if (cardFromSet != null && cardFromSet.hasImage()) {
|
final Iterator<CardEdition> editionIterator = acceptedEditions.iterator();
|
||||||
candidate = cardFromSet;
|
CardEdition ed = editionIterator.next();
|
||||||
break; // we're done here: found card **with Image**
|
PaperCard candidate = candidatesCard.get(ed.getCode());
|
||||||
|
while (!candidate.hasImage() && editionIterator.hasNext()) {
|
||||||
|
ed = editionIterator.next();
|
||||||
|
candidate = candidatesCard.get(ed.getCode());
|
||||||
}
|
}
|
||||||
}
|
//If any, we're sure that at least one candidate is always returned despite it having any image
|
||||||
//If any, we're sure that at least one candidate is always returned nevertheless it has image or not
|
return cr.isFoil ? candidate.getFoiled() : candidate;
|
||||||
return candidate; // any foil request already handled in getCardFromSet
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -716,18 +728,16 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getArtCount(String cardName, String setName) {
|
public int getArtCount(String cardName, String setCode) {
|
||||||
if (cardName == null || setName == null)
|
if (cardName == null || setCode == null)
|
||||||
return 0;
|
return 0;
|
||||||
Collection<PaperCard> cards = getAllCards(cardName);
|
Collection<PaperCard> cardsInSet = getAllCards(cardName, new Predicate<PaperCard>() {
|
||||||
if (null == cards || cards.size() == 0)
|
@Override
|
||||||
return 0;
|
public boolean apply(PaperCard card) {
|
||||||
int artCount = 0;
|
return card.getEdition().equalsIgnoreCase(setCode);
|
||||||
for (PaperCard pc : cards) {
|
|
||||||
if (pc.getEdition().equalsIgnoreCase(setName))
|
|
||||||
artCount++;
|
|
||||||
}
|
}
|
||||||
return artCount;
|
});
|
||||||
|
return cardsInSet.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns a list of all cards from their respective latest (or preferred) editions
|
// returns a list of all cards from their respective latest (or preferred) editions
|
||||||
@@ -834,6 +844,11 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
return Lists.newArrayList(Iterables.filter(getAllCards(), predicate));
|
return Lists.newArrayList(Iterables.filter(getAllCards(), predicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PaperCard> getAllCards(final String cardName, Predicate<PaperCard> predicate){
|
||||||
|
return Lists.newArrayList(Iterables.filter(getAllCards(cardName), predicate));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a modifiable list of cards matching the given predicate
|
* Returns a modifiable list of cards matching the given predicate
|
||||||
*/
|
*/
|
||||||
@@ -1006,29 +1021,33 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
|||||||
// 1. generate all paper cards from edition data we have (either explicit, or found in res/editions, or add to unknown edition)
|
// 1. generate all paper cards from edition data we have (either explicit, or found in res/editions, or add to unknown edition)
|
||||||
List<PaperCard> paperCards = new ArrayList<>();
|
List<PaperCard> paperCards = new ArrayList<>();
|
||||||
if (null == whenItWasPrinted || whenItWasPrinted.isEmpty()) {
|
if (null == whenItWasPrinted || whenItWasPrinted.isEmpty()) {
|
||||||
// TODO Not performant Each time we "putCard" we loop through ALL CARDS IN ALL editions
|
// @friarsol: Not performant Each time we "putCard" we loop through ALL CARDS IN ALL editions
|
||||||
|
// @leriomaggio: DONE! re-using here the same strategy implemented for lazy-loading!
|
||||||
for (CardEdition e : editions.getOrderedEditions()) {
|
for (CardEdition e : editions.getOrderedEditions()) {
|
||||||
int artIdx = IPaperCard.DEFAULT_ART_INDEX;
|
int artIdx = IPaperCard.DEFAULT_ART_INDEX;
|
||||||
for (CardInSet cis : e.getAllCardsInSet()) {
|
for (CardInSet cis : e.getCardInSet(cardName))
|
||||||
if (!cis.name.equals(cardName)) {
|
paperCards.add(new PaperCard(rules, e.getCode(), cis.rarity, artIdx++, false,
|
||||||
continue;
|
cis.collectorNumber, cis.artistName));
|
||||||
}
|
|
||||||
paperCards.add(new PaperCard(rules, e.getCode(), cis.rarity, artIdx++));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
String lastEdition = null;
|
String lastEdition = null;
|
||||||
int artIdx = 0;
|
int artIdx = 0;
|
||||||
for (Pair<String, CardRarity> tuple : whenItWasPrinted) {
|
for (Pair<String, CardRarity> tuple : whenItWasPrinted) {
|
||||||
if (!tuple.getKey().equals(lastEdition)) {
|
if (!tuple.getKey().equals(lastEdition)) {
|
||||||
artIdx = IPaperCard.DEFAULT_ART_INDEX;
|
artIdx = IPaperCard.DEFAULT_ART_INDEX; // reset artIndex
|
||||||
lastEdition = tuple.getKey();
|
lastEdition = tuple.getKey();
|
||||||
}
|
}
|
||||||
CardEdition ed = editions.get(lastEdition);
|
CardEdition ed = editions.get(lastEdition);
|
||||||
if (null == ed) {
|
if (ed == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
paperCards.add(new PaperCard(rules, lastEdition, tuple.getValue(), artIdx++));
|
List<CardInSet> cardsInSet = ed.getCardInSet(cardName);
|
||||||
|
if (cardsInSet.isEmpty())
|
||||||
|
continue;
|
||||||
|
int cardInSetIndex = Math.max(artIdx-1, 0); // make sure doesn't go below zero
|
||||||
|
CardInSet cds = cardsInSet.get(cardInSetIndex); // use ArtIndex to get the right Coll. Number
|
||||||
|
paperCards.add(new PaperCard(rules, lastEdition, tuple.getValue(), artIdx++, false,
|
||||||
|
cds.collectorNumber, cds.artistName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (paperCards.isEmpty()) {
|
if (paperCards.isEmpty()) {
|
||||||
|
|||||||
@@ -373,6 +373,13 @@ public final class CardEdition implements Comparable<CardEdition> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ListMultimap<String, CardInSet> cardsInSetLookupMap = null;
|
private ListMultimap<String, CardInSet> cardsInSetLookupMap = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all the CardInSet instances with the input card name.
|
||||||
|
* @param cardName Name of the Card to look for.
|
||||||
|
* @return A List of all the CardInSet instances for a given name.
|
||||||
|
* If not fount, an Empty sequence (view) will be returned instead!
|
||||||
|
*/
|
||||||
public List<CardInSet> getCardInSet(String cardName){
|
public List<CardInSet> getCardInSet(String cardName){
|
||||||
if (cardsInSetLookupMap == null) {
|
if (cardsInSetLookupMap == null) {
|
||||||
// initialise
|
// initialise
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ public interface ICardDatabase extends Iterable<PaperCard> {
|
|||||||
Collection<PaperCard> getAllCards();
|
Collection<PaperCard> getAllCards();
|
||||||
Collection<PaperCard> getAllCards(String cardName);
|
Collection<PaperCard> getAllCards(String cardName);
|
||||||
Collection<PaperCard> getAllCards(Predicate<PaperCard> predicate);
|
Collection<PaperCard> getAllCards(Predicate<PaperCard> predicate);
|
||||||
|
Collection<PaperCard> getAllCards(String cardName,Predicate<PaperCard> predicate);
|
||||||
Collection<PaperCard> getAllCards(CardEdition edition);
|
Collection<PaperCard> getAllCards(CardEdition edition);
|
||||||
Collection<PaperCard> getUniqueCards();
|
Collection<PaperCard> getUniqueCards();
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public interface IPaperCard extends InventoryItem, Serializable {
|
|||||||
String NO_COLLECTOR_NUMBER = "N.A."; // Placeholder for No-Collection number available
|
String NO_COLLECTOR_NUMBER = "N.A."; // Placeholder for No-Collection number available
|
||||||
int DEFAULT_ART_INDEX = 1;
|
int DEFAULT_ART_INDEX = 1;
|
||||||
int NO_ART_INDEX = -1; // Placeholder when NO ArtIndex is Specified
|
int NO_ART_INDEX = -1; // Placeholder when NO ArtIndex is Specified
|
||||||
|
String NO_ARTIST_NAME = "";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of filters based on CardPrinted values.
|
* Number of filters based on CardPrinted values.
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import forge.card.CardEdition;
|
|||||||
import forge.card.CardRarity;
|
import forge.card.CardRarity;
|
||||||
import forge.card.CardRules;
|
import forge.card.CardRules;
|
||||||
import forge.util.CardTranslation;
|
import forge.util.CardTranslation;
|
||||||
|
import forge.util.ImageUtil;
|
||||||
import forge.util.Localizer;
|
import forge.util.Localizer;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
By default the attribute is marked as "unset" so that it could be retrieved and set.
|
By default the attribute is marked as "unset" so that it could be retrieved and set.
|
||||||
(see getCollectorNumber())
|
(see getCollectorNumber())
|
||||||
*/
|
*/
|
||||||
private String collectorNumber = null;
|
private String collectorNumber;
|
||||||
private final String artist;
|
private final String artist;
|
||||||
private final int artIndex;
|
private final int artIndex;
|
||||||
private final boolean foil;
|
private final boolean foil;
|
||||||
@@ -75,18 +76,6 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCollectorNumber() {
|
public String getCollectorNumber() {
|
||||||
/* The collectorNumber attribute is managed in a property-like fashion.
|
|
||||||
By default it is marked as "unset" (-1), which integrates with all constructors
|
|
||||||
invocations not including this as an extra parameter. In this way, the new
|
|
||||||
attribute could be added to the API with minimum disruption to code
|
|
||||||
throughout the other packages.
|
|
||||||
If "unset", the corresponding collectorNumber will be retrieved
|
|
||||||
from the corresponding CardEdition (see retrieveCollectorNumber)
|
|
||||||
* */
|
|
||||||
if (collectorNumber == null) {
|
|
||||||
collectorNumber = this.retrieveCollectorNumber();
|
|
||||||
}
|
|
||||||
|
|
||||||
return collectorNumber;
|
return collectorNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,6 +141,13 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
return hasImage;
|
return hasImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String imageKeyFromSet = null;
|
||||||
|
public String getImageKeyFromSet() {
|
||||||
|
if (this.imageKeyFromSet == null)
|
||||||
|
this.imageKeyFromSet = ImageUtil.getImageKey(this, false, true);
|
||||||
|
return imageKeyFromSet;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lambda to get rules for selects from list of printed cards.
|
* Lambda to get rules for selects from list of printed cards.
|
||||||
*/
|
*/
|
||||||
@@ -169,15 +165,12 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
};
|
};
|
||||||
|
|
||||||
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0){
|
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0){
|
||||||
this(rules0, edition0, rarity0, IPaperCard.DEFAULT_ART_INDEX);
|
this(rules0, edition0, rarity0, IPaperCard.DEFAULT_ART_INDEX, false,
|
||||||
|
IPaperCard.NO_COLLECTOR_NUMBER, IPaperCard.NO_ARTIST_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, final int artIndex0) {
|
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0,
|
||||||
this(rules0, edition0, rarity0, artIndex0, false, "");
|
final int artIndex0, final boolean foil0, final String collectorNumber0, final String artist0) {
|
||||||
}
|
|
||||||
|
|
||||||
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, final int artIndex0,
|
|
||||||
final boolean foil0, final String artist0) {
|
|
||||||
if (rules0 == null || edition0 == null || rarity0 == null) {
|
if (rules0 == null || edition0 == null || rarity0 == null) {
|
||||||
throw new IllegalArgumentException("Cannot create card without rules, edition or rarity");
|
throw new IllegalArgumentException("Cannot create card without rules, edition or rarity");
|
||||||
}
|
}
|
||||||
@@ -187,16 +180,8 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
artIndex = Math.max(artIndex0, IPaperCard.DEFAULT_ART_INDEX);
|
artIndex = Math.max(artIndex0, IPaperCard.DEFAULT_ART_INDEX);
|
||||||
foil = foil0;
|
foil = foil0;
|
||||||
rarity = rarity0;
|
rarity = rarity0;
|
||||||
artist = (artist0 != null ? artist0 : "");
|
artist = (artist0 != null ? artist0 : IPaperCard.NO_ARTIST_NAME);
|
||||||
}
|
collectorNumber = (collectorNumber0 != null) && (collectorNumber0.length() > 0) ? collectorNumber0 : IPaperCard.NO_COLLECTOR_NUMBER;
|
||||||
|
|
||||||
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0,
|
|
||||||
final int artIndex0, final boolean foil0, final String collectorNumber0, final String artist) {
|
|
||||||
this(rules0, edition0, rarity0, artIndex0, foil0, artist);
|
|
||||||
if ((collectorNumber0 == null) || (collectorNumber0.length() == 0))
|
|
||||||
collectorNumber = IPaperCard.NO_COLLECTOR_NUMBER;
|
|
||||||
else
|
|
||||||
collectorNumber = collectorNumber0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Want this class to be a key for HashTable
|
// Want this class to be a key for HashTable
|
||||||
@@ -268,10 +253,14 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
return CardEdition.CardInSet.getSortableCollectorNumber(collectorNumber);
|
return CardEdition.CardInSet.getSortableCollectorNumber(collectorNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String sortableCNKey = null;
|
||||||
public String getCollectorNumberSortingKey(){
|
public String getCollectorNumberSortingKey(){
|
||||||
|
if (sortableCNKey == null) {
|
||||||
// Hardly the case, but just invoke getter rather than direct
|
// Hardly the case, but just invoke getter rather than direct
|
||||||
// attribute to be sure that collectorNumber has been retrieved already!
|
// attribute to be sure that collectorNumber has been retrieved already!
|
||||||
return makeCollectorNumberSortingKey(getCollectorNumber());
|
sortableCNKey = makeCollectorNumberSortingKey(getCollectorNumber());
|
||||||
|
}
|
||||||
|
return sortableCNKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -309,32 +298,6 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
|||||||
rarity = pc.getRarity();
|
rarity = pc.getRarity();
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: @leriomaggio - remember to get rid of this method once and for all :)
|
|
||||||
private String retrieveCollectorNumber() {
|
|
||||||
StaticData data = StaticData.instance();
|
|
||||||
CardEdition edition = data.getEditions().get(this.edition);
|
|
||||||
if (edition == null) {
|
|
||||||
edition = data.getCustomEditions().get(this.edition);
|
|
||||||
if (edition == null) // don't bother continuing - non-existing card!
|
|
||||||
return NO_COLLECTOR_NUMBER;
|
|
||||||
}
|
|
||||||
int artIndexCount = 0;
|
|
||||||
String collectorNumberInEdition = "";
|
|
||||||
for (CardEdition.CardInSet card : edition.getAllCardsInSet()) {
|
|
||||||
if (card.name.equalsIgnoreCase(this.name)) {
|
|
||||||
artIndexCount += 1;
|
|
||||||
if (artIndexCount == this.artIndex) {
|
|
||||||
collectorNumberInEdition = card.collectorNumber;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// CardEdition stores collectorNumber as a String, which is null if there isn't any.
|
|
||||||
// In this case, the NO_COLLECTOR_NUMBER value (i.e. 0) is returned.
|
|
||||||
return ((collectorNumberInEdition != null) && (collectorNumberInEdition.length() > 0)) ?
|
|
||||||
collectorNumberInEdition : NO_COLLECTOR_NUMBER;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getImageKey(boolean altState) {
|
public String getImageKey(boolean altState) {
|
||||||
String imageKey = ImageKeys.CARD_PREFIX + name + CardDb.NameSetSeparator
|
String imageKey = ImageKeys.CARD_PREFIX + name + CardDb.NameSetSeparator
|
||||||
|
|||||||
@@ -78,8 +78,10 @@ public final class FileUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isDirectoryWithFiles(final String path) {
|
public static boolean isDirectoryWithFiles(final String path) {
|
||||||
|
if (path == null) return false;
|
||||||
final File f = new File(path);
|
final File f = new File(path);
|
||||||
return f.exists() && f.isDirectory() && f.list().length > 0;
|
final String[] fileList = f.list();
|
||||||
|
return fileList!=null && fileList.length > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean ensureDirectoryExists(final String path) {
|
public static boolean ensureDirectoryExists(final String path) {
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class ImageUtil {
|
|||||||
int artIdx = cp.getArtIndex() - 1;
|
int artIdx = cp.getArtIndex() - 1;
|
||||||
if (hasManyPictures) {
|
if (hasManyPictures) {
|
||||||
if (cntPictures <= artIdx) // prevent overflow
|
if (cntPictures <= artIdx) // prevent overflow
|
||||||
artIdx = cntPictures == 0 ? 0 : artIdx % cntPictures;
|
artIdx = artIdx % cntPictures;
|
||||||
s.append(artIdx + 1);
|
s.append(artIdx + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ public class ImageCache {
|
|||||||
if (useArtCrop) {
|
if (useArtCrop) {
|
||||||
if (ipc != null && ipc.getRules().getSplitType() == CardSplitType.Flip) {
|
if (ipc != null && ipc.getRules().getSplitType() == CardSplitType.Flip) {
|
||||||
// Art crop will always use front face as image key for flip cards
|
// Art crop will always use front face as image key for flip cards
|
||||||
imageKey = ImageUtil.getImageKey((PaperCard) ipc, false, true);
|
imageKey = ((PaperCard) ipc).getImageKeyFromSet(); // ImageUtil.getImageKey((PaperCard) ipc, false, true);
|
||||||
}
|
}
|
||||||
imageKey = TextUtil.fastReplace(imageKey, ".full", ".artcrop");
|
imageKey = TextUtil.fastReplace(imageKey, ".full", ".artcrop");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -536,13 +536,7 @@ public abstract class ACEditorBase<TItem extends InventoryItem, TModel extends D
|
|||||||
CardManager cardManager = (CardManager) CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckManager();
|
CardManager cardManager = (CardManager) CDeckEditorUI.SINGLETON_INSTANCE.getCurrentEditorController().getDeckManager();
|
||||||
PaperCard existingCard = cardManager.getSelectedItem();
|
PaperCard existingCard = cardManager.getSelectedItem();
|
||||||
// make a foiled version based on the original
|
// make a foiled version based on the original
|
||||||
PaperCard foiledCard = new PaperCard(
|
PaperCard foiledCard = existingCard.getFoiled();
|
||||||
existingCard.getRules(),
|
|
||||||
existingCard.getEdition(),
|
|
||||||
existingCard.getRarity(),
|
|
||||||
existingCard.getArtIndex(),
|
|
||||||
true,
|
|
||||||
existingCard.getArtist());
|
|
||||||
// remove *quantity* instances of existing card
|
// remove *quantity* instances of existing card
|
||||||
CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, quantity);
|
CDeckEditorUI.SINGLETON_INSTANCE.removeSelectedCards(false, quantity);
|
||||||
// add *quantity* into the deck and set them as selected
|
// add *quantity* into the deck and set them as selected
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package forge.card;
|
||||||
|
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import org.testng.annotations.BeforeMethod;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import static org.testng.Assert.assertNotNull;
|
||||||
|
|
||||||
|
public class CardDbPerformanceTests extends CardDbTestCase {
|
||||||
|
|
||||||
|
private Set<String> fullDbCardNames = new TreeSet<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@BeforeMethod
|
||||||
|
public void setup() {
|
||||||
|
super.setup();
|
||||||
|
Collection<PaperCard> uniqueCards = this.cardDb.getUniqueCards();
|
||||||
|
for (PaperCard card : uniqueCards)
|
||||||
|
this.fullDbCardNames.add(card.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBenchmarkFullDbGetCardLegacyImplementation() {
|
||||||
|
int nRuns = 100;
|
||||||
|
long averageTime = 0;
|
||||||
|
long minTime = 10000; // 10 secs
|
||||||
|
long maxTime = 0;
|
||||||
|
for (int r = 1; r <= nRuns; r++) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
for (String name : this.fullDbCardNames) {
|
||||||
|
PaperCard card = this.legacyCardDb.getCard(name);
|
||||||
|
assertNotNull(card);
|
||||||
|
}
|
||||||
|
long timeRun = System.currentTimeMillis() - start;
|
||||||
|
averageTime += timeRun;
|
||||||
|
if (timeRun < minTime)
|
||||||
|
minTime = timeRun;
|
||||||
|
if (timeRun > maxTime)
|
||||||
|
maxTime = timeRun;
|
||||||
|
}
|
||||||
|
System.out.println("[LEGACY] Total Time (in sec): " + ((double) averageTime)/ 1000);
|
||||||
|
System.out.println("[LEGACY] Average Time (in sec): " + ((double) averageTime / nRuns)/ 1000);
|
||||||
|
System.out.println("[LEGACY] Best Time (in sec): " + ((double) minTime)/ 1000);
|
||||||
|
System.out.println("[LEGACY] Worst Time (in sec): " + ((double) maxTime)/ 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBenchmarkFullDbGetCardNewDbImplementation() {
|
||||||
|
int nRuns = 100;
|
||||||
|
long averageTime = 0;
|
||||||
|
long minTime = 10000; // 10 secs
|
||||||
|
long maxTime = 0;
|
||||||
|
for (int r = 1; r <= nRuns; r++) {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
for (String name : this.fullDbCardNames) {
|
||||||
|
PaperCard card = this.cardDb.getCard(name);
|
||||||
|
assertNotNull(card);
|
||||||
|
}
|
||||||
|
long timeRun = System.currentTimeMillis() - start;
|
||||||
|
averageTime += timeRun;
|
||||||
|
if (timeRun < minTime)
|
||||||
|
minTime = timeRun;
|
||||||
|
if (timeRun > maxTime)
|
||||||
|
maxTime = timeRun;
|
||||||
|
}
|
||||||
|
System.out.println("[NEW] Total Time (in sec): " + ((double) averageTime)/ 1000);
|
||||||
|
System.out.println("[NEW] Average Time (in sec): " + ((double) averageTime / nRuns)/ 1000);
|
||||||
|
System.out.println("[NEW] Best Time (in sec): " + ((double) minTime)/ 1000);
|
||||||
|
System.out.println("[NEW] Worst Time (in sec): " + ((double) maxTime)/ 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetCardFullDbNewImplementationToProfile(){
|
||||||
|
for (String name : this.fullDbCardNames) {
|
||||||
|
PaperCard card = this.cardDb.getCard(name);
|
||||||
|
assertNotNull(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetCardFullDbLegacyImplementationToProfile(){
|
||||||
|
for (String name : this.fullDbCardNames) {
|
||||||
|
PaperCard card = this.legacyCardDb.getCard(name);
|
||||||
|
assertNotNull(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package forge.card;
|
package forge.card;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
@@ -10,7 +11,10 @@ import org.testng.annotations.Test;
|
|||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.testng.Assert.*;
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
@@ -101,6 +105,44 @@ public class CardDbTestCase extends ForgeCardMockTestCase {
|
|||||||
this.legacyCardDb = new LegacyCardDb(data.getCommonCards().getAllCards(), data.getEditions());
|
this.legacyCardDb = new LegacyCardDb(data.getCommonCards().getAllCards(), data.getEditions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEST FOR GET ALL CARDS
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAllCardsWithName(){
|
||||||
|
List<PaperCard> allCounterSpellPrints = this.cardDb.getAllCards(this.cardNameCounterspell);
|
||||||
|
assertNotNull(allCounterSpellPrints);
|
||||||
|
for (PaperCard card : allCounterSpellPrints)
|
||||||
|
assertEquals(card.getName(), this.cardNameCounterspell);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetAllCardsThatWerePrintedInSets(){
|
||||||
|
List<String> allowedSets = new ArrayList<>();
|
||||||
|
allowedSets.add(this.latestArtShivanDragonEdition);
|
||||||
|
Predicate<PaperCard> wasPrinted = (Predicate<PaperCard>) this.cardDb.wasPrintedInSets(allowedSets);
|
||||||
|
List<PaperCard> allCardsInSet = this.cardDb.getAllCards(wasPrinted);
|
||||||
|
assertNotNull(allCardsInSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test void testGetAllCardsOfaGivenNameAndLegalInSets(){
|
||||||
|
List<String> allowedSets = new ArrayList<>(Arrays.asList(this.editionsCounterspell));
|
||||||
|
Predicate<PaperCard> printedInSets = (Predicate<PaperCard>) this.cardDb.wasPrintedInSets(allowedSets);
|
||||||
|
List<PaperCard> allCounterSpellsInSets = this.cardDb.getAllCards(this.cardNameCounterspell, printedInSets);
|
||||||
|
assertNotNull(allCounterSpellsInSets);
|
||||||
|
assertTrue(allCounterSpellsInSets.size() > 0);
|
||||||
|
assertTrue(allCounterSpellsInSets.size() > 1);
|
||||||
|
for (PaperCard card : allCounterSpellsInSets) {
|
||||||
|
assertEquals(card.getName(), this.cardNameCounterspell);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEST FOR CARD RETRIEVAL METHODS
|
||||||
|
*/
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGetCardByName() {
|
public void testGetCardByName() {
|
||||||
PaperCard legacyCard = this.legacyCardDb.getCard(cardNameShivanDragon);
|
PaperCard legacyCard = this.legacyCardDb.getCard(cardNameShivanDragon);
|
||||||
@@ -2019,6 +2061,30 @@ public class CardDbTestCase extends ForgeCardMockTestCase {
|
|||||||
assertEquals(legacyAinokCard, ainokCard);
|
assertEquals(legacyAinokCard, ainokCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetIslandsFromEditionsWithSpecificArtIndex(){
|
||||||
|
String cardName = "Island";
|
||||||
|
assertEquals(this.cardDb.getCardArtPreference(), CardDb.CardArtPreference.LATEST_ART_ALL_EDITIONS);
|
||||||
|
PaperCard islandLatest = this.cardDb.getCardFromEditions(cardName, CardDb.CardArtPreference.LATEST_ART_ALL_EDITIONS, 12);
|
||||||
|
assertNotNull(islandLatest);
|
||||||
|
assertEquals(islandLatest.getName(), "Island");
|
||||||
|
assertEquals(islandLatest.getEdition(), "SLD");
|
||||||
|
assertEquals(islandLatest.getArtIndex(), 12);
|
||||||
|
|
||||||
|
// PALP
|
||||||
|
PaperCard islandOriginal = this.cardDb.getCardFromEditions(cardName, CardDb.CardArtPreference.ORIGINAL_ART_CORE_EXPANSIONS_REPRINT_ONLY, 12);
|
||||||
|
assertNotNull(islandOriginal);
|
||||||
|
assertEquals(islandOriginal.getName(), "Island");
|
||||||
|
assertEquals(islandOriginal.getEdition(), "SLD");
|
||||||
|
assertEquals(islandOriginal.getArtIndex(), 12);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMaxArtCountForBasicLand(){
|
||||||
|
int maxArtIndex = this.cardDb.getMaxArtIndex("Island");
|
||||||
|
assertEquals(maxArtIndex, 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ public class CardRequestTestCase {
|
|||||||
request = CardRequest.fromString(requestString);
|
request = CardRequest.fromString(requestString);
|
||||||
assertEquals(request.cardName, cardName);
|
assertEquals(request.cardName, cardName);
|
||||||
assertEquals(request.edition, edition);
|
assertEquals(request.edition, edition);
|
||||||
assertEquals(request.artIndex, IPaperCard.DEFAULT_ART_INDEX);
|
assertEquals(request.artIndex, 20);
|
||||||
assertEquals(request.collectorNumber, IPaperCard.NO_COLLECTOR_NUMBER);
|
assertEquals(request.collectorNumber, IPaperCard.NO_COLLECTOR_NUMBER);
|
||||||
|
|
||||||
|
|
||||||
@@ -215,4 +215,15 @@ public class CardRequestTestCase {
|
|||||||
assertNotEquals(request.artIndex, newRequest.artIndex);
|
assertNotEquals(request.artIndex, newRequest.artIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreatingCardRequestWithArtIndexGreaterThanNine(){
|
||||||
|
String requestString = CardRequest.compose("Island", "SLD", 13);
|
||||||
|
CardRequest request = CardRequest.fromString(requestString);
|
||||||
|
|
||||||
|
assertEquals(request.cardName, "Island");
|
||||||
|
assertEquals(request.edition, "SLD");
|
||||||
|
assertEquals(request.artIndex, 13);
|
||||||
|
assertEquals(request.collectorNumber, IPaperCard.NO_COLLECTOR_NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import forge.ImageKeys;
|
|||||||
import forge.Singletons;
|
import forge.Singletons;
|
||||||
import forge.StaticData;
|
import forge.StaticData;
|
||||||
import forge.gamesimulationtests.util.CardDatabaseHelper;
|
import forge.gamesimulationtests.util.CardDatabaseHelper;
|
||||||
|
import forge.item.PaperCard;
|
||||||
import forge.localinstance.properties.ForgeConstants;
|
import forge.localinstance.properties.ForgeConstants;
|
||||||
import forge.localinstance.properties.ForgePreferences;
|
import forge.localinstance.properties.ForgePreferences;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
@@ -133,6 +134,9 @@ public class ForgeCardMockTestCase extends PowerMockTestCase {
|
|||||||
PowerMockito.mockStatic(ImageKeys.class);
|
PowerMockito.mockStatic(ImageKeys.class);
|
||||||
initForgeConstants();
|
initForgeConstants();
|
||||||
|
|
||||||
|
// Always Has Image (there is a separated test case to cover the opposite case)
|
||||||
|
PowerMockito.when(ImageKeys.hasImage(Mockito.any(PaperCard.class))).thenReturn(true);
|
||||||
|
|
||||||
//Mocking some more static stuff
|
//Mocking some more static stuff
|
||||||
PowerMockito.mockStatic(Singletons.class);
|
PowerMockito.mockStatic(Singletons.class);
|
||||||
PowerMockito.mockStatic(FModel.class);
|
PowerMockito.mockStatic(FModel.class);
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ public class LegacyCardDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public PaperCard getFoiled(PaperCard card0) {
|
public PaperCard getFoiled(PaperCard card0) {
|
||||||
return new PaperCard(card0.getRules(), card0.getEdition(), card0.getRarity(), card0.getArtIndex(), true, card0.getArtist());
|
return card0.getFoiled();
|
||||||
}
|
}
|
||||||
|
|
||||||
public PaperCard getCardFromEdition(final String cardName, LegacySetPreference fromSet) {
|
public PaperCard getCardFromEdition(final String cardName, LegacySetPreference fromSet) {
|
||||||
|
|||||||
Reference in New Issue
Block a user