mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-04-14 19:56:19 +00:00
more refactors
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package com.dfsek.terra.api.profiler;
|
||||
|
||||
public class ProfileFrame implements AutoCloseable {
|
||||
private final Runnable action;
|
||||
|
||||
public ProfileFrame(Runnable action) {
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
action.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.dfsek.terra.api.profiler;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface Profiler {
|
||||
/**
|
||||
* Push a frame to this profiler.
|
||||
*
|
||||
* @param frame ID of frame.
|
||||
*/
|
||||
void push(String frame);
|
||||
|
||||
/**
|
||||
* Pop a frame from this profiler.
|
||||
*
|
||||
* @param frame ID of frame. Must match ID
|
||||
* at the top of the profiler stack.
|
||||
*/
|
||||
void pop(String frame);
|
||||
|
||||
/**
|
||||
* Start profiling.
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Stop profiling.
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* Get the profiler data.
|
||||
*
|
||||
* @return Profiler data.
|
||||
*/
|
||||
Map<String, Timings> getTimings();
|
||||
|
||||
/**
|
||||
* Return a {@link AutoCloseable} implementation that
|
||||
* may be used in a try-with-resources statement for
|
||||
* more intuitive profiling, with auto-push/pop.
|
||||
*
|
||||
* @param frame ID of frame.
|
||||
* @return {@link AutoCloseable} implementation for use
|
||||
* in try-with-resources.
|
||||
*/
|
||||
default ProfileFrame profile(String frame) {
|
||||
push(frame);
|
||||
return new ProfileFrame(() -> pop(frame));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the profiler data.
|
||||
*/
|
||||
void reset();
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.dfsek.terra.api.profiler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Timings {
|
||||
private final Map<String, Timings> subItems = new HashMap<>();
|
||||
|
||||
private final List<Long> timings = new ArrayList<>();
|
||||
|
||||
public void addTime(long time) {
|
||||
timings.add(time);
|
||||
}
|
||||
|
||||
public List<Long> getTimings() {
|
||||
return timings;
|
||||
}
|
||||
|
||||
public double average() {
|
||||
return (double) timings.stream().reduce(0L, Long::sum) / timings.size();
|
||||
}
|
||||
|
||||
public long max() {
|
||||
return timings.stream().mapToLong(Long::longValue).max().orElse(0L);
|
||||
}
|
||||
|
||||
public long min() {
|
||||
return timings.stream().mapToLong(Long::longValue).min().orElse(0L);
|
||||
}
|
||||
|
||||
public double sum() {
|
||||
return timings.stream().mapToDouble(Long::doubleValue).sum();
|
||||
}
|
||||
|
||||
public Timings getSubItem(String id) {
|
||||
return subItems.computeIfAbsent(id, s -> new Timings());
|
||||
}
|
||||
|
||||
private String toString(int indent, Timings parent, Set<Integer> branches) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append((double) min() / 1000000).append("ms min / ").append(average() / 1000000).append("ms avg / ")
|
||||
.append((double) max() / 1000000).append("ms max (").append(timings.size()).append(" samples, ")
|
||||
.append((sum() / parent.sum()) * 100).append("% of parent)");
|
||||
|
||||
List<String> frames = new ArrayList<>();
|
||||
Set<Integer> newBranches = new HashSet<>(branches);
|
||||
newBranches.add(indent);
|
||||
subItems.forEach((id, timings) -> frames.add(id + ": " + timings.toString(indent + 1, this, newBranches)));
|
||||
|
||||
for(int i = 0; i < frames.size(); i++) {
|
||||
builder.append('\n');
|
||||
for(int j = 0; j < indent; j++) {
|
||||
if(branches.contains(j)) builder.append("│ ");
|
||||
else builder.append(" ");
|
||||
}
|
||||
if(i == frames.size() - 1 && !frames.get(i).contains("\n")) builder.append("└───");
|
||||
else builder.append("├───");
|
||||
builder.append(frames.get(i));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toString(1, this, Collections.emptySet());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.dfsek.terra.api.structure.buffer;
|
||||
|
||||
import com.dfsek.terra.api.vector.Location;
|
||||
|
||||
public interface Buffer {
|
||||
Buffer addItem(BufferedItem item, Location location);
|
||||
|
||||
Location getOrigin();
|
||||
|
||||
String getMark(Location location);
|
||||
|
||||
Buffer setMark(String mark, Location location);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.dfsek.terra.api.structure.buffer;
|
||||
|
||||
import com.dfsek.terra.api.vector.Location;
|
||||
import com.dfsek.terra.api.world.Chunk;
|
||||
|
||||
public interface BufferedItem {
|
||||
void paste(Location origin);
|
||||
|
||||
default void paste(Chunk chunk, Location origin) {
|
||||
origin.setWorld(chunk.getWorld()); // Fabric weirdness
|
||||
paste(origin);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.dfsek.terra.api.structure.rotation;
|
||||
|
||||
import net.jafama.FastMath;
|
||||
|
||||
public enum Rotation {
|
||||
|
||||
CW_90(90), CW_180(180), CCW_90(270), NONE(0);
|
||||
private final int degrees;
|
||||
|
||||
Rotation(int degrees) {
|
||||
this.degrees = degrees;
|
||||
}
|
||||
|
||||
public static Rotation fromDegrees(int deg) {
|
||||
switch(FastMath.floorMod(deg, 360)) {
|
||||
case 0:
|
||||
return Rotation.NONE;
|
||||
case 90:
|
||||
return Rotation.CW_90;
|
||||
case 180:
|
||||
return Rotation.CW_180;
|
||||
case 270:
|
||||
return Rotation.CCW_90;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public int getDegrees() {
|
||||
return degrees;
|
||||
}
|
||||
|
||||
public Rotation inverse() {
|
||||
switch(this) {
|
||||
case NONE:
|
||||
return NONE;
|
||||
case CCW_90:
|
||||
return CW_90;
|
||||
case CW_90:
|
||||
return CCW_90;
|
||||
case CW_180:
|
||||
return CW_180;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public Rotation rotate(Rotation rotation) {
|
||||
return fromDegrees(this.getDegrees() + rotation.getDegrees());
|
||||
}
|
||||
|
||||
public enum Axis {
|
||||
X, Y, Z
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,291 @@
|
||||
package com.dfsek.terra.api.structure.rotation;
|
||||
|
||||
import com.dfsek.terra.api.vector.Vector2;
|
||||
import com.dfsek.terra.api.block.Axis;
|
||||
import com.dfsek.terra.api.block.BlockData;
|
||||
import com.dfsek.terra.api.block.BlockFace;
|
||||
import com.dfsek.terra.api.block.data.Directional;
|
||||
import com.dfsek.terra.api.block.data.MultipleFacing;
|
||||
import com.dfsek.terra.api.block.data.Orientable;
|
||||
import com.dfsek.terra.api.block.data.Rail;
|
||||
import com.dfsek.terra.api.block.data.RedstoneWire;
|
||||
import com.dfsek.terra.api.block.data.Rotatable;
|
||||
import com.dfsek.terra.api.block.data.Wall;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.jafama.FastMath;
|
||||
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class RotationUtil {
|
||||
private static final Set<BlockFace> CARDINALS = Sets.newHashSet(BlockFace.NORTH, BlockFace.SOUTH, BlockFace.EAST, BlockFace.WEST);
|
||||
|
||||
/**
|
||||
* Rotate and mirror a coordinate pair.
|
||||
*
|
||||
* @param orig Vector to rotate.
|
||||
* @param r Rotation
|
||||
*/
|
||||
public static void rotateVector(Vector2 orig, Rotation r) {
|
||||
Vector2 copy = orig.clone();
|
||||
switch(r) {
|
||||
case CW_90:
|
||||
copy.setX(orig.getZ()).setZ(-orig.getX());
|
||||
break;
|
||||
case CCW_90:
|
||||
copy.setX(-orig.getZ()).setZ(orig.getX());
|
||||
break;
|
||||
case CW_180:
|
||||
copy.multiply(-1);
|
||||
break;
|
||||
}
|
||||
orig.setX(copy.getX());
|
||||
orig.setZ(copy.getZ());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BlockFace with rotation and mirrors applied to it
|
||||
*
|
||||
* @param f BlockFace to apply rotation to
|
||||
* @param r Rotation
|
||||
* @return Rotated BlockFace
|
||||
*/
|
||||
public static BlockFace getRotatedFace(BlockFace f, Rotation r) {
|
||||
BlockFace n = f;
|
||||
int rotateNum = r.getDegrees() / 90;
|
||||
int rn = faceRotation(f);
|
||||
if(rn >= 0) {
|
||||
n = fromRotation(faceRotation(n) + 4 * rotateNum);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an integer representation of a BlockFace, to perform math on.
|
||||
*
|
||||
* @param f BlockFace to get integer for
|
||||
* @return integer representation of BlockFace
|
||||
*/
|
||||
public static int faceRotation(BlockFace f) {
|
||||
switch(f) {
|
||||
case NORTH:
|
||||
return 0;
|
||||
case NORTH_NORTH_EAST:
|
||||
return 1;
|
||||
case NORTH_EAST:
|
||||
return 2;
|
||||
case EAST_NORTH_EAST:
|
||||
return 3;
|
||||
case EAST:
|
||||
return 4;
|
||||
case EAST_SOUTH_EAST:
|
||||
return 5;
|
||||
case SOUTH_EAST:
|
||||
return 6;
|
||||
case SOUTH_SOUTH_EAST:
|
||||
return 7;
|
||||
case SOUTH:
|
||||
return 8;
|
||||
case SOUTH_SOUTH_WEST:
|
||||
return 9;
|
||||
case SOUTH_WEST:
|
||||
return 10;
|
||||
case WEST_SOUTH_WEST:
|
||||
return 11;
|
||||
case WEST:
|
||||
return 12;
|
||||
case WEST_NORTH_WEST:
|
||||
return 13;
|
||||
case NORTH_WEST:
|
||||
return 14;
|
||||
case NORTH_NORTH_WEST:
|
||||
return 15;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert integer to BlockFace representation
|
||||
*
|
||||
* @param r integer to get BlockFace for
|
||||
* @return BlockFace represented by integer.
|
||||
*/
|
||||
public static BlockFace fromRotation(int r) {
|
||||
switch(FastMath.floorMod(r, 16)) {
|
||||
case 0:
|
||||
return BlockFace.NORTH;
|
||||
case 1:
|
||||
return BlockFace.NORTH_NORTH_EAST;
|
||||
case 2:
|
||||
return BlockFace.NORTH_EAST;
|
||||
case 3:
|
||||
return BlockFace.EAST_NORTH_EAST;
|
||||
case 4:
|
||||
return BlockFace.EAST;
|
||||
case 5:
|
||||
return BlockFace.EAST_SOUTH_EAST;
|
||||
case 6:
|
||||
return BlockFace.SOUTH_EAST;
|
||||
case 7:
|
||||
return BlockFace.SOUTH_SOUTH_EAST;
|
||||
case 8:
|
||||
return BlockFace.SOUTH;
|
||||
case 9:
|
||||
return BlockFace.SOUTH_SOUTH_WEST;
|
||||
case 10:
|
||||
return BlockFace.SOUTH_WEST;
|
||||
case 11:
|
||||
return BlockFace.WEST_SOUTH_WEST;
|
||||
case 12:
|
||||
return BlockFace.WEST;
|
||||
case 13:
|
||||
return BlockFace.WEST_NORTH_WEST;
|
||||
case 14:
|
||||
return BlockFace.NORTH_WEST;
|
||||
case 15:
|
||||
return BlockFace.NORTH_NORTH_WEST;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public static Axis getRotatedAxis(Axis orig, Rotation r) {
|
||||
Axis other = orig;
|
||||
final boolean shouldSwitch = r.equals(Rotation.CW_90) || r.equals(Rotation.CCW_90);
|
||||
switch(orig) {
|
||||
case X:
|
||||
if(shouldSwitch) other = Axis.Z;
|
||||
break;
|
||||
case Z:
|
||||
if(shouldSwitch) other = Axis.X;
|
||||
break;
|
||||
}
|
||||
return other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to rotate the incredibly obnoxious Rail.Shape enum
|
||||
*
|
||||
* @param orig Original shape
|
||||
* @param r Rotate
|
||||
* @return Rotated/mirrored shape
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static Rail.Shape getRotatedRail(Rail.Shape orig, Rotation r) {
|
||||
switch(r) {
|
||||
case CCW_90:
|
||||
switch(orig) {
|
||||
case NORTH_WEST:
|
||||
return Rail.Shape.SOUTH_WEST;
|
||||
case NORTH_SOUTH:
|
||||
return Rail.Shape.EAST_WEST;
|
||||
case SOUTH_WEST:
|
||||
return Rail.Shape.SOUTH_EAST;
|
||||
case SOUTH_EAST:
|
||||
return Rail.Shape.NORTH_EAST;
|
||||
case EAST_WEST:
|
||||
return Rail.Shape.NORTH_SOUTH;
|
||||
case NORTH_EAST:
|
||||
return Rail.Shape.NORTH_WEST;
|
||||
case ASCENDING_EAST:
|
||||
return Rail.Shape.ASCENDING_NORTH;
|
||||
case ASCENDING_WEST:
|
||||
return Rail.Shape.ASCENDING_SOUTH;
|
||||
case ASCENDING_NORTH:
|
||||
return Rail.Shape.ASCENDING_WEST;
|
||||
case ASCENDING_SOUTH:
|
||||
return Rail.Shape.ASCENDING_EAST;
|
||||
}
|
||||
case CW_90:
|
||||
switch(orig) {
|
||||
case NORTH_WEST:
|
||||
return Rail.Shape.NORTH_EAST;
|
||||
case NORTH_SOUTH:
|
||||
return Rail.Shape.EAST_WEST;
|
||||
case SOUTH_WEST:
|
||||
return Rail.Shape.NORTH_WEST;
|
||||
case SOUTH_EAST:
|
||||
return Rail.Shape.SOUTH_WEST;
|
||||
case EAST_WEST:
|
||||
return Rail.Shape.NORTH_SOUTH;
|
||||
case NORTH_EAST:
|
||||
return Rail.Shape.SOUTH_EAST;
|
||||
case ASCENDING_EAST:
|
||||
return Rail.Shape.ASCENDING_SOUTH;
|
||||
case ASCENDING_WEST:
|
||||
return Rail.Shape.ASCENDING_NORTH;
|
||||
case ASCENDING_NORTH:
|
||||
return Rail.Shape.ASCENDING_EAST;
|
||||
case ASCENDING_SOUTH:
|
||||
return Rail.Shape.ASCENDING_WEST;
|
||||
}
|
||||
case CW_180:
|
||||
switch(orig) {
|
||||
case NORTH_WEST:
|
||||
return Rail.Shape.SOUTH_EAST;
|
||||
case NORTH_SOUTH:
|
||||
return Rail.Shape.NORTH_SOUTH;
|
||||
case SOUTH_WEST:
|
||||
return Rail.Shape.NORTH_EAST;
|
||||
case SOUTH_EAST:
|
||||
return Rail.Shape.NORTH_WEST;
|
||||
case EAST_WEST:
|
||||
return Rail.Shape.EAST_WEST;
|
||||
case NORTH_EAST:
|
||||
return Rail.Shape.SOUTH_WEST;
|
||||
case ASCENDING_EAST:
|
||||
return Rail.Shape.ASCENDING_WEST;
|
||||
case ASCENDING_WEST:
|
||||
return Rail.Shape.ASCENDING_EAST;
|
||||
case ASCENDING_NORTH:
|
||||
return Rail.Shape.ASCENDING_SOUTH;
|
||||
case ASCENDING_SOUTH:
|
||||
return Rail.Shape.ASCENDING_NORTH;
|
||||
}
|
||||
}
|
||||
return orig;
|
||||
}
|
||||
|
||||
public static void rotateBlockData(BlockData data, Rotation r) {
|
||||
if(data instanceof Rotatable) {
|
||||
BlockFace rt = getRotatedFace(((Rotatable) data).getRotation(), r);
|
||||
((Rotatable) data).setRotation(rt);
|
||||
} else if(data instanceof Directional) {
|
||||
BlockFace rt = getRotatedFace(((Directional) data).getFacing(), r);
|
||||
((Directional) data).setFacing(rt);
|
||||
} else if(data instanceof MultipleFacing) {
|
||||
MultipleFacing mfData = (MultipleFacing) data;
|
||||
Map<BlockFace, Boolean> faces = new EnumMap<>(BlockFace.class);
|
||||
for(BlockFace f : mfData.getAllowedFaces()) {
|
||||
faces.put(f, mfData.hasFace(f));
|
||||
}
|
||||
for(Map.Entry<BlockFace, Boolean> face : faces.entrySet()) {
|
||||
mfData.setFace(getRotatedFace(face.getKey(), r), face.getValue());
|
||||
}
|
||||
} else if(data instanceof Rail) {
|
||||
Rail.Shape newShape = getRotatedRail(((Rail) data).getShape(), r);
|
||||
((Rail) data).setShape(newShape);
|
||||
} else if(data instanceof Orientable) {
|
||||
Axis newAxis = getRotatedAxis(((Orientable) data).getAxis(), r);
|
||||
((Orientable) data).setAxis(newAxis);
|
||||
} else if(data instanceof RedstoneWire) {
|
||||
Map<BlockFace, RedstoneWire.Connection> connections = new EnumMap<>(BlockFace.class);
|
||||
RedstoneWire rData = (RedstoneWire) data;
|
||||
for(BlockFace f : rData.getAllowedFaces()) {
|
||||
connections.put(f, rData.getFace(f));
|
||||
}
|
||||
for(Map.Entry<BlockFace, RedstoneWire.Connection> e : connections.entrySet()) {
|
||||
rData.setFace(getRotatedFace(e.getKey(), r), e.getValue());
|
||||
}
|
||||
} else if(data instanceof Wall) {
|
||||
Wall wallData = (Wall) data;
|
||||
Map<BlockFace, Wall.Height> faces = new EnumMap<>(BlockFace.class);
|
||||
for(BlockFace b : CARDINALS) faces.put(b, wallData.getHeight(b));
|
||||
for(Map.Entry<BlockFace, Wall.Height> face : faces.entrySet()) {
|
||||
wallData.setHeight(getRotatedFace(face.getKey(), r), face.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
common/api/src/main/java/com/dfsek/terra/api/util/Range.java
Normal file
36
common/api/src/main/java/com/dfsek/terra/api/util/Range.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package com.dfsek.terra.api.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
|
||||
public interface Range extends Iterable<Integer> {
|
||||
boolean isInRange(int test);
|
||||
|
||||
int getMax();
|
||||
|
||||
ConstantRange setMax(int max);
|
||||
|
||||
int getMin();
|
||||
|
||||
ConstantRange setMin(int min);
|
||||
|
||||
int getRange();
|
||||
|
||||
ConstantRange multiply(int mult);
|
||||
|
||||
ConstantRange reflect(int pt);
|
||||
|
||||
int get(Random r);
|
||||
|
||||
ConstantRange intersects(ConstantRange other);
|
||||
|
||||
ConstantRange add(int add);
|
||||
|
||||
ConstantRange sub(int sub);
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
Iterator<Integer> iterator();
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.dfsek.terra.api.util.generic.either;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public final class Either<L, R> {
|
||||
private final L left;
|
||||
private final R right;
|
||||
private final boolean leftPresent;
|
||||
|
||||
private Either(L left, R right, boolean leftPresent) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
this.leftPresent = leftPresent;
|
||||
}
|
||||
|
||||
public static <L1, R1> Either<L1, R1> left(L1 left) {
|
||||
return new Either<>(left, null, true);
|
||||
}
|
||||
|
||||
public static <L1, R1> Either<L1, R1> right(R1 right) {
|
||||
return new Either<>(null, right, false);
|
||||
}
|
||||
|
||||
public Optional<L> getLeft() {
|
||||
if(leftPresent) return Optional.of(left);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<R> getRight() {
|
||||
if(!leftPresent) return Optional.of(right);
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Either<L, R> ifLeft(Consumer<L> action) {
|
||||
if(leftPresent) action.accept(left);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Either<L, R> ifRight(Consumer<R> action) {
|
||||
if(!leftPresent) action.accept(right);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean hasLeft() {
|
||||
return leftPresent;
|
||||
}
|
||||
|
||||
public boolean hasRight() {
|
||||
return !leftPresent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.dfsek.terra.api.util.generic.pair;
|
||||
|
||||
public final class ImmutablePair<L, R> {
|
||||
private final L left;
|
||||
private final R right;
|
||||
|
||||
private static final ImmutablePair<?, ?> NULL = new ImmutablePair<>(null, null);
|
||||
|
||||
private ImmutablePair(L left, R right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public static <L1, R1> ImmutablePair<L1, R1> of(L1 left, R1 right) {
|
||||
return new ImmutablePair<>(left, right);
|
||||
}
|
||||
|
||||
public R getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public L getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <L1, R1> ImmutablePair<L1, R1> ofNull() {
|
||||
return (ImmutablePair<L1, R1>) NULL;
|
||||
}
|
||||
|
||||
public Pair<L, R> mutable() {
|
||||
return Pair.of(left, right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.dfsek.terra.api.util.generic.pair;
|
||||
|
||||
public class Pair<L, R> {
|
||||
private L left;
|
||||
private R right;
|
||||
|
||||
private Pair(L left, R right) {
|
||||
this.left = left;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public static <L1, R1> Pair<L1, R1> of(L1 left, R1 right) {
|
||||
return new Pair<>(left, right);
|
||||
}
|
||||
|
||||
public L getLeft() {
|
||||
return left;
|
||||
}
|
||||
|
||||
public void setLeft(L left) {
|
||||
this.left = left;
|
||||
}
|
||||
|
||||
public R getRight() {
|
||||
return right;
|
||||
}
|
||||
|
||||
public void setRight(R right) {
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public ImmutablePair<L, R> immutable() {
|
||||
return ImmutablePair.of(left, right);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MutableBoolean implements MutablePrimitive<Boolean> {
|
||||
private boolean value;
|
||||
|
||||
public MutableBoolean() {
|
||||
this.value = false;
|
||||
}
|
||||
|
||||
public MutableBoolean(boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean invert() {
|
||||
value = !value;
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull Boolean o) {
|
||||
return Boolean.compare(value, o);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MutableDouble extends MutableNumber<Double> {
|
||||
private static final long serialVersionUID = -2218110876763640053L;
|
||||
|
||||
public MutableDouble(Double value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void increment() {
|
||||
add(1d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decrement() {
|
||||
subtract(1d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Double add) {
|
||||
value += add;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void multiply(Double mul) {
|
||||
value *= mul;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subtract(Double sub) {
|
||||
value -= sub;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void divide(Double divide) {
|
||||
value /= divide;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull Double o) {
|
||||
return Double.compare(value, o);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class MutableInteger extends MutableNumber<Integer> {
|
||||
private static final long serialVersionUID = -4427935901819632745L;
|
||||
|
||||
public MutableInteger(Integer value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
public void increment() {
|
||||
add(1);
|
||||
}
|
||||
|
||||
public void decrement() {
|
||||
subtract(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(Integer add) {
|
||||
value += add;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void multiply(Integer mul) {
|
||||
value *= mul;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void subtract(Integer sub) {
|
||||
value -= sub;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void divide(Integer divide) {
|
||||
value /= divide;
|
||||
}
|
||||
|
||||
public void add(int add) {
|
||||
value += add;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull Integer o) {
|
||||
return Integer.compare(value, o);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
public abstract class MutableNumber<T extends Number> extends Number implements MutablePrimitive<T> {
|
||||
|
||||
private static final long serialVersionUID = 8619508342781664393L;
|
||||
protected T value;
|
||||
|
||||
public MutableNumber(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public abstract void increment();
|
||||
|
||||
public abstract void decrement();
|
||||
|
||||
public abstract void add(T add);
|
||||
|
||||
public abstract void multiply(T mul);
|
||||
|
||||
public abstract void subtract(T sub);
|
||||
|
||||
public abstract void divide(T divide);
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(T value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
return value.intValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
return value.longValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float floatValue() {
|
||||
return value.floatValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double doubleValue() {
|
||||
return value.doubleValue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
|
||||
public interface MutablePrimitive<T> extends Comparable<T>{
|
||||
T get();
|
||||
|
||||
void set(T value);
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
/**
|
||||
* Mutable objects containing primitive types.
|
||||
*/
|
||||
package com.dfsek.terra.api.util.mutable;
|
||||
@@ -11,6 +11,8 @@ public interface Vector2 extends Cloneable {
|
||||
*/
|
||||
double getX();
|
||||
|
||||
Vector2 clone();
|
||||
|
||||
Vector2 setX(double x);
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.dfsek.terra.api.world;
|
||||
|
||||
import com.dfsek.terra.api.math.Range;
|
||||
import com.dfsek.terra.api.vector.Location;
|
||||
import com.dfsek.terra.api.block.Block;
|
||||
import com.dfsek.terra.api.world.Chunk;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface Flora {
|
||||
List<Block> getValidSpawnsAt(Chunk chunk, int x, int z, Range check);
|
||||
|
||||
boolean plant(Location l);
|
||||
}
|
||||
Reference in New Issue
Block a user