Skip to content

Commit

Permalink
Implement array variable type
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Herrera <[email protected]>
  • Loading branch information
Pablete1234 committed Nov 12, 2023
1 parent 1cecddb commit fea7b43
Show file tree
Hide file tree
Showing 15 changed files with 366 additions and 102 deletions.
10 changes: 7 additions & 3 deletions core/src/main/java/tc/oc/pgm/action/ActionParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,14 @@ public <T extends Filterable<?>> SetVariableAction<T> parseSetVariable(Element e
+ scope.getSimpleName(),
el);

String expression = Node.fromRequiredAttr(el, "value").getValue();
Formula<T> formula =
Formula.of(
expression, variables.getVariableNames(scope), variables.getContextBuilder(scope));
Formula.of(Node.fromRequiredAttr(el, "value").getValue(), variables.getContext(scope));

if (var.isIndexed()) {
Formula<T> idx =
Formula.of(Node.fromRequiredAttr(el, "index").getValue(), variables.getContext(scope));
return new SetVariableAction.Indexed<>(scope, var, idx, formula);
}

return new SetVariableAction<>(scope, var, formula);
}
Expand Down
23 changes: 21 additions & 2 deletions core/src/main/java/tc/oc/pgm/action/actions/SetVariableAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
import tc.oc.pgm.filters.Filterable;
import tc.oc.pgm.util.math.Formula;
import tc.oc.pgm.variables.VariableDefinition;
import tc.oc.pgm.variables.types.IndexedVariable;

