ColorSet: store EnumSet and toString as Final (#8720)

This commit is contained in:
Hans Mackowiak
2025-09-16 16:32:16 +02:00
committed by GitHub
parent cebddb7f4b
commit 6cf2f20cdc
15 changed files with 111 additions and 127 deletions

View File

@@ -20,7 +20,6 @@ package forge.card;
import com.google.common.collect.UnmodifiableIterator;
import forge.card.MagicColor.Color;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostShard;
import forge.util.BinaryUtil;
import java.io.Serializable;
@@ -41,27 +40,97 @@ import java.util.stream.Stream;
public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Serializable {
private static final long serialVersionUID = 794691267379929080L;
// needs to be before other static
private static final ColorSet[] cache = new ColorSet[MagicColor.ALL_COLORS + 1];
static {
byte COLORLESS = MagicColor.COLORLESS;
byte WHITE = MagicColor.WHITE;
byte BLUE = MagicColor.BLUE;
byte BLACK = MagicColor.BLACK;
byte RED = MagicColor.RED;
byte GREEN = MagicColor.GREEN;
Color C = Color.COLORLESS;
Color W = Color.WHITE;
Color U = Color.BLUE;
Color B = Color.BLACK;
Color R = Color.RED;
Color G = Color.GREEN;
//colorless
cache[COLORLESS] = new ColorSet(C);
//mono-color
cache[WHITE] = new ColorSet(W);
cache[BLUE] = new ColorSet(U);
cache[BLACK] = new ColorSet(B);
cache[RED] = new ColorSet(R);
cache[GREEN] = new ColorSet(G);
//two-color
cache[WHITE | BLUE] = new ColorSet(W, U);
cache[WHITE | BLACK] = new ColorSet(W, B);
cache[BLUE | BLACK] = new ColorSet(U, B);
cache[BLUE | RED] = new ColorSet(U, R);
cache[BLACK | RED] = new ColorSet(B, R);
cache[BLACK | GREEN] = new ColorSet(B, G);
cache[RED | GREEN] = new ColorSet(R, G);
cache[RED | WHITE] = new ColorSet(R, W);
cache[GREEN | WHITE] = new ColorSet(G, W);
cache[GREEN | BLUE] = new ColorSet(G, U);
//three-color
cache[WHITE | BLUE | BLACK] = new ColorSet(W, U, B);
cache[WHITE | BLACK | GREEN] = new ColorSet(W, B, G);
cache[BLUE | BLACK | RED] = new ColorSet(U, B, R);
cache[BLUE | RED | WHITE] = new ColorSet(U, R, W);
cache[BLACK | RED | GREEN] = new ColorSet(B, R, G);
cache[BLACK | GREEN | BLUE] = new ColorSet(B, G, U);
cache[RED | GREEN | WHITE] = new ColorSet(R, G, W);
cache[RED | WHITE | BLACK] = new ColorSet(R, W, B);
cache[GREEN | WHITE | BLUE] = new ColorSet(G, W, U);
cache[GREEN | BLUE | RED] = new ColorSet(G, U, R);
//four-color
cache[WHITE | BLUE | BLACK | RED] = new ColorSet(W, U, B, R);
cache[BLUE | BLACK | RED | GREEN] = new ColorSet(U, B, R, G);
cache[BLACK | RED | GREEN | WHITE] = new ColorSet(B, R, G, W);
cache[RED | GREEN | WHITE | BLUE] = new ColorSet(R, G, W, U);
cache[GREEN | WHITE | BLUE | BLACK] = new ColorSet(G, W, U, B);
//five-color
cache[WHITE | BLUE | BLACK | RED | GREEN] = new ColorSet(W, U, B, R, G);
}
private final Collection<Color> orderedShards;
private final byte myColor;
private final float orderWeight;
private static final ColorSet[] cache = new ColorSet[32];
private final Set<Color> enumSet;
private final String desc;
public static final ColorSet ALL_COLORS = fromMask(MagicColor.ALL_COLORS);
private static final ColorSet NO_COLORS = fromMask(MagicColor.COLORLESS);
public static final ColorSet NO_COLORS = fromMask(MagicColor.COLORLESS);
private ColorSet(final byte mask) {
this.myColor = mask;
private ColorSet(final Color... ordered) {
this.orderedShards = Arrays.asList(ordered);
this.myColor = orderedShards.stream().map(Color::getColorMask).reduce((byte)0, (a, b) -> (byte)(a | b));
this.orderWeight = this.getOrderWeight();
this.enumSet = EnumSet.copyOf(orderedShards);
this.desc = orderedShards.stream().map(Color::getShortName).collect(Collectors.joining());
}
public static ColorSet fromMask(final int mask) {
final int mask32 = mask & MagicColor.ALL_COLORS;
if (cache[mask32] == null) {
cache[mask32] = new ColorSet((byte) mask32);
}
return cache[mask32];
}
public static ColorSet fromEnums(final Color... colors) {
byte mask = 0;
for (Color e : colors) {
mask |= e.getColorMask();
}
return fromMask(mask);
}
public static ColorSet fromNames(final String... colors) {
byte mask = 0;
for (final String s : colors) {
@@ -293,17 +362,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
*/
@Override
public String toString() {
final ManaCostShard[] orderedShards = getOrderedShards();
return Arrays.stream(orderedShards).map(ManaCostShard::toShortString).collect(Collectors.joining());
}
/**
* Gets the null color.
*
* @return the nullColor
*/
public static ColorSet getNullColor() {
return NO_COLORS;
return desc;
}
/**
@@ -325,16 +384,7 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
}
public Set<Color> toEnumSet() {
if (isColorless()) {
return EnumSet.of(Color.COLORLESS);
}
List<Color> list = new ArrayList<>();
for (Color c : Color.values()) {
if (hasAnyColor(c.getColormask())) {
list.add(c);
}
}
return EnumSet.copyOf(list);
return EnumSet.copyOf(enumSet);
}
@Override
@@ -372,72 +422,12 @@ public final class ColorSet implements Comparable<ColorSet>, Iterable<Byte>, Ser
}
}
public Stream<MagicColor.Color> stream() {
public Stream<Color> stream() {
return this.toEnumSet().stream();
}
//Get array of mana cost shards for color set in the proper order
public ManaCostShard[] getOrderedShards() {
return shardOrderLookup[myColor];
}
private static final ManaCostShard[][] shardOrderLookup = new ManaCostShard[MagicColor.ALL_COLORS + 1][];
static {
byte COLORLESS = MagicColor.COLORLESS;
byte WHITE = MagicColor.WHITE;
byte BLUE = MagicColor.BLUE;
byte BLACK = MagicColor.BLACK;
byte RED = MagicColor.RED;
byte GREEN = MagicColor.GREEN;
ManaCostShard C = ManaCostShard.COLORLESS;
ManaCostShard W = ManaCostShard.WHITE;
ManaCostShard U = ManaCostShard.BLUE;
ManaCostShard B = ManaCostShard.BLACK;
ManaCostShard R = ManaCostShard.RED;
ManaCostShard G = ManaCostShard.GREEN;
//colorless
shardOrderLookup[COLORLESS] = new ManaCostShard[] { C };
//mono-color
shardOrderLookup[WHITE] = new ManaCostShard[] { W };
shardOrderLookup[BLUE] = new ManaCostShard[] { U };
shardOrderLookup[BLACK] = new ManaCostShard[] { B };
shardOrderLookup[RED] = new ManaCostShard[] { R };
shardOrderLookup[GREEN] = new ManaCostShard[] { G };
//two-color
shardOrderLookup[WHITE | BLUE] = new ManaCostShard[] { W, U };
shardOrderLookup[WHITE | BLACK] = new ManaCostShard[] { W, B };
shardOrderLookup[BLUE | BLACK] = new ManaCostShard[] { U, B };
shardOrderLookup[BLUE | RED] = new ManaCostShard[] { U, R };
shardOrderLookup[BLACK | RED] = new ManaCostShard[] { B, R };
shardOrderLookup[BLACK | GREEN] = new ManaCostShard[] { B, G };
shardOrderLookup[RED | GREEN] = new ManaCostShard[] { R, G };
shardOrderLookup[RED | WHITE] = new ManaCostShard[] { R, W };
shardOrderLookup[GREEN | WHITE] = new ManaCostShard[] { G, W };
shardOrderLookup[GREEN | BLUE] = new ManaCostShard[] { G, U };
//three-color
shardOrderLookup[WHITE | BLUE | BLACK] = new ManaCostShard[] { W, U, B };
shardOrderLookup[WHITE | BLACK | GREEN] = new ManaCostShard[] { W, B, G };
shardOrderLookup[BLUE | BLACK | RED] = new ManaCostShard[] { U, B, R };
shardOrderLookup[BLUE | RED | WHITE] = new ManaCostShard[] { U, R, W };
shardOrderLookup[BLACK | RED | GREEN] = new ManaCostShard[] { B, R, G };
shardOrderLookup[BLACK | GREEN | BLUE] = new ManaCostShard[] { B, G, U };
shardOrderLookup[RED | GREEN | WHITE] = new ManaCostShard[] { R, G, W };
shardOrderLookup[RED | WHITE | BLACK] = new ManaCostShard[] { R, W, B };
shardOrderLookup[GREEN | WHITE | BLUE] = new ManaCostShard[] { G, W, U };
shardOrderLookup[GREEN | BLUE | RED] = new ManaCostShard[] { G, U, R };
//four-color
shardOrderLookup[WHITE | BLUE | BLACK | RED] = new ManaCostShard[] { W, U, B, R };
shardOrderLookup[BLUE | BLACK | RED | GREEN] = new ManaCostShard[] { U, B, R, G };
shardOrderLookup[BLACK | RED | GREEN | WHITE] = new ManaCostShard[] { B, R, G, W };
shardOrderLookup[RED | GREEN | WHITE | BLUE] = new ManaCostShard[] { R, G, W, U };
shardOrderLookup[GREEN | WHITE | BLUE | BLACK] = new ManaCostShard[] { G, W, U, B };
//five-color
shardOrderLookup[WHITE | BLUE | BLACK | RED | GREEN] = new ManaCostShard[] { W, U, B, R, G };
public Collection<Color> getOrderedColors() {
return orderedShards;
}
}

View File

@@ -166,7 +166,7 @@ public final class MagicColor {
COLORLESS(Constant.COLORLESS, MagicColor.COLORLESS, "C", "lblColorless");
private final String name, shortName, symbol;
private final String localizedName;
private final String label;
private final byte colormask;
Color(String name0, byte colormask0, String shortName, String label) {
@@ -174,7 +174,7 @@ public final class MagicColor {
colormask = colormask0;
this.shortName = shortName;
symbol = "{" + shortName + "}";
localizedName = Localizer.getInstance().getMessage(label);
this.label = label;
}
public static Color fromByte(final byte color) {
@@ -196,10 +196,10 @@ public final class MagicColor {
}
public String getLocalizedName() {
return localizedName;
return Localizer.getInstance().getMessage(label);
}
public byte getColormask() {
public byte getColorMask() {
return colormask;
}
public String getSymbol() {

View File

@@ -1015,7 +1015,7 @@ public class DeckRecognizer {
return String.format("%s // %s", getMagicColourLabel(magicColor1), getMagicColourLabel(magicColor2));
String localisedName1 = magicColor1.getLocalizedName();
String localisedName2 = magicColor2.getLocalizedName();
String comboManaSymbol = manaSymbolsMap.get(magicColor1.getColormask() | magicColor2.getColormask());
String comboManaSymbol = manaSymbolsMap.get(magicColor1.getColorMask() | magicColor2.getColorMask());
return String.format("%s/%s {%s}", localisedName1, localisedName2, comboManaSymbol);
}

View File

@@ -593,7 +593,7 @@ public class PaperCard implements Comparable<IPaperCard>, InventoryItemFromSet,
public PaperCardFlags withMarkedColors(ColorSet markedColors) {
if(markedColors == null)
markedColors = ColorSet.getNullColor();
markedColors = ColorSet.NO_COLORS;
return new PaperCardFlags(this, markedColors, null);
}

View File

@@ -35,7 +35,7 @@ public class ForgeScript {
boolean withSource = property.endsWith("Source");
final ColorSet colors;
if (withSource && StaticAbilityColorlessDamageSource.colorlessDamageSource(cardState)) {
colors = ColorSet.getNullColor();
colors = ColorSet.NO_COLORS;
} else {
colors = cardState.getCard().getColor(cardState);
}

View File

@@ -2263,7 +2263,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
public final ColorSet getMarkedColors() {
if (markedColor == null) {
return ColorSet.getNullColor();
return ColorSet.NO_COLORS;
}
return markedColor;
}

View File

@@ -464,7 +464,7 @@ public class TrackableTypes {
public static final TrackableType<ColorSet> ColorSetType = new TrackableType<ColorSet>() {
@Override
public ColorSet getDefaultValue() {
return ColorSet.getNullColor();
return ColorSet.NO_COLORS;
}
@Override

View File

@@ -6,7 +6,7 @@ import java.awt.Graphics;
import javax.swing.JTable;
import forge.card.ColorSet;
import forge.card.mana.ManaCostShard;
import forge.card.MagicColor;
import forge.toolbox.CardFaceSymbols;
public class ColorSetRenderer extends ItemCellRenderer {
@@ -33,7 +33,7 @@ public class ColorSetRenderer extends ItemCellRenderer {
this.cs = (ColorSet) value;
}
else {
this.cs = ColorSet.getNullColor();
this.cs = ColorSet.NO_COLORS;
}
this.setToolTipText(cs.toString());
return super.getTableCellRendererComponent(table, "", isSelected, hasFocus, row, column);
@@ -57,8 +57,8 @@ public class ColorSetRenderer extends ItemCellRenderer {
final int offsetIfNoSpace = cntGlyphs > 1 ? (cellWidth - padding0 - elemtWidth) / (cntGlyphs - 1) : elemtWidth + elemtGap;
final int dx = Math.min(elemtWidth + elemtGap, offsetIfNoSpace);
for (final ManaCostShard s : cs.getOrderedShards()) {
CardFaceSymbols.drawManaSymbol(s.getImageKey(), g, x, y);
for (final MagicColor.Color s : cs.getOrderedColors()) {
CardFaceSymbols.drawManaSymbol(s.getShortName(), g, x, y);
x += dx;
}
}

View File

@@ -8,6 +8,7 @@ import java.util.StringTokenizer;
import com.esotericsoftware.minlog.Log;
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostShard;
import forge.gui.GuiBase;
@@ -204,9 +205,9 @@ public class CardFaceSymbols {
}
public static void drawColorSet(Graphics g, ColorSet colorSet, int x, int y, int imageSize, boolean vertical) {
for (final ManaCostShard s : colorSet.getOrderedShards()) {
if (DECK_COLORSET.get(s.getImageKey())!=null)
FSkin.drawImage(g, DECK_COLORSET.get(s.getImageKey()), x, y, imageSize, imageSize);
for (final MagicColor.Color s : colorSet.getOrderedColors()) {
if (DECK_COLORSET.get(s.getShortName())!=null)
FSkin.drawImage(g, DECK_COLORSET.get(s.getShortName()), x, y, imageSize, imageSize);
if (!vertical)
x += imageSize;
else

View File

@@ -186,8 +186,8 @@ public class CardFaceSymbols {
public static void drawColorSet(Graphics g, ColorSet colorSet, float x, float y, final float imageSize, boolean vertical) {
final float dx = imageSize;
for (final ManaCostShard s : colorSet.getOrderedShards()) {
drawSymbol(s.getImageKey(), g, x, y, imageSize, imageSize);
for (final MagicColor.Color s : colorSet.getOrderedColors()) {
drawSymbol(s.getShortName(), g, x, y, imageSize, imageSize);
if (!vertical)
x += dx;
else

View File

@@ -11,7 +11,7 @@ public class ColorSetImage implements FImage {
public ColorSetImage(ColorSet colorSet0) {
colorSet = colorSet0;
shardCount = colorSet.getOrderedShards().length;
shardCount = colorSet.getOrderedColors().size();
}
@Override

View File

@@ -16,7 +16,6 @@ import forge.assets.*;
import forge.assets.FSkinColor.Colors;
import forge.card.*;
import forge.card.CardRenderer.CardStackPosition;
import forge.card.mana.ManaCostShard;
import forge.deck.*;
import forge.deck.io.DeckPreferences;
import forge.game.card.CardView;
@@ -37,7 +36,6 @@ import forge.util.Utils;
import java.util.*;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static forge.assets.FSkin.getDefaultSkinFile;
@@ -1100,10 +1098,10 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
deckSelectMode = true;
deckProxy = (DeckProxy) item;
}
if (item instanceof PaperCard) {
if (item instanceof PaperCard pc) {
showRanking = itemManager.getShowRanking() && FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.UI_OVERLAY_DRAFT_RANKING);
if (showRanking) {
double score = CardRanker.getRawScore((PaperCard) item);
double score = CardRanker.getRawScore(pc);
draftRank = score <= 0 ? 0 : score > 99 ? 99 : (int) Math.round(CardRanker.getRawScore((PaperCard) item));
if (draftRank >= 90) {
draftRankImage = FSkinImage.DRAFTRANK_S;
@@ -1115,10 +1113,8 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
draftRankImage = FSkinImage.DRAFTRANK_C;
}
}
if (((PaperCard) item).getMarkedColors() != null) {
markedColors = Arrays.stream(((PaperCard) item).getMarkedColors().getOrderedShards())
.map(ManaCostShard::toString)
.collect(Collectors.joining());
if (pc.getMarkedColors() != null) {
markedColors = pc.getMarkedColors().toString();
}
}
if(fnPrice != null) {

View File

@@ -11,7 +11,6 @@ import com.google.common.collect.Sets;
import forge.card.*;
import forge.card.CardType.CoreType;
import forge.card.mana.ManaCostShard;
import forge.deck.CardPool;
import forge.deck.Deck;
import forge.deck.DeckFormat;
@@ -320,10 +319,9 @@ public class ConquestUtil {
public static AEtherFilter getColorFilter(ColorSet color) {
StringBuilder name = new StringBuilder();
for (ManaCostShard s : color.getOrderedShards()) {
name.append(s.toString());
for (MagicColor.Color s : color.getOrderedColors()) {
name.append(s.getShortName());
}
name = new StringBuilder(name.toString().replaceAll("[{}]", "")); //remove all brackets
try {
return AEtherFilter.valueOf(name.toString());
}

View File

@@ -5,7 +5,6 @@ import forge.card.CardRarity;
import forge.card.CardStateName;
import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.card.mana.ManaCostShard;
import forge.deck.DeckRecognizer;
import forge.game.GameView;
import forge.game.card.Card;
@@ -100,7 +99,7 @@ public class CardDetailUtil {
borderColors.add(DetailColors.MULTICOLOR);
}
else { //for 3 colors or fewer, return all colors in shard order
for (ManaCostShard shard : cardColors.getOrderedShards()) {
for (MagicColor.Color shard : cardColors.getOrderedColors()) {
switch (shard.getColorMask()) {
case MagicColor.WHITE:
borderColors.add(DetailColors.WHITE);

View File

@@ -377,7 +377,7 @@ public enum ColumnDef {
}
private static ColorSet toColor(final InventoryItem i) {
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getColor() : ColorSet.getNullColor();
return i instanceof IPaperCard ? ((IPaperCard) i).getRules().getColor() : ColorSet.NO_COLORS;
}
private static Integer toPower(final InventoryItem i) {