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.api.BlockSafety;
import org.mvplugins.multiverse.core.destination.ParsedDestination; 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.AsyncResult;
import org.mvplugins.multiverse.core.utils.result.Attempt;
import org.mvplugins.multiverse.core.utils.result.Result; import org.mvplugins.multiverse.core.utils.result.Result;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -33,7 +35,7 @@ public class AsyncSafetyTeleporter {
this.teleportQueue = teleportQueue; this.teleportQueue = teleportQueue;
} }
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleportSafely( public AsyncAttempt<Void, TeleportResult.Failure> teleportSafely(
@NotNull Entity teleportee, @NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) { @Nullable ParsedDestination<?> destination) {
return teleportSafely(null, teleportee, destination); return teleportSafely(null, teleportee, destination);
@ -48,34 +50,34 @@ public class AsyncSafetyTeleporter {
.toList()); .toList());
} }
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleportSafely( public AsyncAttempt<Void, TeleportResult.Failure> teleportSafely(
@Nullable CommandSender teleporter, @Nullable CommandSender teleporter,
@NotNull Entity teleportee, @NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) { @Nullable ParsedDestination<?> destination) {
if (destination == null) { if (destination == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.NULL_DESTINATION)); return AsyncAttempt.failure(TeleportResult.Failure.NULL_DESTINATION);
} }
return destination.getDestination().checkTeleportSafety() return destination.getDestination().checkTeleportSafety()
? teleportSafely(teleporter, teleportee, destination.getLocation(teleportee)) ? teleportSafely(teleporter, teleportee, destination.getLocation(teleportee))
: teleport(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, @NotNull Entity teleportee,
@Nullable Location location) { @Nullable Location location) {
return teleportSafely(null, teleportee, location); return teleportSafely(null, teleportee, location);
} }
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleportSafely( public AsyncAttempt<Void, TeleportResult.Failure> teleportSafely(
@Nullable CommandSender teleporter, @Nullable CommandSender teleporter,
@NotNull Entity teleportee, @NotNull Entity teleportee,
@Nullable Location location) { @Nullable Location location) {
if (location == null) { if (location == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.NULL_LOCATION)); return AsyncAttempt.failure(TeleportResult.Failure.NULL_LOCATION);
} }
Location safeLocation = blockSafety.getSafeLocation(location); Location safeLocation = blockSafety.getSafeLocation(location);
if (safeLocation == null) { if (safeLocation == null) {
return AsyncResult.completedFuture(Result.failure(TeleportResult.Failure.UNSAFE_LOCATION)); return AsyncAttempt.failure(TeleportResult.Failure.UNSAFE_LOCATION);
} }
return teleport(teleporter, teleportee, safeLocation); return teleport(teleporter, teleportee, safeLocation);
} }
@ -88,18 +90,18 @@ public class AsyncSafetyTeleporter {
.toList()); .toList());
} }
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport( public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@NotNull Entity teleportee, @NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) { @Nullable ParsedDestination<?> destination) {
return teleport(null, teleportee, destination); return teleport(null, teleportee, destination);
} }
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport( public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@Nullable CommandSender teleporter, @Nullable CommandSender teleporter,
@NotNull Entity teleportee, @NotNull Entity teleportee,
@Nullable ParsedDestination<?> destination) { @Nullable ParsedDestination<?> destination) {
if (destination == null) { 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)); return teleport(teleporter, teleportee, destination.getLocation(teleportee));
} }
@ -112,18 +114,18 @@ public class AsyncSafetyTeleporter {
.toList()); .toList());
} }
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport( public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@NotNull Entity teleportee, @NotNull Entity teleportee,
@Nullable Location location) { @Nullable Location location) {
return teleport(null, teleportee, location); return teleport(null, teleportee, location);
} }
public AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> teleport( public AsyncAttempt<Void, TeleportResult.Failure> teleport(
@Nullable CommandSender teleporter, @Nullable CommandSender teleporter,
@NotNull Entity teleportee, @NotNull Entity teleportee,
@Nullable Location location) { @Nullable Location location) {
if (location == null) { 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; boolean shouldAddToQueue = teleporter != null && teleportee instanceof Player;
@ -131,34 +133,27 @@ public class AsyncSafetyTeleporter {
teleportQueue.addToQueue(teleporter.getName(), teleportee.getName()); teleportQueue.addToQueue(teleporter.getName(), teleportee.getName());
} }
AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> future = new AsyncResult<>(); return doAsyncTeleport(teleportee, location, shouldAddToQueue);
doAsyncTeleport(teleportee, location, future, shouldAddToQueue);
return future;
} }
private void doAsyncTeleport( private AsyncAttempt<Void, TeleportResult.Failure> doAsyncTeleport(
@NotNull Entity teleportee, @NotNull Entity teleportee,
@NotNull Location location, @NotNull Location location,
AsyncResult<Result<TeleportResult.Success, TeleportResult.Failure>> future,
boolean shouldAddToQueue) { 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); Logging.finer("Teleported async %s to %s", teleportee.getName(), location);
future.complete(result if (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) { if (shouldAddToQueue) {
teleportQueue.popFromQueue(teleportee.getName()); 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) {
}
}