* Performance: memory usage optimization for deck editor (removed bloated usage of ManaCosts -> ManaColor objects, see #7515);

This commit is contained in:
Oleg Agafonov 2021-02-12 14:08:17 +04:00
parent c3d55ea12a
commit 275e996c08
23 changed files with 170 additions and 143 deletions

View file

@ -57,7 +57,7 @@ public abstract class MageObjectImpl implements MageObject {
color = new ObjectColor();
frameColor = new ObjectColor();
frameStyle = FrameStyle.M15_NORMAL;
manaCost = new ManaCostsImpl<>("");
manaCost = new ManaCostsImpl<>();
abilities = new AbilitiesImpl<>();
textParts = new ArrayList<>();
}

View file

@ -24,6 +24,10 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
private ManaColor() {
}
protected ManaColor(final ManaColor manaColor) {
this.copyFrom(manaColor);
}
private ManaColor(int amount) {
this.amount = amount;
}
@ -76,9 +80,12 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
}
protected ManaColor copy() {
ManaColor copy = new ManaColor();
copy.incrementAmount(this);
return copy;
return new ManaColor(this);
}
protected void copyFrom(final ManaColor manaColor) {
this.amount = manaColor.amount;
this.snowAmount = manaColor.snowAmount;
}
@Override
@ -1202,14 +1209,15 @@ public class Mana implements Comparable<Mana>, Serializable, Copyable<Mana> {
* @param mana the mana to set this object to.
*/
public void setToMana(final Mana mana) {
this.any = mana.any.copy();
this.white = mana.white.copy();
this.blue = mana.blue.copy();
this.black = mana.black.copy();
this.red = mana.red.copy();
this.green = mana.green.copy();
this.colorless = mana.colorless.copy();
this.generic = mana.generic.copy();
this.any.copyFrom(mana.any);
this.white.copyFrom(mana.white);
this.blue.copyFrom(mana.blue.copy());
this.black.copyFrom(mana.black.copy());
this.red.copyFrom(mana.red.copy());
this.green.copyFrom(mana.green.copy());
this.colorless.copyFrom(mana.colorless.copy());
this.generic.copyFrom(mana.generic.copy());
//this.flag = mana.flag;
}
/**

View file

@ -194,11 +194,11 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
private void handleLikePhyrexianManaCosts(Player player, Ability source, Game game) {
if (this.isEmpty()) {
return; // nothing to be done without any mana costs. prevents NRE from occurring here
}
}
FilterMana phyrexianColors = player.getPhyrexianColors();
if (player.getPhyrexianColors() != null) {
Costs<PayLifeCost> tempCosts = new CostsImpl<>();
Iterator<T> manaCostIterator = this.iterator();
while (manaCostIterator.hasNext()) {
ManaCost manaCost = manaCostIterator.next();
@ -440,15 +440,16 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
@Override
public final void load(String mana, boolean extractMonoHybridGenericValue) {
this.clear();
if (!extractMonoHybridGenericValue && mana != null && costsCache.containsKey(mana)) {
if (mana == null || mana.isEmpty()) {
return;
}
if (!extractMonoHybridGenericValue && costsCache.containsKey(mana)) {
ManaCosts<ManaCost> savedCosts = costsCache.get(mana);
for (ManaCost cost : savedCosts) {
this.add(cost.copy());
}
} else {
if (mana == null || mana.isEmpty()) {
return;
}
String[] symbols = mana.split("^\\{|}\\{|}$");
int modifierForX = 0;
for (String symbol : symbols) {
@ -463,15 +464,15 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
} else if (!symbol.equals("X")) {
this.add(new ColoredManaCost(ColoredManaSymbol.lookup(symbol.charAt(0))));
} else // check X wasn't added before
if (modifierForX == 0) {
// count X occurence
for (String s : symbols) {
if (s.equals("X")) {
modifierForX++;
if (modifierForX == 0) {
// count X occurence
for (String s : symbols) {
if (s.equals("X")) {
modifierForX++;
}
}
}
this.add(new VariableManaCost(modifierForX));
} //TODO: handle multiple {X} and/or {Y} symbols
this.add(new VariableManaCost(modifierForX));
} //TODO: handle multiple {X} and/or {Y} symbols
} else if (Character.isDigit(symbol.charAt(0))) {
MonoHybridManaCost cost;
if (extractMonoHybridGenericValue) {
@ -534,14 +535,7 @@ public class ManaCostsImpl<T extends ManaCost> extends ArrayList<T> implements M
StringBuilder sbText = new StringBuilder();
for (ManaCost cost : this) {
if (cost instanceof GenericManaCost) {
sbText.append(cost.getText());
}
}
for (ManaCost cost : this) {
if (!(cost instanceof GenericManaCost)) {
sbText.append(cost.getText());
}
sbText.append(cost.getText());
}
return sbText.toString();
}

View file

@ -29,8 +29,10 @@ public class MockCard extends CardImpl {
private int startingLoyalty;
// mana cost extra info for multiple mana drawing
protected ManaCosts<ManaCost> manaCostLeft;
protected ManaCosts<ManaCost> manaCostRight;
// warning, don't use ManaCost objects here due too much memory consumptions
protected List<String> manaCostLeftStr;
protected List<String> manaCostRightStr;
protected List<String> manaCostStr;
protected String adventureSpellName;
protected boolean isModalDoubleFacesCard;
@ -47,9 +49,10 @@ public class MockCard extends CardImpl {
this.usesVariousArt = card.usesVariousArt();
this.manaCostLeft = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.LEFT)));
this.manaCostRight = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.RIGHT)));
this.manaCost = new ManaCostsImpl(join(card.getManaCosts(CardInfo.ManaCostSide.ALL)));
this.manaCostLeftStr = card.getManaCosts(CardInfo.ManaCostSide.LEFT);
this.manaCostRightStr = card.getManaCosts(CardInfo.ManaCostSide.RIGHT);
this.manaCostStr = card.getManaCosts(CardInfo.ManaCostSide.ALL);
this.color = card.getColor();
@ -112,7 +115,8 @@ public class MockCard extends CardImpl {
return manaCost;
}
public ManaCosts<ManaCost> getManaCost(CardInfo.ManaCostSide manaCostSide) {
/*
private ManaCosts<ManaCost> getManaCost(CardInfo.ManaCostSide manaCostSide) {
switch (manaCostSide) {
case LEFT:
return manaCostLeft;
@ -122,6 +126,18 @@ public class MockCard extends CardImpl {
case ALL:
return manaCost;
}
}*/
public List<String> getManaCostStr(CardInfo.ManaCostSide manaCostSide) {
switch (manaCostSide) {
case LEFT:
return manaCostLeftStr;
case RIGHT:
return manaCostRightStr;
default:
case ALL:
return manaCostStr;
}
}
public String getFullName(boolean showSecondName) {

View file

@ -293,7 +293,7 @@ public class CardInfo {
return sb.toString();
}
private List<String> parseList(String list, ManaCostSide manaCostSide) {
public static List<String> parseList(String list, ManaCostSide manaCostSide) {
if (list.isEmpty()) {
return Collections.emptyList();
}

View file

@ -791,6 +791,15 @@ public final class CardUtil {
return res;
}
public static String concatManaSymbols(String delimeter, String mana1, String mana2) {
String res = mana1;
if (!res.isEmpty() && !mana2.isEmpty() && delimeter != null && !delimeter.isEmpty()) {
res += delimeter;
}
res += mana2;
return res;
}
public static ColoredManaSymbol manaTypeToColoredManaSymbol(ManaType manaType) {
switch (manaType) {
case BLACK:

View file

@ -523,7 +523,7 @@ public final class ManaUtil {
* @param secondSideCard second side of double faces card
* @return
*/
public static FilterMana getColorIdentity(ObjectColor cardColor, List<String> cardManaSymbols, List<String> cardRules, Card secondSideCard) {
public static FilterMana getColorIdentity(ObjectColor cardColor, String cardManaSymbols, List<String> cardRules, Card secondSideCard) {
// 20210121
// 903.4
// The Commander variant uses color identity to determine what cards can be in a deck with a certain
@ -612,6 +612,11 @@ public final class ManaUtil {
return cardManaSymbols.stream().anyMatch(s -> s.contains(needSymbol));
}
private static boolean containsManaSymbol(String cardManaSymbols, String needSymbol) {
// search R in {R/B}
return cardManaSymbols.contains(needSymbol);
}
public static FilterMana getColorIdentity(Card card) {
Card secondSide;
if (card instanceof SplitCard) {
@ -623,7 +628,7 @@ public final class ManaUtil {
} else {
secondSide = card.getSecondCardFace();
}
return getColorIdentity(card.getColor(), card.getManaCost().getSymbols(), card.getRules(), secondSide);
return getColorIdentity(card.getColor(), String.join("", card.getManaCost().getSymbols()), card.getRules(), secondSide);
}
public static int getColorIdentityHash(FilterMana colorIdentity) {