Add AsyncAttempt for example purposes.

This commit is contained in:
Jeremy Wood 2023-09-13 16:16:47 -04:00
parent 2f3306aa97
commit 3df46bc55c
No known key found for this signature in database
GPG Key ID: C5BAD04C77B91B4B
2 changed files with 85 additions and 34 deletions

View File

@ -16,7 +16,9 @@ import org.jvnet.hk2.annotations.Service;
import org.mvplugins.multiverse.core.api.BlockSafety;
import org.mvplugins.multiverse.core.destination.ParsedDestination;
import org.mvplugins.multiverse.core.utils.result.AsyncAttempt;
import org.mvplugins.multiverse.core.utils.result.AsyncResult;
import org.mvplugins.multiverse.core.utils.result.Attempt;
import org.mvplugins.multiverse.core.utils.result.Result;
@SuppressWarnings("unchecked")
@ -33,7 +35,7 @@ public class AsyncSafetyTeleporter {
this.teleportQueue = teleportQueue;
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleportSafely(
public AsyncAttempt<Void, TeleportResult.Failure> teleportSafely(
@NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) {
return teleportSafely(null, teleportee, destination);
@ -48,34 +50,34 @@ public class AsyncSafetyTeleporter {
.toList());
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleportSafely(
public AsyncAttempt<Void, TeleportResult.Failure> teleportSafely(
@Nullable CommandSender teleporter,
@NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) {
if (destination == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.NULL_DESTINATION));
return AsyncAttempt.failure(TeleportResult.Failure.NULL_DESTINATION);
}
return destination.getDestination().checkTeleportSafety()
? teleportSafely(teleporter, teleportee, destination.getLocation(teleportee))
: teleport(teleporter, teleportee, destination.getLocation(teleportee));
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleportSafely(
public AsyncAttempt<Void, TeleportResult.Failure> teleportSafely(
@NotNull Entity teleportee,
@Nullable Location location) {
return teleportSafely(null, teleportee, location);
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleportSafely(
public AsyncAttempt<Void, TeleportResult.Failure> teleportSafely(
@Nullable CommandSender teleporter,
@NotNull Entity teleportee,
@Nullable Location location) {
if (location == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.NULL_LOCATION));
return AsyncAttempt.failure(TeleportResult.Failure.NULL_LOCATION);
}
Location safeLocation = blockSafety.getSafeLocation(location);
if (safeLocation == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.UNSAFE_LOCATION));
return AsyncAttempt.failure(TeleportResult.Failure.UNSAFE_LOCATION);
}
return teleport(teleporter, teleportee, safeLocation);
}
@ -88,18 +90,18 @@ public class AsyncSafetyTeleporter {
.toList());
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport(
public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) {
return teleport(null, teleportee, destination);
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport(
public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@Nullable CommandSender teleporter,
@NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) {
if (destination == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.NULL_DESTINATION));
return AsyncAttempt.failure(TeleportResult.Failure.NULL_DESTINATION);
}
return teleport(teleporter, teleportee, destination.getLocation(teleportee));
}
@ -112,18 +114,18 @@ public class AsyncSafetyTeleporter {
.toList());
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport(
public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@NotNull Entity teleportee,
@Nullable Location location) {
return teleport(null, teleportee, location);
}
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport(
public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@Nullable CommandSender teleporter,
@NotNull Entity teleportee,
@Nullable Location location) {
if (location == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.NULL_LOCATION));
return AsyncAttempt.failure(TeleportResult.Failure.NULL_LOCATION);
}
boolean shouldAddToQueue = teleporter != null && teleportee instanceof Player;
@ -131,33 +133,26 @@ public class AsyncSafetyTeleporter {
teleportQueue.addToQueue(teleporter.getName(), teleportee.getName());
}
AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> future = new AsyncResult<>();
doAsyncTeleport(teleportee, location, future, shouldAddToQueue);
return future;
return doAsyncTeleport(teleportee, location, shouldAddToQueue);
}
private void doAsyncTeleport(
private AsyncAttempt<Void, TeleportResult.Failure> doAsyncTeleport(
@NotNull Entity teleportee,
@NotNull Location location,
AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> future,
boolean shouldAddToQueue) {
Try.run(() -> PaperLib.teleportAsync(teleportee, location).thenAccept(result -> {
return AsyncAttempt.of(PaperLib.teleportAsync(teleportee, location), exception -> {
Logging.warning("Failed to teleport %s to %s: %s",
teleportee.getName(), location, exception.getMessage());
return Attempt.failure(TeleportResult.Failure.TELEPORT_FAILED_EXCEPTION);
}).mapAsyncAttempt(result -> {
Logging.finer("Teleported async %s to %s", teleportee.getName(), location);
future.complete(result
? Result.success(TeleportResult.Success.SUCCESS)
: Result.failure(TeleportResult.Failure.TELEPORT_FAILED));
}).exceptionally(exception -> {
Logging.warning("Failed to teleport %s to %s: %s",
teleportee.getName(), location, exception.getMessage());
future.completeExceptionally(exception);
return null;
})).onFailure(exception -> {
Logging.warning("Failed to teleport %s to %s: %s",
teleportee.getName(), location, exception.getMessage());
future.complete(Result.failure(TeleportResult.Failure.TELEPORT_FAILED_EXCEPTION));
}).andFinally(() -> {
if (shouldAddToQueue) {
teleportQueue.popFromQueue(teleportee.getName());
if (result) {
if (shouldAddToQueue) {
teleportQueue.popFromQueue(teleportee.getName());
}
return AsyncAttempt.success();
} else {
return AsyncAttempt.failure(TeleportResult.Failure.TELEPORT_FAILED);
}
});
}

View File

@ -0,0 +1,56 @@
package org.mvplugins.multiverse.core.utils.result;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.mvplugins.multiverse.core.utils.message.MessageReplacement;
public final class AsyncAttempt<T, F extends FailureReason> {
public static <T, F extends FailureReason> AsyncAttempt<T, F> of(
CompletableFuture<T> future,
BiFunction<T, Throwable, Attempt<T, F>> completionHandler) {
return new AsyncAttempt<>(future.handleAsync(completionHandler));
}
public static <T, F extends FailureReason> AsyncAttempt<T, F> of(
CompletableFuture<T> future,
Function<Throwable, Attempt<T, F>> exceptionHandler) {
BiFunction<T, Throwable, Attempt<T, F>> completionHandler = (result, exception) -> {
if (exception != null) {
return exceptionHandler.apply(exception);
} else {
return Attempt.success(result);
}
};
return of(future, completionHandler);
}
public static <F extends FailureReason> AsyncAttempt<Void, F> success() {
return new AsyncAttempt<>(CompletableFuture.completedFuture(null));
}
public static <F extends FailureReason> AsyncAttempt<Void, F> failure(
F failureReason,
MessageReplacement... messageReplacements) {
return new AsyncAttempt<>(CompletableFuture.completedFuture(
Attempt.failure(failureReason, messageReplacements)));
}
private final CompletableFuture<Attempt<T, F>> future;
`
private AsyncAttempt(CompletableFuture<Attempt<T, F>> future) {
this.future = future;
}
public <U> AsyncAttempt<U, F> map(Function<? super T, ? extends U> mapper) {
}
public <U> AsyncAttempt<U, F> mapAsyncAttempt(Function<? super T, AsyncAttempt<U, F>> mapper) {
}
public AsyncAttempt<T, F> onSuccess(Runnable runnable) {
}
}