Skip to content

Commit 89bf197

Browse files
authored
Properties as enum (UnitSupportAttachment) (#13745)
* Properties as enum * Properties in enum directly define MutableProperty * Use property value instead of repeated strings * Extract IPropertyEnum from UnitSupportAttachment * Add IPropertyEnum * Change name IPropertyEnum to PropertyEnum
1 parent 4a0be7d commit 89bf197

File tree

2 files changed

+98
-62
lines changed

2 files changed

+98
-62
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package games.strategy.engine.data;
2+
3+
import java.util.Arrays;
4+
import java.util.Optional;
5+
import java.util.function.Function;
6+
7+
public interface PropertyEnum<A> {
8+
String getValue();
9+
10+
Function<A, MutableProperty<?>> getPropertyAccessor();
11+
12+
default MutableProperty<?> getMutableProperty(A attachment) {
13+
return getPropertyAccessor().apply(attachment);
14+
}
15+
16+
static <E extends Enum<E> & PropertyEnum<?>> Optional<E> parseFromString(
17+
Class<E> enumClass, String propertyName) {
18+
return Arrays.stream(enumClass.getEnumConstants())
19+
.filter(e -> e.getValue().equals(propertyName))
20+
.findAny();
21+
}
22+
23+
static <E extends Enum<E> & PropertyEnum<A>, A> Optional<MutableProperty<?>> getPropertyOrEmpty(
24+
Class<E> enumClass, String propertyName, A attachment) {
25+
return parseFromString(enumClass, propertyName).map(p -> p.getMutableProperty(attachment));
26+
}
27+
}

game-app/game-core/src/main/java/games/strategy/triplea/attachments/UnitSupportAttachment.java

Lines changed: 71 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import games.strategy.engine.data.GamePlayer;
88
import games.strategy.engine.data.GameState;
99
import games.strategy.engine.data.MutableProperty;
10+
import games.strategy.engine.data.PropertyEnum;
1011
import games.strategy.engine.data.UnitType;
1112
import games.strategy.engine.data.UnitTypeList;
1213
import games.strategy.engine.data.gameparser.GameParseException;
@@ -18,11 +19,14 @@
1819
import java.util.List;
1920
import java.util.Optional;
2021
import java.util.Set;
22+
import java.util.function.Function;
2123
import java.util.stream.Collectors;
2224
import javax.annotation.Nonnull;
2325
import javax.annotation.Nullable;
26+
import lombok.AllArgsConstructor;
2427
import lombok.EqualsAndHashCode;
2528
import lombok.Getter;
29+
import lombok.ToString;
2630
import lombok.Value;
2731
import org.jetbrains.annotations.NonNls;
2832

@@ -34,10 +38,60 @@
3438
* <p>The set of UnitSupportAttachments do not change during a game.
3539
*/
3640
public class UnitSupportAttachment extends DefaultAttachment {
37-
@NonNls public static final String BONUS = "bonus";
38-
@NonNls public static final String BONUS_TYPE = "bonusType";
39-
@NonNls public static final String DICE = "dice";
40-
@NonNls public static final String UNIT_TYPE = "unitType";
41+
@ToString(onlyExplicitlyIncluded = true)
42+
@AllArgsConstructor
43+
public enum PropertyName implements PropertyEnum<UnitSupportAttachment> {
44+
AA_ROLL("aaRoll", a -> MutableProperty.ofReadOnly(a::getAaRoll)),
45+
AA_STRENGTH("aaStrength", a -> MutableProperty.ofReadOnly(a::getAaStrength)),
46+
ALLIED("allied", a -> MutableProperty.ofReadOnly(a::getAllied)),
47+
BONUS("bonus", a -> MutableProperty.of(a::setBonus, a::setBonus, a::getBonus, a::resetBonus)),
48+
BONUS_TYPE(
49+
"bonusType",
50+
a ->
51+
MutableProperty.of(
52+
a::setBonusType, a::setBonusType, a::getBonusType, a::resetBonusType)),
53+
DEFENCE("defence", a -> MutableProperty.ofReadOnly(a::getDefence)),
54+
DICE("dice", a -> MutableProperty.ofString(a::setDice, a::getDice, a::resetDice)),
55+
ENEMY("enemy", a -> MutableProperty.ofReadOnly(a::getEnemy)),
56+
FACTION(
57+
"faction", a -> MutableProperty.ofString(a::setFaction, a::getFaction, a::resetFaction)),
58+
IMP_ART_TECH(
59+
"impArtTech",
60+
a ->
61+
MutableProperty.of(
62+
a::setImpArtTech, a::setImpArtTech, a::getImpArtTech, a::resetImpArtTech)),
63+
NUMBER(
64+
"number",
65+
a -> MutableProperty.of(a::setNumber, a::setNumber, a::getNumber, a::resetNumber)),
66+
OFFENCE("offence", a -> MutableProperty.ofReadOnly(a::getOffence)),
67+
PLAYERS(
68+
"players",
69+
a -> MutableProperty.of(a::setPlayers, a::setPlayers, a::getPlayers, a::resetPlayers)),
70+
ROLL("roll", a -> MutableProperty.ofReadOnly(a::getRoll)),
71+
SIDE("side", a -> MutableProperty.ofString(a::setSide, a::getSide, a::resetSide)),
72+
STRENGTH("strength", a -> MutableProperty.ofReadOnly(a::getStrength)),
73+
UNIT_TYPE(
74+
"unitType",
75+
a -> MutableProperty.of(a::setUnitType, a::setUnitType, a::getUnitType, a::resetUnitType)),
76+
;
77+
78+
@ToString.Include private final String value;
79+
private final Function<UnitSupportAttachment, MutableProperty<?>> propertyAccessor;
80+
81+
public MutableProperty<?> getMutableProperty(UnitSupportAttachment attachment) {
82+
return propertyAccessor.apply(attachment);
83+
}
84+
85+
@Override
86+
public String getValue() {
87+
return value;
88+
}
89+
90+
@Override
91+
public Function<UnitSupportAttachment, MutableProperty<?>> getPropertyAccessor() {
92+
return propertyAccessor;
93+
}
94+
}
4195

4296
private static final long serialVersionUID = -3015679930172496082L;
4397

@@ -126,9 +180,9 @@ public UnitSupportAttachment setFaction(final String faction) throws GameParseEx
126180
allied = false;
127181
enemy = false;
128182
for (final String element : splitOnColon(faction)) {
129-
if (element.equalsIgnoreCase("allied")) {
183+
if (element.equalsIgnoreCase(PropertyName.ALLIED.value)) {
130184
allied = true;
131-
} else if (element.equalsIgnoreCase("enemy")) {
185+
} else if (element.equalsIgnoreCase(PropertyName.ENEMY.value)) {
132186
enemy = true;
133187
} else {
134188
throw new GameParseException(
@@ -152,9 +206,9 @@ public UnitSupportAttachment setSide(final String side) throws GameParseExceptio
152206
defence = false;
153207
offence = false;
154208
for (final String element : splitOnColon(side)) {
155-
if (element.equalsIgnoreCase("defence")) {
209+
if (element.equalsIgnoreCase(PropertyName.DEFENCE.value)) {
156210
defence = true;
157-
} else if (element.equalsIgnoreCase("offence")) {
211+
} else if (element.equalsIgnoreCase(PropertyName.OFFENCE.value)) {
158212
offence = true;
159213
} else {
160214
throw new GameParseException(side + " side must be defence or offence" + thisErrorMsg());
@@ -179,13 +233,13 @@ public UnitSupportAttachment setDice(final String dice) throws GameParseExceptio
179233
resetDice();
180234
this.dice = dice.intern();
181235
for (final String element : splitOnColon(dice)) {
182-
if (element.equalsIgnoreCase("roll")) {
236+
if (element.equalsIgnoreCase(PropertyName.ROLL.value)) {
183237
roll = true;
184-
} else if (element.equalsIgnoreCase("strength")) {
238+
} else if (element.equalsIgnoreCase(PropertyName.STRENGTH.value)) {
185239
strength = true;
186-
} else if (element.equalsIgnoreCase("AAroll")) {
240+
} else if (element.equalsIgnoreCase(PropertyName.AA_ROLL.value)) {
187241
aaRoll = true;
188-
} else if (element.equalsIgnoreCase("AAstrength")) {
242+
} else if (element.equalsIgnoreCase(PropertyName.AA_STRENGTH.value)) {
189243
aaStrength = true;
190244
} else {
191245
throw new GameParseException(
@@ -351,11 +405,11 @@ static void addRule(final UnitType type, final GameData data, final boolean firs
351405
final UnitSupportAttachment rule = new UnitSupportAttachment(attachmentName, type, data);
352406
rule.setBonus(1);
353407
rule.setBonusType(Constants.OLD_ART_RULE_NAME);
354-
rule.setDice("strength");
355-
rule.setFaction("allied");
408+
rule.setDice(PropertyName.STRENGTH.value);
409+
rule.setFaction(PropertyName.ALLIED.value);
356410
rule.setImpArtTech(true);
357411
rule.setNumber(first ? 0 : 1);
358-
rule.setSide("offence");
412+
rule.setSide(PropertyName.OFFENCE.value);
359413
rule.addUnitTypes(first ? Set.of(type) : getTargets(data.getUnitTypeList()));
360414
if (!first) {
361415
rule.setPlayers(new ArrayList<>(data.getPlayerList().getPlayers()));
@@ -414,54 +468,9 @@ static void addTarget(final UnitType type, final GameData data) throws GameParse
414468
@Override
415469
public void validate(final GameState data) {}
416470

471+
@SuppressWarnings("unchecked")
417472
@Override
418473
public Optional<MutableProperty<?>> getPropertyOrEmpty(final @NonNls String propertyName) {
419-
return switch (propertyName) {
420-
case UNIT_TYPE ->
421-
Optional.of(
422-
MutableProperty.of(
423-
this::setUnitType, this::setUnitType, this::getUnitType, this::resetUnitType));
424-
case "offence" -> Optional.of(MutableProperty.ofReadOnly(this::getOffence));
425-
case "defence" -> Optional.of(MutableProperty.ofReadOnly(this::getDefence));
426-
case "roll" -> Optional.of(MutableProperty.ofReadOnly(this::getRoll));
427-
case "strength" -> Optional.of(MutableProperty.ofReadOnly(this::getStrength));
428-
case "aaRoll" -> Optional.of(MutableProperty.ofReadOnly(this::getAaRoll));
429-
case "aaStrength" -> Optional.of(MutableProperty.ofReadOnly(this::getAaStrength));
430-
case BONUS ->
431-
Optional.of(
432-
MutableProperty.of(this::setBonus, this::setBonus, this::getBonus, this::resetBonus));
433-
case "number" ->
434-
Optional.of(
435-
MutableProperty.of(
436-
this::setNumber, this::setNumber, this::getNumber, this::resetNumber));
437-
case "allied" -> Optional.of(MutableProperty.ofReadOnly(this::getAllied));
438-
case "enemy" -> Optional.of(MutableProperty.ofReadOnly(this::getEnemy));
439-
case BONUS_TYPE ->
440-
Optional.of(
441-
MutableProperty.of(
442-
this::setBonusType,
443-
this::setBonusType,
444-
this::getBonusType,
445-
this::resetBonusType));
446-
case "players" ->
447-
Optional.of(
448-
MutableProperty.of(
449-
this::setPlayers, this::setPlayers, this::getPlayers, this::resetPlayers));
450-
case "impArtTech" ->
451-
Optional.of(
452-
MutableProperty.of(
453-
this::setImpArtTech,
454-
this::setImpArtTech,
455-
this::getImpArtTech,
456-
this::resetImpArtTech));
457-
case DICE ->
458-
Optional.of(MutableProperty.ofString(this::setDice, this::getDice, this::resetDice));
459-
case "side" ->
460-
Optional.of(MutableProperty.ofString(this::setSide, this::getSide, this::resetSide));
461-
case "faction" ->
462-
Optional.of(
463-
MutableProperty.ofString(this::setFaction, this::getFaction, this::resetFaction));
464-
default -> Optional.empty();
465-
};
474+
return PropertyEnum.getPropertyOrEmpty(PropertyName.class, propertyName, this);
466475
}
467476
}

0 commit comments

Comments
 (0)