mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
implement a bunch of function utils
This commit is contained in:
@@ -16,6 +16,7 @@ import java.util.function.Function;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
import static com.dfsek.terra.api.util.function.FunctionUtils.*;
|
||||||
|
|
||||||
|
|
||||||
public class BiomeLocator {
|
public class BiomeLocator {
|
||||||
@@ -76,7 +77,7 @@ public class BiomeLocator {
|
|||||||
.mapToObj(z -> new int[]{ minX, z }); // Fixed X (min), varying Z
|
.mapToObj(z -> new int[]{ minX, z }); // Fixed X (min), varying Z
|
||||||
|
|
||||||
Optional<Either<Vector3Int, Vector2Int>> ringResult = Stream.of(northSide, eastSide, southSide, westSide)
|
Optional<Either<Vector3Int, Vector2Int>> ringResult = Stream.of(northSide, eastSide, southSide, westSide)
|
||||||
.flatMap(Function.identity())
|
.flatMap(identity())
|
||||||
.parallel()
|
.parallel()
|
||||||
.map(coords -> check(
|
.map(coords -> check(
|
||||||
provider,
|
provider,
|
||||||
@@ -93,10 +94,10 @@ public class BiomeLocator {
|
|||||||
.findFirst(); // findFirst() respects encounter order (North -> East -> South -> West)
|
.findFirst(); // findFirst() respects encounter order (North -> East -> South -> West)
|
||||||
|
|
||||||
if(ringResult.isPresent()) {
|
if(ringResult.isPresent()) {
|
||||||
return Maybe.fromOptional(ringResult);
|
return fromOptional(ringResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Maybe.nothing();
|
return nothing();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -120,16 +121,16 @@ public class BiomeLocator {
|
|||||||
// Iterate from bottom to top of the world using the step
|
// Iterate from bottom to top of the world using the step
|
||||||
for(int y = minHeight; y < maxHeight; y += step) {
|
for(int y = minHeight; y < maxHeight; y += step) {
|
||||||
if(filter.test(provider.getBiome(x, y, z, seed))) {
|
if(filter.test(provider.getBiome(x, y, z, seed))) {
|
||||||
return Maybe.just(Either.left(Vector3Int.of(x, y, z)));
|
return just(left(Vector3Int.of(x, y, z)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Maybe.nothing();
|
return nothing();
|
||||||
} else {
|
} else {
|
||||||
// 2D Mode: Check only the base biome
|
// 2D Mode: Check only the base biome
|
||||||
// We use a flatMap approach here to be safe with Optionals inside the stream
|
// We use a flatMap approach here to be safe with Optionals inside the stream
|
||||||
return provider.getBaseBiome(x, z, seed)
|
return provider.getBaseBiome(x, z, seed)
|
||||||
.filter(filter)
|
.filter(filter)
|
||||||
.map(b -> Either.right(Vector2Int.of(x, z)));
|
.map(b -> right(Vector2Int.of(x, z)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -29,6 +29,7 @@ import java.util.function.Function;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.registry.key.RegistryKey;
|
import com.dfsek.terra.api.registry.key.RegistryKey;
|
||||||
import com.dfsek.terra.api.util.reflection.TypeKey;
|
import com.dfsek.terra.api.util.reflection.TypeKey;
|
||||||
|
import static com.dfsek.terra.api.util.function.FunctionUtils.*;
|
||||||
|
|
||||||
|
|
||||||
public interface Registry<T> extends TypeLoader<T> {
|
public interface Registry<T> extends TypeLoader<T> {
|
||||||
@@ -96,11 +97,11 @@ public interface Registry<T> extends TypeLoader<T> {
|
|||||||
|
|
||||||
default Either<Invalid, T> getByID(String id) {
|
default Either<Invalid, T> getByID(String id) {
|
||||||
return getByID(id, map -> {
|
return getByID(id, map -> {
|
||||||
if(map.isEmpty()) return Either.left(new NoSuchElement("No such value \"" + id + "\""));
|
if(map.isEmpty()) return left(new NoSuchElement("No such value \"" + id + "\""));
|
||||||
if(map.size() == 1) {
|
if(map.size() == 1) {
|
||||||
return Either.right(map.values().stream().findFirst().get()); // only one value.
|
return right(map.values().stream().findFirst().get()); // only one value.
|
||||||
}
|
}
|
||||||
return Either.left(new AmbiguousKey("ID \"" + id + "\" is ambiguous; matches: " + map
|
return left(new AmbiguousKey("ID \"" + id + "\" is ambiguous; matches: " + map
|
||||||
.keySet()
|
.keySet()
|
||||||
.stream()
|
.stream()
|
||||||
.map(RegistryKey::toString)
|
.map(RegistryKey::toString)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.dfsek.terra.api.error.Invalid;
|
|||||||
import com.dfsek.terra.api.error.InvalidKey;
|
import com.dfsek.terra.api.error.InvalidKey;
|
||||||
import com.dfsek.terra.api.util.generic.data.types.Either;
|
import com.dfsek.terra.api.util.generic.data.types.Either;
|
||||||
import com.dfsek.terra.api.util.generic.data.types.Maybe;
|
import com.dfsek.terra.api.util.generic.data.types.Maybe;
|
||||||
|
import static com.dfsek.terra.api.util.function.FunctionUtils.*;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@@ -33,12 +34,12 @@ public final class RegistryKey implements StringIdentifiable, Namespaced {
|
|||||||
|
|
||||||
public static Either<Invalid, RegistryKey> parse(String key) {
|
public static Either<Invalid, RegistryKey> parse(String key) {
|
||||||
if(key.chars().filter(c -> c == ':').count() != 1) {
|
if(key.chars().filter(c -> c == ':').count() != 1) {
|
||||||
return Either.left(new InvalidKey("Malformed RegistryKey: " + key));
|
return left(new InvalidKey("Malformed RegistryKey: " + key));
|
||||||
}
|
}
|
||||||
String namespace = key.substring(0, key.indexOf(":"));
|
String namespace = key.substring(0, key.indexOf(":"));
|
||||||
String id = key.substring(key.indexOf(":") + 1);
|
String id = key.substring(key.indexOf(":") + 1);
|
||||||
|
|
||||||
return Either.right(new RegistryKey(namespace, id));
|
return right(new RegistryKey(namespace, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static RegistryKey of(String namespace, String id) {
|
public static RegistryKey of(String namespace, String id) {
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ package com.dfsek.terra.api.util.function;
|
|||||||
|
|
||||||
import com.dfsek.terra.api.util.generic.data.types.Either;
|
import com.dfsek.terra.api.util.generic.data.types.Either;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.util.generic.data.types.Maybe;
|
||||||
import com.dfsek.terra.api.util.generic.data.types.Pair;
|
import com.dfsek.terra.api.util.generic.data.types.Pair;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
@@ -17,6 +19,30 @@ import java.util.function.Supplier;
|
|||||||
public final class FunctionUtils {
|
public final class FunctionUtils {
|
||||||
private FunctionUtils() { }
|
private FunctionUtils() { }
|
||||||
|
|
||||||
|
public static <T> Function<T, T> identity() {
|
||||||
|
return Function.identity();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Maybe<T> just(T t) {
|
||||||
|
return Maybe.just(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Maybe<T> nothing() {
|
||||||
|
return Maybe.nothing();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <L, R> Either<L, R> left(L l) {
|
||||||
|
return Either.left(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <L, R> Either<L, R> right(R r) {
|
||||||
|
return Either.right(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> Maybe<T> fromOptional(Optional<T> op) {
|
||||||
|
return Maybe.fromOptional(op);
|
||||||
|
}
|
||||||
|
|
||||||
@Contract("_ -> new")
|
@Contract("_ -> new")
|
||||||
public static <T> @NotNull Function<T, T> lift(@NotNull Consumer<T> c) {
|
public static <T> @NotNull Function<T, T> lift(@NotNull Consumer<T> c) {
|
||||||
Objects.requireNonNull(c);
|
Objects.requireNonNull(c);
|
||||||
@@ -26,6 +52,17 @@ public final class FunctionUtils {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Contract("_ -> new")
|
||||||
|
public static <T, R> @NotNull Function<T, R> lift(@NotNull Supplier<R> c) {
|
||||||
|
Objects.requireNonNull(c);
|
||||||
|
return co -> c.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Contract("_ -> new")
|
||||||
|
public static <T, R> @NotNull Function<T, R> lift(@NotNull R c) {
|
||||||
|
return lift(() -> c);
|
||||||
|
}
|
||||||
|
|
||||||
@Contract("_ -> fail")
|
@Contract("_ -> fail")
|
||||||
public static <T extends Throwable, U> @NotNull U throw_(@NotNull T e) throws T {
|
public static <T extends Throwable, U> @NotNull U throw_(@NotNull T e) throws T {
|
||||||
throw e;
|
throw e;
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
|
|
||||||
package com.dfsek.terra.api.util.generic.data.types;
|
package com.dfsek.terra.api.util.generic.data.types;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.function.FunctionUtils;
|
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.generic.control.Monad;
|
import com.dfsek.terra.api.util.generic.control.Monad;
|
||||||
|
|
||||||
import com.dfsek.terra.api.util.generic.data.BiFunctor;
|
import com.dfsek.terra.api.util.generic.data.BiFunctor;
|
||||||
@@ -20,28 +18,29 @@ import java.util.Objects;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import static com.dfsek.terra.api.util.function.FunctionUtils.*;
|
||||||
|
|
||||||
|
|
||||||
public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L, R, Either<?, ?>> {
|
public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L, R, Either<?, ?>> {
|
||||||
static <T> T collapse(Either<T, T> either) {
|
static <T> T collapse(Either<T, T> either) {
|
||||||
return either.collect(Function.identity(), Function.identity());
|
return either.collect(identity(), identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
static <T, L> Either<L, T> toEither(Optional<T> o, L de) {
|
static <T, L> Either<L, T> toEither(Optional<T> o, L de) {
|
||||||
return (Either<L, T>) o.map(Either::right).orElseGet(() -> left(de));
|
return (Either<L, T>) o.map(Either::right).orElseGet(() -> Either.left(de));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Contract("_ -> this")
|
@Contract("_ -> this")
|
||||||
default Either<L, R> ifLeft(@NotNull Consumer<L> action) {
|
default Either<L, R> ifLeft(@NotNull Consumer<L> action) {
|
||||||
return mapLeft(FunctionUtils.lift(action));
|
return mapLeft(lift(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Contract("_ -> this")
|
@Contract("_ -> this")
|
||||||
default Either<L, R> ifRight(@NotNull Consumer<R> action) {
|
default Either<L, R> ifRight(@NotNull Consumer<R> action) {
|
||||||
return mapRight(FunctionUtils.lift(action));
|
return mapRight(lift(action));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Either is a functor in its right parameter.
|
// Either is a functor in its right parameter.
|
||||||
@@ -52,7 +51,7 @@ public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
default <T1> @NotNull Either<?, T1> pure(@NotNull T1 t) {
|
default <T1> @NotNull Either<?, T1> pure(@NotNull T1 t) {
|
||||||
return right(t);
|
return Either.right(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -64,13 +63,27 @@ public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L
|
|||||||
@Override
|
@Override
|
||||||
<R1> @NotNull Either<L, R1> mapRight(@NotNull Function<R, R1> f);
|
<R1> @NotNull Either<L, R1> mapRight(@NotNull Function<R, R1> f);
|
||||||
|
|
||||||
Maybe<L> getLeft();
|
@Override
|
||||||
|
@NotNull
|
||||||
|
default <V, W> Either<V, W> bimap(@NotNull Function<L, V> left, @NotNull Function<R, W> right) {
|
||||||
|
return (Either<V, W>) BiFunctor.super.bimap(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
Maybe<R> getRight();
|
default Maybe<L> getLeft() {
|
||||||
|
return collapse(bimap(Maybe::just, lift(Maybe::nothing)));
|
||||||
|
}
|
||||||
|
|
||||||
boolean isLeft();
|
default Maybe<R> getRight() {
|
||||||
|
return collapse(bimap(lift(Maybe::nothing), Maybe::just));
|
||||||
|
}
|
||||||
|
|
||||||
boolean isRight();
|
default boolean isLeft() {
|
||||||
|
return collapse(bimap(lift(true), lift(false)));
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isRight() {
|
||||||
|
return collapse(bimap(lift(false), lift(true)));
|
||||||
|
}
|
||||||
|
|
||||||
Either<R, L> flip();
|
Either<R, L> flip();
|
||||||
|
|
||||||
@@ -88,7 +101,7 @@ public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L
|
|||||||
|
|
||||||
@SuppressWarnings("Convert2MethodRef")
|
@SuppressWarnings("Convert2MethodRef")
|
||||||
default <T extends Throwable> R collectThrow(Function<L, T> left) throws T {
|
default <T extends Throwable> R collectThrow(Function<L, T> left) throws T {
|
||||||
return mapLeft(left).collect(l -> FunctionUtils.sneakyThrow(l), Function.identity());
|
return mapLeft(left).collect(l -> sneakyThrow(l), identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -122,29 +135,9 @@ public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L
|
|||||||
return (Either<L, R1>) this;
|
return (Either<L, R1>) this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Maybe<L> getLeft() {
|
|
||||||
return Maybe.just(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Maybe<R> getRight() {
|
|
||||||
return Maybe.nothing();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLeft() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRight() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Either<R, L> flip() {
|
public Either<R, L> flip() {
|
||||||
return right(value);
|
return Either.right(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -171,29 +164,9 @@ public sealed interface Either<L, R> extends Monad<R, Either<?, ?>>, BiFunctor<L
|
|||||||
return new Right<>(f.apply(value));
|
return new Right<>(f.apply(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Maybe<L> getLeft() {
|
|
||||||
return Maybe.nothing();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Maybe<R> getRight() {
|
|
||||||
return Maybe.just(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isLeft() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isRight() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Either<R, L> flip() {
|
public Either<R, L> flip() {
|
||||||
return left(value);
|
return Either.left(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Reference in New Issue
Block a user