Range rework (#2284)

* Range rework

* Range.Int
This commit is contained in:
TheMode 2024-07-21 18:09:28 +02:00 committed by Matt Worzala
parent 3a8157f263
commit 9498b28fda
14 changed files with 104 additions and 247 deletions

View File

@ -5,10 +5,10 @@ import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.entity.EntityType;
import net.minestom.server.entity.GameMode;
import net.minestom.server.utils.Range;
import net.minestom.server.utils.StringUtils;
import net.minestom.server.utils.binary.BinaryWriter;
import net.minestom.server.utils.entity.EntityFinder;
import net.minestom.server.utils.math.IntRange;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -252,7 +252,7 @@ public class ArgumentEntity extends Argument<EntityFinder> {
break;
case "level":
try {
final IntRange level = Argument.parse(sender, new ArgumentIntRange(value));
final Range.Int level = Argument.parse(sender, new ArgumentIntRange(value));
entityFinder.setLevel(level);
} catch (ArgumentSyntaxException e) {
throw new ArgumentSyntaxException("Invalid level number", input, INVALID_ARGUMENT_VALUE);
@ -260,7 +260,7 @@ public class ArgumentEntity extends Argument<EntityFinder> {
break;
case "distance":
try {
final IntRange distance = Argument.parse(sender, new ArgumentIntRange(value));
final Range.Int distance = Argument.parse(sender, new ArgumentIntRange(value));
entityFinder.setDistance(distance);
} catch (ArgumentSyntaxException e) {
throw new ArgumentSyntaxException("Invalid level number", input, INVALID_ARGUMENT_VALUE);

View File

@ -1,16 +1,16 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.utils.math.FloatRange;
import net.minestom.server.utils.Range;
/**
* Represents an argument which will give you an {@link FloatRange}.
* Represents an argument which will give you an {@link Range.Float}.
* <p>
* Example: ..3, 3.., 5..10, 15
*/
public class ArgumentFloatRange extends ArgumentRange<FloatRange, Float> {
public class ArgumentFloatRange extends ArgumentRange<Range.Float, Float> {
public ArgumentFloatRange(String id) {
super(id, -Float.MAX_VALUE, Float.MAX_VALUE, Float::parseFloat, FloatRange::new);
super(id, -Float.MAX_VALUE, Float.MAX_VALUE, Float::parseFloat, Range.Float::new);
}
@Override

View File

@ -1,16 +1,16 @@
package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.utils.math.IntRange;
import net.minestom.server.utils.Range;
/**
* Represents an argument which will give you an {@link IntRange}.
* Represents an argument which will give you an {@link Range.Int}.
* <p>
* Example: ..3, 3.., 5..10, 15
*/
public class ArgumentIntRange extends ArgumentRange<IntRange, Integer> {
public class ArgumentIntRange extends ArgumentRange<Range.Int, Integer> {
public ArgumentIntRange(String id) {
super(id, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt, IntRange::new);
super(id, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer::parseInt, Range.Int::new);
}
@Override

View File

@ -3,7 +3,7 @@ package net.minestom.server.command.builder.arguments.minecraft;
import net.minestom.server.command.CommandSender;
import net.minestom.server.command.builder.arguments.Argument;
import net.minestom.server.command.builder.exception.ArgumentSyntaxException;
import net.minestom.server.utils.math.Range;
import net.minestom.server.utils.Range;
import org.jetbrains.annotations.NotNull;
import java.util.function.BiFunction;

View File

@ -0,0 +1,68 @@
package net.minestom.server.utils;
/**
* Represents the base for any data type that is numeric.
*
* @param <T> The type numeric of the range object.
*/
public sealed interface Range<T extends Number> {
record Byte(byte min, byte max) implements Range<java.lang.Byte> {
public Byte(byte value) {
this(value, value);
}
public boolean inRange(byte value) {
return value >= min && value <= max;
}
}
record Short(short min, short max) implements Range<java.lang.Short> {
public Short(short value) {
this(value, value);
}
public boolean inRange(short value) {
return value >= min && value <= max;
}
}
record Int(int min, int max) implements Range<java.lang.Integer> {
public Int(int value) {
this(value, value);
}
public boolean inRange(int value) {
return value >= min && value <= max;
}
}
record Long(long min, long max) implements Range<java.lang.Long> {
public Long(long value) {
this(value, value);
}
public boolean inRange(long value) {
return value >= min && value <= max;
}
}
record Float(float min, float max) implements Range<java.lang.Float> {
public Float(float value) {
this(value, value);
}
public boolean inRange(float value) {
return value >= min && value <= max;
}
}
record Double(double min, double max) implements Range<java.lang.Double> {
public Double(double value) {
this(value, value);
}
public boolean inRange(double value) {
return value >= min && value <= max;
}
}
}

View File

@ -13,7 +13,7 @@ import net.minestom.server.entity.Player;
import net.minestom.server.instance.Instance;
import net.minestom.server.network.ConnectionManager;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.utils.math.IntRange;
import net.minestom.server.utils.Range;
import net.minestom.server.utils.validate.Check;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -37,7 +37,7 @@ public class EntityFinder {
// Position
private Point startPosition;
private Float dx, dy, dz;
private IntRange distance;
private Range.Int distance;
// By traits
private Integer limit;
@ -50,7 +50,7 @@ public class EntityFinder {
// Players specific
private final ToggleableMap<GameMode> gameModes = new ToggleableMap<>();
private IntRange level;
private Range.Int level;
public EntityFinder setTargetSelector(@NotNull TargetSelector targetSelector) {
this.targetSelector = targetSelector;
@ -67,7 +67,7 @@ public class EntityFinder {
return this;
}
public EntityFinder setDistance(@NotNull IntRange distance) {
public EntityFinder setDistance(@NotNull Range.Int distance) {
this.distance = distance;
return this;
}
@ -77,7 +77,7 @@ public class EntityFinder {
return this;
}
public EntityFinder setLevel(@NotNull IntRange level) {
public EntityFinder setLevel(@NotNull Range.Int level) {
this.level = level;
return this;
}
@ -148,8 +148,8 @@ public class EntityFinder {
// Distance argument
if (distance != null) {
final int minDistance = distance.getMinimum();
final int maxDistance = distance.getMaximum();
final int minDistance = distance.min();
final int maxDistance = distance.max();
result = result.stream()
.filter(entity -> MathUtils.isBetween(entity.getPosition().distanceSquared(pos), minDistance * minDistance, maxDistance * maxDistance))
.toList();
@ -195,8 +195,8 @@ public class EntityFinder {
// Level
if (level != null) {
final int minLevel = level.getMinimum();
final int maxLevel = level.getMaximum();
final int minLevel = level.min();
final int maxLevel = level.max();
result = result.stream()
.filter(Player.class::isInstance)
.filter(entity -> MathUtils.isBetween(((Player) entity).getLevel(), minLevel, maxLevel))

View File

@ -1,20 +0,0 @@
package net.minestom.server.utils.math;
public class ByteRange extends Range<Byte> {
public ByteRange(Byte minimum, Byte maximum) {
super(minimum, maximum);
}
public ByteRange(Byte value) {
super(value);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isInRange(Byte value) {
return value >= this.getMinimum() && value <= this.getMaximum();
}
}

View File

@ -1,20 +0,0 @@
package net.minestom.server.utils.math;
public class DoubleRange extends Range<Double> {
public DoubleRange(Double minimum, Double maximum) {
super(minimum, maximum);
}
public DoubleRange(Double value) {
super(value);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isInRange(Double value) {
return value >= this.getMinimum() && value <= this.getMaximum();
}
}

View File

@ -1,19 +0,0 @@
package net.minestom.server.utils.math;
public class FloatRange extends Range<Float> {
public FloatRange(Float minimum, Float maximum) {
super(minimum, maximum);
}
public FloatRange(Float value) {
super(value);
}
/** {@inheritDoc} */
@Override
public boolean isInRange(Float value) {
return value >= this.getMinimum() && value <= this.getMaximum();
}
}

View File

@ -1,20 +0,0 @@
package net.minestom.server.utils.math;
public class IntRange extends Range<Integer> {
public IntRange(Integer minimum, Integer maximum) {
super(minimum, maximum);
}
public IntRange(Integer value) {
super(value);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isInRange(Integer value) {
return value >= this.getMinimum() && value <= this.getMaximum();
}
}

View File

@ -1,20 +0,0 @@
package net.minestom.server.utils.math;
public class LongRange extends Range<Long> {
public LongRange(Long minimum, Long maximum) {
super(minimum, maximum);
}
public LongRange(Long value) {
super(value);
}
/**
* {@inheritDoc}
*/
@Override
public boolean isInRange(Long value) {
return value >= this.getMinimum() && value <= this.getMaximum();
}
}

View File

@ -1,93 +0,0 @@
package net.minestom.server.utils.math;
import java.util.Objects;
/**
* Represents the base for any data type that is numeric.
*
* @param <T> The type numeric of the range object.
*/
public abstract class Range<T> {
private T minimum;
private T maximum;
/**
* Constructs a new {@link Range} with a {@code minimum} and a {@code maximum} value.
*
* @param minimum The minimum of the range.
* @param maximum The maximum of the range.
*/
public Range(T minimum, T maximum) {
this.minimum = minimum;
this.maximum = maximum;
}
/**
* Constructs a new {@link Range} with the {@code value}.
*
* @param value The value of the range.
*/
public Range(T value) {
this(value, value);
}
/**
* Retrieves the minimum value of the range.
*
* @return The range's minimum value.
*/
public T getMinimum() {
return this.minimum;
}
/**
* Changes the minimum value of the range.
*
* @param minimum The new minimum value.
*/
public void setMinimum(T minimum) {
this.minimum = minimum;
}
/**
* Retrieves the maximum value of the range.
*
* @return The range's maximum value.
*/
public T getMaximum() {
return this.maximum;
}
/**
* Changes the maximum value of the range.
*
* @param maximum The new maximum value.
*/
public void setMaximum(T maximum) {
this.maximum = maximum;
}
/**
* Whether the given {@code value} is in range of the minimum and the maximum.
*
* @param value The value to be checked.
* @return {@code true} if the value in the range of {@code minimum} and {@code maximum},
* otherwise {@code false}.
*/
public abstract boolean isInRange(T value);
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Range<?> range = (Range<?>) o;
return Objects.equals(minimum, range.minimum) && Objects.equals(maximum, range.maximum);
}
@Override
public int hashCode() {
return Objects.hash(minimum, maximum);
}
}

View File

@ -1,18 +0,0 @@
package net.minestom.server.utils.math;
public class ShortRange extends Range<Short> {
public ShortRange(Short minimum, Short maximum) {
super(minimum, maximum);
}
public ShortRange(Short value) {
super(value);
}
/** {@inheritDoc} */
@Override
public boolean isInRange(Short value) {
return value >= this.getMinimum() && value <= this.getMaximum();
}
}

View File

@ -23,9 +23,8 @@ import net.minestom.server.item.Material;
import net.minestom.server.item.component.CustomData;
import net.minestom.server.particle.Particle;
import net.minestom.server.tag.Tag;
import net.minestom.server.utils.Range;
import net.minestom.server.utils.location.RelativeVec;
import net.minestom.server.utils.math.FloatRange;
import net.minestom.server.utils.math.IntRange;
import net.minestom.server.utils.time.TimeUnit;
import org.junit.jupiter.api.Test;
@ -129,14 +128,14 @@ public class ArgumentTypeTest {
@Test
public void testArgumentFloatRange() {
var arg = ArgumentType.FloatRange("float_range");
assertArg(arg, new FloatRange(0f, 50f), "0..50");
assertArg(arg, new FloatRange(0f, 0f), "0..0");
assertArg(arg, new FloatRange(-50f, 0f), "-50..0");
assertArg(arg, new FloatRange(-Float.MAX_VALUE, 50f), "..50");
assertArg(arg, new FloatRange(0f, Float.MAX_VALUE), "0..");
assertArg(arg, new FloatRange(-Float.MAX_VALUE, Float.MAX_VALUE), "-3.4028235E38..3.4028235E38");
assertArg(arg, new FloatRange(0.5f, 24f), "0.5..24");
assertArg(arg, new FloatRange(12f, 45.6f), "12..45.6");
assertArg(arg, new Range.Float(0f, 50f), "0..50");
assertArg(arg, new Range.Float(0f, 0f), "0..0");
assertArg(arg, new Range.Float(-50f, 0f), "-50..0");
assertArg(arg, new Range.Float(-Float.MAX_VALUE, 50f), "..50");
assertArg(arg, new Range.Float(0f, Float.MAX_VALUE), "0..");
assertArg(arg, new Range.Float(-Float.MAX_VALUE, Float.MAX_VALUE), "-3.4028235E38..3.4028235E38");
assertArg(arg, new Range.Float(0.5f, 24f), "0.5..24");
assertArg(arg, new Range.Float(12f, 45.6f), "12..45.6");
assertInvalidArg(arg, "..");
assertInvalidArg(arg, "0..50..");
}
@ -145,12 +144,12 @@ public class ArgumentTypeTest {
public void testArgumentIntRange() {
var arg = ArgumentType.IntRange("int_range");
assertArg(arg, new IntRange(0, 50), "0..50");
assertArg(arg, new IntRange(0, 0), "0..0");
assertArg(arg, new IntRange(-50, 0), "-50..0");
assertArg(arg, new IntRange(Integer.MIN_VALUE, 50), "..50");
assertArg(arg, new IntRange(0, Integer.MAX_VALUE), "0..");
assertArg(arg, new IntRange(Integer.MIN_VALUE, Integer.MAX_VALUE), "-2147483648..2147483647");
assertArg(arg, new Range.Int(0, 50), "0..50");
assertArg(arg, new Range.Int(0, 0), "0..0");
assertArg(arg, new Range.Int(-50, 0), "-50..0");
assertArg(arg, new Range.Int(Integer.MIN_VALUE, 50), "..50");
assertArg(arg, new Range.Int(0, Integer.MAX_VALUE), "0..");
assertArg(arg, new Range.Int(Integer.MIN_VALUE, Integer.MAX_VALUE), "-2147483648..2147483647");
assertInvalidArg(arg, "..");
assertInvalidArg(arg, "-2147483649..2147483647");