public class SetVariableAction<T extends Filterable<?>> extends AbstractAction<T> {

private final VariableDefinition<?> variable;
private final Formula<T> formula;
protected final VariableDefinition<?> variable;
protected final Formula<T> formula;

public SetVariableAction(Class<T> scope, VariableDefinition<?> variable, Formula<T> formula) {
super(scope);
Expand All @@ -19,4 +20,22 @@ public SetVariableAction(Class<T> scope, VariableDefinition<?> variable, Formula
public void trigger(T t) {
variable.getVariable(t.getMatch()).setValue(t, formula.applyAsDouble(t));
}

public static class Indexed<T extends Filterable<?>> extends SetVariableAction<T> {

private final Formula<T> idx;

public Indexed(
Class<T> scope, VariableDefinition<?> variable, Formula<T> idx, Formula<T> formula) {
super(scope, variable, formula);
this.idx = idx;
}

@Override
@SuppressWarnings("unchecked")
public void trigger(T t) {
((IndexedVariable<T>) variable.getVariable(t.getMatch()))
.setValue(t, (int) idx.applyAsDouble(t), formula.applyAsDouble(t));
}
}
}
22 changes: 20 additions & 2 deletions core/src/main/java/tc/oc/pgm/command/MapDevCommand.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package tc.oc.pgm.command;

import static net.kyori.adventure.text.Component.join;
import static net.kyori.adventure.text.Component.text;
import static tc.oc.pgm.command.util.ParserConstants.CURRENT;

Expand All @@ -11,7 +12,10 @@
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.ComponentLike;
import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.command.CommandSender;
import tc.oc.pgm.api.Permissions;
Expand All @@ -22,6 +26,7 @@
import tc.oc.pgm.util.PrettyPaginatedComponentResults;
import tc.oc.pgm.util.text.TextFormatter;
import tc.oc.pgm.variables.Variable;
import tc.oc.pgm.variables.types.IndexedVariable;

public class MapDevCommand {

Expand Down Expand Up @@ -64,8 +69,21 @@ public void showVariables(
page,
resultsPerPage,
header,
(v, i) ->
text().append(text(v.getId() + ": ", NamedTextColor.AQUA), text(v.getValue(target))));
(v, pageIndex) -> {
ComponentLike value;
if (v.isIndexed()) {
IndexedVariable<?> idx = (IndexedVariable<?>) v;
List<Component> values =
IntStream.range(0, idx.size())
.mapToObj(i -> text(idx.getValue(target, i)))
.collect(Collectors.toList());
value = join(JoinConfiguration.commas(true), values);
} else {
value = text(v.getValue(target));
}

return text().append(text(v.getId() + ": ", NamedTextColor.AQUA), value);
});
}

@CommandMethod("variable set <variable> <value> [target]")
Expand Down
44 changes: 23 additions & 21 deletions core/src/main/java/tc/oc/pgm/rotation/vote/MapVotePicker.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.util.NavigableMap;
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.bukkit.configuration.ConfigurationSection;
Expand All @@ -20,6 +19,7 @@
import tc.oc.pgm.api.map.MapTag;
import tc.oc.pgm.rotation.MapPoolManager;
import tc.oc.pgm.util.math.Formula;
import tc.oc.pgm.util.math.VariableExpressionContext;

/**
* Responsible for picking the set of maps that will be on the vote. It's able to apply any
Expand All @@ -35,7 +35,7 @@ public class MapVotePicker {
// with larger numbers.
private static final double MINIMUM_WEIGHT = 0.00000001;

private static final Formula<Context> DEFAULT_MODIFIER = c -> Math.pow(c.score, 2);
private static final Formula<Context> DEFAULT_MODIFIER = c -> Math.pow(c.getVariable("score"), 2);

private final MapPoolManager manager;
private final Formula<Context> modifier;
Expand All @@ -46,7 +46,11 @@ public static MapVotePicker of(MapPoolManager manager, ConfigurationSection conf

Formula<Context> formula = DEFAULT_MODIFIER;
try {
formula = Formula.of(config.getString("modifier"), Context.getKeys(), DEFAULT_MODIFIER);
formula =
Formula.of(
config.getString("modifier"),
Formula.ContextFactory.ofStatic(new Context().getVariables()),
DEFAULT_MODIFIER);
} catch (IllegalArgumentException e) {
PGM.get()
.getLogger()
Expand Down Expand Up @@ -131,32 +135,30 @@ private double getRepeatedGamemodes(List<MapInfo> selected, MapInfo map) {
return selected.stream().filter(s -> !Collections.disjoint(gamemodes, s.getTags())).count();
}

private static final class Context implements Supplier<Map<String, Double>> {
private double score;
private double sameGamemode;
private double mapsize;
private double players;
private static final class Context implements VariableExpressionContext {
private final ImmutableMap<String, Double> values;

public Context(double score, double sameGamemode, double mapsize, double players) {
this.score = score;
this.sameGamemode = sameGamemode;
this.mapsize = mapsize;
this.players = players;
this.values =
ImmutableMap.of(
"score", score,
"same_gamemode", sameGamemode,
"mapsize", mapsize,
"players", players);
}

private Context() {}
private Context() {
this(0, 0, 0, 0);
}

public static Set<String> getKeys() {
return new Context().get().keySet();
@Override
public Set<String> getVariables() {
return values.keySet();
}

@Override
public Map<String, Double> get() {
return ImmutableMap.of(
"score", score,
"same_gamemode", sameGamemode,
"mapsize", mapsize,
"players", players);
public Double getVariable(String s) {
return values.get(s);
}
}
}
4 changes: 4 additions & 0 deletions core/src/main/java/tc/oc/pgm/variables/Variable.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ default String getId() {

void setValue(Filterable<?> context, double value);

default boolean isIndexed() {
return getDefinition().isIndexed();
}

default void postLoad(Match match) {}
}
26 changes: 0 additions & 26 deletions core/src/main/java/tc/oc/pgm/variables/VariableContextBuilder.java

This file was deleted.

13 changes: 12 additions & 1 deletion core/src/main/java/tc/oc/pgm/variables/VariableDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@
public class VariableDefinition<T extends Filterable<?>> extends SelfIdentifyingFeatureDefinition {

private final Class<T> scope;
private final boolean isDynamic;
private final boolean isDynamic, isIndexed;
private final Function<VariableDefinition<T>, Variable<T>> builder;

public VariableDefinition(
String id,
Class<T> scope,
boolean isDynamic,
boolean isIndexed,
Function<VariableDefinition<T>, Variable<T>> builder) {
super(id);
this.scope = scope;
this.isDynamic = isDynamic;
this.isIndexed = isIndexed;
this.builder = builder;
}

public static <T extends Filterable<?>> VariableDefinition<T> ofStatic(
String id, Class<T> scope, Function<VariableDefinition<T>, Variable<T>> builder) {
return new VariableDefinition<>(id, scope, false, false, builder);
}

public Class<T> getScope() {
return scope;
}
Expand All @@ -30,6 +37,10 @@ public boolean isDynamic() {
return isDynamic;
}

public boolean isIndexed() {
return isIndexed;
}

public Variable<T> buildInstance() {
return builder.apply(this);
}
Expand Down
25 changes: 20 additions & 5 deletions core/src/main/java/tc/oc/pgm/variables/VariableParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import tc.oc.pgm.util.xml.InvalidXMLException;
import tc.oc.pgm.util.xml.Node;
import tc.oc.pgm.util.xml.XMLUtils;
import tc.oc.pgm.variables.types.ArrayVariable;
import tc.oc.pgm.variables.types.BlitzVariable;
import tc.oc.pgm.variables.types.DummyVariable;
import tc.oc.pgm.variables.types.MaxBuildVariable;
Expand Down Expand Up @@ -62,18 +63,28 @@ public VariableDefinition<?> parseDummy(Element el, String id) throws InvalidXML
Integer excl =
XMLUtils.parseNumberInRange(
Node.fromAttr(el, "exclusive"), Integer.class, Range.closed(1, 50), null);
return new VariableDefinition<>(id, scope, true, vd -> new DummyVariable<>(vd, def, excl));
return new VariableDefinition<>(
id, scope, true, false, vd -> new DummyVariable<>(vd, def, excl));
}

@MethodParser("array")
public VariableDefinition<?> parseArray(Element el, String id) throws InvalidXMLException {
Class<? extends Filterable<?>> scope = Filterables.parse(Node.fromRequiredAttr(el, "scope"));
int size = XMLUtils.parseNumber(Node.fromRequiredAttr(el, "size"), Integer.class);
double def = XMLUtils.parseNumber(Node.fromAttr(el, "default"), Double.class, 0d);
return new VariableDefinition<>(
id, scope, true, true, vd -> new ArrayVariable<>(vd, size, def));
}

@MethodParser("lives")
public VariableDefinition<MatchPlayer> parseBlitzLives(Element el, String id)
throws InvalidXMLException {
return new VariableDefinition<>(id, MatchPlayer.class, false, BlitzVariable::new);
return VariableDefinition.ofStatic(id, MatchPlayer.class, BlitzVariable::new);
}

@MethodParser("score")
public VariableDefinition<Party> parseScore(Element el, String id) throws InvalidXMLException {
return new VariableDefinition<>(id, Party.class, false, ScoreVariable::new);
return VariableDefinition.ofStatic(id, Party.class, ScoreVariable::new);
}

@MethodParser("with-team")
Expand All @@ -92,11 +103,15 @@ public VariableDefinition<Match> parseTeamAdapter(Element el, String id)
factory.getFeatures().createReference(Node.fromRequiredAttr(el, "team"), TeamFactory.class);

return new VariableDefinition<>(
id, Match.class, var.isDynamic(), vd -> new TeamVariableAdapter(vd, var, team));
id,
Match.class,
var.isDynamic(),
var.isIndexed(),
vd -> new TeamVariableAdapter(vd, var, team));
}

@MethodParser("maxbuildheight")
public VariableDefinition<Match> parseMaxBuild(Element el, String id) throws InvalidXMLException {
return new VariableDefinition<>(id, Match.class, false, MaxBuildVariable::new);
return VariableDefinition.ofStatic(id, Match.class, MaxBuildVariable::new);
}
}
Loading

0 comments on commit fea7b43

Please sign in to comment.