mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +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.util.FileUtil;
|
||||
import forge.util.ImageUtil;
|
||||
import forge.util.TextUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public final class ImageKeys {
|
||||
public static final String CARD_PREFIX = "c:";
|
||||
@@ -68,9 +66,8 @@ public final class ImageKeys {
|
||||
}
|
||||
|
||||
public static File getImageFile(String key) {
|
||||
if (StringUtils.isEmpty(key)) {
|
||||
if (StringUtils.isEmpty(key))
|
||||
return null;
|
||||
}
|
||||
|
||||
final String dir;
|
||||
final String filename;
|
||||
@@ -220,14 +217,35 @@ public final class ImageKeys {
|
||||
|
||||
//shortcut for determining if a card image exists for a given card
|
||||
//should only be called from PaperCard.hasImage()
|
||||
static HashMap<String, HashSet<String>> cachedContent=new HashMap<>();
|
||||
public static boolean hasImage(PaperCard pc) {
|
||||
Boolean editionHasImage = editionImageLookup.get(pc.getEdition());
|
||||
if (editionHasImage == null) {
|
||||
String setFolder = getSetFolder(pc.getEdition());
|
||||
editionHasImage = FileUtil.isDirectoryWithFiles(CACHE_CARD_PICS_DIR + setFolder);
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
public static String compose(String cardName, boolean isFoil){
|
||||
if (isFoil)
|
||||
return cardName+foilSuffix;
|
||||
return cardName;
|
||||
}
|
||||
|
||||
public static String compose(String cardName, String setCode) {
|
||||
setCode = setCode != null ? setCode : "";
|
||||
cardName = cardName != null ? cardName : "";
|
||||
@@ -135,7 +141,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
||||
}
|
||||
|
||||
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) {
|
||||
@@ -462,15 +468,15 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
||||
}
|
||||
|
||||
// 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
|
||||
Collection<PaperCard> cards = getAllCards(request.cardName);
|
||||
if (cards == null)
|
||||
if (cards.isEmpty()) // Never null being this a view in MultiMap
|
||||
return null;
|
||||
// Either No Edition has been specified OR as a fallback in case of any error!
|
||||
// get card using the default card art preference
|
||||
result = getCardFromEditions(request.cardName, this.defaultCardArtPreference, request.artIndex);
|
||||
return result != null && request.isFoil ? result.getFoiled() : result;
|
||||
String cardRequest = CardRequest.compose(request.cardName, request.isFoil);
|
||||
return getCardFromEditions(cardRequest, this.defaultCardArtPreference, request.artIndex);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -510,9 +516,7 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
||||
cardName = cardNameRequest.cardName;
|
||||
isFoil = isFoil || cardNameRequest.isFoil;
|
||||
|
||||
List<PaperCard> cards = getAllCards(cardName);
|
||||
// Look for Code or Code2 to make the retrieval more robust
|
||||
List<PaperCard> candidates = Lists.newArrayList(Iterables.filter(cards, new Predicate<PaperCard>() {
|
||||
List<PaperCard> candidates = getAllCards(cardName, new Predicate<PaperCard>() {
|
||||
@Override
|
||||
public boolean apply(PaperCard c) {
|
||||
boolean artIndexFilter = true;
|
||||
@@ -526,21 +530,17 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
||||
collectorNumberFilter = (c.getCollectorNumber().equals(collectorNumber));
|
||||
return setFilter && artIndexFilter && collectorNumberFilter;
|
||||
}
|
||||
}));
|
||||
});
|
||||
if (candidates.isEmpty())
|
||||
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.
|
||||
// If not, try to replace current candidate with one having image,
|
||||
// so to align this implementation with old one.
|
||||
if (!candidate.hasImage()) {
|
||||
for (PaperCard card : candidates) {
|
||||
if (card.hasImage()) {
|
||||
candidate = card;
|
||||
break; // found, ready to go
|
||||
}
|
||||
}
|
||||
while (!candidate.hasImage() && candidatesIterator.hasNext()) {
|
||||
candidate = candidatesIterator.next();
|
||||
}
|
||||
return isFoil ? candidate.getFoiled() : candidate;
|
||||
}
|
||||
@@ -567,8 +567,8 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaperCard getCardFromEditions(final String cardName, final CardArtPreference artPreference, int artIndex) {
|
||||
return this.tryToGetCardFromEditions(cardName, artPreference, artIndex);
|
||||
public PaperCard getCardFromEditions(final String cardInfo, final CardArtPreference artPreference, int 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 )
|
||||
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) {
|
||||
cards = Lists.newArrayList(Iterables.filter(cards, new Predicate<PaperCard>() {
|
||||
cards = getAllCards(cr.cardName, new Predicate<PaperCard>() {
|
||||
@Override
|
||||
public boolean apply(PaperCard c) {
|
||||
if (c.getArtIndex() != cr.artIndex)
|
||||
return false; // not interested anyway!
|
||||
CardEdition ed = editions.get(c.getEdition());
|
||||
if (ed == null) return false;
|
||||
if (releasedBeforeFlag)
|
||||
return ed.getDate().before(releaseDate);
|
||||
else
|
||||
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!
|
||||
return null;
|
||||
if (cards.size() == 1) // if only one candidate, there much else we should do
|
||||
return cr.isFoil ? cards.get(0).getFoiled() : cards.get(0);
|
||||
|
||||
/* 2. Retrieve cards based of [Frame]Set Preference
|
||||
================================================ */
|
||||
|
||||
// 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) {
|
||||
String setCode = card.getEdition();
|
||||
CardEdition ed;
|
||||
if (setCode.equals(CardEdition.UNKNOWN.getCode()))
|
||||
cardEditions.add(CardEdition.UNKNOWN);
|
||||
else {
|
||||
CardEdition ed = editions.get(card.getEdition());
|
||||
if (ed != null)
|
||||
cardEditions.add(ed);
|
||||
ed = CardEdition.UNKNOWN;
|
||||
else
|
||||
ed = editions.get(card.getEdition());
|
||||
if (ed != null) {
|
||||
cardEditions.add(ed);
|
||||
candidatesCard.put(setCode, card);
|
||||
}
|
||||
}
|
||||
if (cardEditions.isEmpty())
|
||||
return null; // nothing to do
|
||||
|
||||
// Filter Cards Editions based on set preferences
|
||||
List<CardEdition> acceptedEditions = Lists.newArrayList(Iterables.filter(cardEditions, new Predicate<CardEdition>() {
|
||||
@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
|
||||
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);
|
||||
|
||||
Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date
|
||||
if (artPref.latestFirst)
|
||||
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()) {
|
||||
candidate = cardFromSet;
|
||||
break; // we're done here: found card **with Image**
|
||||
}
|
||||
if (acceptedEditions.size() > 1) {
|
||||
Collections.sort(acceptedEditions); // CardEdition correctly sort by (release) date
|
||||
if (artPref.latestFirst)
|
||||
Collections.reverse(acceptedEditions); // newest editions first
|
||||
}
|
||||
//If any, we're sure that at least one candidate is always returned nevertheless it has image or not
|
||||
return candidate; // any foil request already handled in getCardFromSet
|
||||
|
||||
final Iterator<CardEdition> editionIterator = acceptedEditions.iterator();
|
||||
CardEdition ed = editionIterator.next();
|
||||
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
|
||||
return cr.isFoil ? candidate.getFoiled() : candidate;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -716,18 +728,16 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getArtCount(String cardName, String setName) {
|
||||
if (cardName == null || setName == null)
|
||||
public int getArtCount(String cardName, String setCode) {
|
||||
if (cardName == null || setCode == null)
|
||||
return 0;
|
||||
Collection<PaperCard> cards = getAllCards(cardName);
|
||||
if (null == cards || cards.size() == 0)
|
||||
return 0;
|
||||
int artCount = 0;
|
||||
for (PaperCard pc : cards) {
|
||||
if (pc.getEdition().equalsIgnoreCase(setName))
|
||||
artCount++;
|
||||
}
|
||||
return artCount;
|
||||
Collection<PaperCard> cardsInSet = getAllCards(cardName, new Predicate<PaperCard>() {
|
||||
@Override
|
||||
public boolean apply(PaperCard card) {
|
||||
return card.getEdition().equalsIgnoreCase(setCode);
|
||||
}
|
||||
});
|
||||
return cardsInSet.size();
|
||||
}
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
@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
|
||||
*/
|
||||
@@ -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)
|
||||
List<PaperCard> paperCards = new ArrayList<>();
|
||||
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()) {
|
||||
int artIdx = IPaperCard.DEFAULT_ART_INDEX;
|
||||
for (CardInSet cis : e.getAllCardsInSet()) {
|
||||
if (!cis.name.equals(cardName)) {
|
||||
continue;
|
||||
}
|
||||
paperCards.add(new PaperCard(rules, e.getCode(), cis.rarity, artIdx++));
|
||||
}
|
||||
for (CardInSet cis : e.getCardInSet(cardName))
|
||||
paperCards.add(new PaperCard(rules, e.getCode(), cis.rarity, artIdx++, false,
|
||||
cis.collectorNumber, cis.artistName));
|
||||
}
|
||||
} else {
|
||||
String lastEdition = null;
|
||||
int artIdx = 0;
|
||||
for (Pair<String, CardRarity> tuple : whenItWasPrinted) {
|
||||
if (!tuple.getKey().equals(lastEdition)) {
|
||||
artIdx = IPaperCard.DEFAULT_ART_INDEX;
|
||||
artIdx = IPaperCard.DEFAULT_ART_INDEX; // reset artIndex
|
||||
lastEdition = tuple.getKey();
|
||||
}
|
||||
CardEdition ed = editions.get(lastEdition);
|
||||
if (null == ed) {
|
||||
if (ed == null) {
|
||||
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()) {
|
||||
|
||||
@@ -373,6 +373,13 @@ public final class CardEdition implements Comparable<CardEdition> {
|
||||
}
|
||||
|
||||
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){
|
||||
if (cardsInSetLookupMap == null) {
|
||||
// initialise
|
||||
|
||||
@@ -79,6 +79,7 @@ public interface ICardDatabase extends Iterable<PaperCard> {
|
||||
Collection<PaperCard> getAllCards();
|
||||
Collection<PaperCard> getAllCards(String cardName);
|
||||
Collection<PaperCard> getAllCards(Predicate<PaperCard> predicate);
|
||||
Collection<PaperCard> getAllCards(String cardName,Predicate<PaperCard> predicate);
|
||||
Collection<PaperCard> getAllCards(CardEdition edition);
|
||||
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
|
||||
int DEFAULT_ART_INDEX = 1;
|
||||
int NO_ART_INDEX = -1; // Placeholder when NO ArtIndex is Specified
|
||||
String NO_ARTIST_NAME = "";
|
||||
|
||||
/**
|
||||
* Number of filters based on CardPrinted values.
|
||||
|
||||
@@ -25,6 +25,7 @@ import forge.card.CardEdition;
|
||||
import forge.card.CardRarity;
|
||||
import forge.card.CardRules;
|
||||
import forge.util.CardTranslation;
|
||||
import forge.util.ImageUtil;
|
||||
import forge.util.Localizer;
|
||||
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.
|
||||
(see getCollectorNumber())
|
||||
*/
|
||||
private String collectorNumber = null;
|
||||
private String collectorNumber;
|
||||
private final String artist;
|
||||
private final int artIndex;
|
||||
private final boolean foil;
|
||||
@@ -75,18 +76,6 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
||||
|
||||
@Override
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -152,6 +141,13 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
||||
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.
|
||||
*/
|
||||
@@ -169,15 +165,12 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
||||
};
|
||||
|
||||
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) {
|
||||
this(rules0, edition0, rarity0, artIndex0, false, "");
|
||||
}
|
||||
|
||||
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0, final int artIndex0,
|
||||
final boolean foil0, final String artist0) {
|
||||
public PaperCard(final CardRules rules0, final String edition0, final CardRarity rarity0,
|
||||
final int artIndex0, final boolean foil0, final String collectorNumber0, final String artist0) {
|
||||
if (rules0 == null || edition0 == null || rarity0 == null) {
|
||||
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);
|
||||
foil = foil0;
|
||||
rarity = rarity0;
|
||||
artist = (artist0 != null ? artist0 : "");
|
||||
}
|
||||
|
||||
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;
|
||||
artist = (artist0 != null ? artist0 : IPaperCard.NO_ARTIST_NAME);
|
||||
collectorNumber = (collectorNumber0 != null) && (collectorNumber0.length() > 0) ? collectorNumber0 : IPaperCard.NO_COLLECTOR_NUMBER;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
private String sortableCNKey = null;
|
||||
public String getCollectorNumberSortingKey(){
|
||||
// Hardly the case, but just invoke getter rather than direct
|
||||
// attribute to be sure that collectorNumber has been retrieved already!
|
||||
return makeCollectorNumberSortingKey(getCollectorNumber());
|
||||
if (sortableCNKey == null) {
|
||||
// Hardly the case, but just invoke getter rather than direct
|
||||
// attribute to be sure that collectorNumber has been retrieved already!
|
||||
sortableCNKey = makeCollectorNumberSortingKey(getCollectorNumber());
|
||||
}
|
||||
return sortableCNKey;
|
||||
}
|
||||
|
||||
|
||||
@@ -309,32 +298,6 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
||||
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
|
||||
public String getImageKey(boolean altState) {
|
||||
String imageKey = ImageKeys.CARD_PREFIX + name + CardDb.NameSetSeparator
|
||||
|
||||
@@ -78,8 +78,10 @@ public final class FileUtil {
|
||||
}
|
||||
|
||||
public static boolean isDirectoryWithFiles(final String path) {
|
||||
if (path == null) return false;
|
||||
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) {
|
||||
|
||||
@@ -56,7 +56,7 @@ public class ImageUtil {
|
||||
int artIdx = cp.getArtIndex() - 1;
|
||||
if (hasManyPictures) {
|
||||
if (cntPictures <= artIdx) // prevent overflow
|
||||
artIdx = cntPictures == 0 ? 0 : artIdx % cntPictures;
|
||||
artIdx = artIdx % cntPictures;
|
||||
s.append(artIdx + 1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user