Merge pull request #3022 from Multiverse/dtm/mv5/teleporter_attempt
Add AsyncAttempt.
This commit is contained in:
commit
91f9842b24
|
@ -24,7 +24,7 @@ import org.mvplugins.multiverse.core.commandtools.flags.CommandFlag;
|
|||
import org.mvplugins.multiverse.core.commandtools.flags.ParsedCommandFlags;
|
||||
import org.mvplugins.multiverse.core.commandtools.queue.QueuedCommand;
|
||||
import org.mvplugins.multiverse.core.utils.MVCorei18n;
|
||||
import org.mvplugins.multiverse.core.utils.result.AsyncResult;
|
||||
import org.mvplugins.multiverse.core.utils.result.Async;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
import org.mvplugins.multiverse.core.world.helpers.PlayerWorldTeleporter;
|
||||
|
@ -83,7 +83,7 @@ class DeleteCommand extends MultiverseCommand {
|
|||
|
||||
var future = parsedFlags.hasFlag(REMOVE_PLAYERS_FLAG)
|
||||
? playerWorldTeleporter.removeFromWorld(world)
|
||||
: AsyncResult.completedFuture(Collections.emptyList());
|
||||
: Async.completedFuture(Collections.emptyList());
|
||||
|
||||
future.thenRun(() -> doWorldDeleting(issuer, world));
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ import org.mvplugins.multiverse.core.commandtools.flags.CommandValueFlag;
|
|||
import org.mvplugins.multiverse.core.commandtools.flags.ParsedCommandFlags;
|
||||
import org.mvplugins.multiverse.core.commandtools.queue.QueuedCommand;
|
||||
import org.mvplugins.multiverse.core.utils.MVCorei18n;
|
||||
import org.mvplugins.multiverse.core.utils.result.AsyncResult;
|
||||
import org.mvplugins.multiverse.core.utils.result.Async;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
import org.mvplugins.multiverse.core.world.helpers.PlayerWorldTeleporter;
|
||||
|
@ -101,7 +101,7 @@ class RegenCommand extends MultiverseCommand {
|
|||
|
||||
var future = parsedFlags.hasFlag(REMOVE_PLAYERS_FLAG)
|
||||
? playerWorldTeleporter.removeFromWorld(world)
|
||||
: AsyncResult.completedFuture(Collections.emptyList());
|
||||
: Async.completedFuture(Collections.emptyList());
|
||||
|
||||
future.thenRun(() -> doWorldRegening(issuer, world, parsedFlags, worldPlayers));
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.mvplugins.multiverse.core.commandtools.MultiverseCommand;
|
|||
import org.mvplugins.multiverse.core.commandtools.flags.CommandFlag;
|
||||
import org.mvplugins.multiverse.core.commandtools.flags.ParsedCommandFlags;
|
||||
import org.mvplugins.multiverse.core.utils.MVCorei18n;
|
||||
import org.mvplugins.multiverse.core.utils.result.AsyncResult;
|
||||
import org.mvplugins.multiverse.core.utils.result.Async;
|
||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
import org.mvplugins.multiverse.core.world.helpers.PlayerWorldTeleporter;
|
||||
|
||||
|
@ -70,8 +70,8 @@ class RemoveCommand extends MultiverseCommand {
|
|||
var future = parsedFlags.hasFlag(REMOVE_PLAYERS_FLAG)
|
||||
? worldManager.getLoadedWorld(worldName)
|
||||
.map(playerWorldTeleporter::removeFromWorld)
|
||||
.getOrElse(AsyncResult.completedFuture(Collections.emptyList()))
|
||||
: AsyncResult.completedFuture(Collections.emptyList());
|
||||
.getOrElse(Async.completedFuture(Collections.emptyList()))
|
||||
: Async.completedFuture(Collections.emptyList());
|
||||
|
||||
future.thenRun(() -> doWorldRemoving(issuer, worldName));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package org.mvplugins.multiverse.core.commands;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import co.aikar.commands.CommandIssuer;
|
||||
import co.aikar.commands.annotation.CommandAlias;
|
||||
|
@ -22,7 +22,6 @@ import org.mvplugins.multiverse.core.destination.ParsedDestination;
|
|||
import org.mvplugins.multiverse.core.permissions.CorePermissionsChecker;
|
||||
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter;
|
||||
import org.mvplugins.multiverse.core.utils.MVCorei18n;
|
||||
import org.mvplugins.multiverse.core.utils.result.AsyncResult;
|
||||
|
||||
@Service
|
||||
@CommandAlias("mv")
|
||||
|
@ -72,10 +71,8 @@ class TeleportCommand extends MultiverseCommand {
|
|||
issuer.sendInfo(MVCorei18n.TELEPORT_SUCCESS,
|
||||
"{player}", playerName, "{destination}", destination.toString());
|
||||
|
||||
AsyncResult.allOf(Arrays.stream(players)
|
||||
.map(player -> safetyTeleporter.teleportSafely(issuer.getIssuer(), player, destination))
|
||||
.toList())
|
||||
.thenRun(() -> Logging.fine("Async teleport result: %s"))
|
||||
safetyTeleporter.teleportSafely(issuer.getIssuer(), List.of(players), destination)
|
||||
.thenAccept(attempts -> Logging.fine("Async teleport completed: %s", attempts))
|
||||
.exceptionally(throwable -> {
|
||||
Logging.severe("Error while teleporting %s to %s: %s",
|
||||
playerName, destination, throwable.getMessage());
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.mvplugins.multiverse.core.commandtools.MultiverseCommand;
|
|||
import org.mvplugins.multiverse.core.commandtools.flags.CommandFlag;
|
||||
import org.mvplugins.multiverse.core.commandtools.flags.ParsedCommandFlags;
|
||||
import org.mvplugins.multiverse.core.utils.MVCorei18n;
|
||||
import org.mvplugins.multiverse.core.utils.result.AsyncResult;
|
||||
import org.mvplugins.multiverse.core.utils.result.Async;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
import org.mvplugins.multiverse.core.world.WorldManager;
|
||||
import org.mvplugins.multiverse.core.world.helpers.PlayerWorldTeleporter;
|
||||
|
@ -73,7 +73,7 @@ class UnloadCommand extends MultiverseCommand {
|
|||
|
||||
var future = parsedFlags.hasFlag(REMOVE_PLAYERS_FLAG)
|
||||
? playerWorldTeleporter.removeFromWorld(world)
|
||||
: AsyncResult.completedFuture(Collections.emptyList());
|
||||
: Async.completedFuture(Collections.emptyList());
|
||||
|
||||
future.thenRun(() -> doWorldUnloading(issuer, world, parsedFlags));
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import java.util.List;
|
|||
|
||||
import com.dumptruckman.minecraft.util.Logging;
|
||||
import io.papermc.lib.PaperLib;
|
||||
import io.vavr.control.Try;
|
||||
import jakarta.inject.Inject;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -16,10 +15,13 @@ 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.AsyncResult;
|
||||
import org.mvplugins.multiverse.core.utils.result.Result;
|
||||
import org.mvplugins.multiverse.core.utils.result.Async;
|
||||
import org.mvplugins.multiverse.core.utils.result.AsyncAttempt;
|
||||
import org.mvplugins.multiverse.core.utils.result.Attempt;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
/**
|
||||
* Teleports entities safely and asynchronously.
|
||||
*/
|
||||
@Service
|
||||
public class AsyncSafetyTeleporter {
|
||||
private final BlockSafety blockSafety;
|
||||
|
@ -33,97 +35,97 @@ 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);
|
||||
}
|
||||
|
||||
public <T extends Entity> AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>> teleportSafely(
|
||||
public <T extends Entity> Async<List<Attempt<Void, TeleportResult.Failure>>> teleportSafely(
|
||||
@Nullable CommandSender teleporter,
|
||||
@NotNull List<T> teleportees,
|
||||
@Nullable ParsedDestination<?> destination) {
|
||||
return AsyncResult.allOf(teleportees.stream()
|
||||
return AsyncAttempt.allOf(teleportees.stream()
|
||||
.map(teleportee -> teleportSafely(teleporter, teleportee, destination))
|
||||
.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);
|
||||
}
|
||||
|
||||
public <T extends Entity> AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>> teleport(
|
||||
public <T extends Entity> Async<List<Attempt<Void, TeleportResult.Failure>>> teleport(
|
||||
@NotNull List<T> teleportees,
|
||||
@Nullable ParsedDestination<?> destination) {
|
||||
return AsyncResult.allOf(teleportees.stream()
|
||||
return AsyncAttempt.allOf(teleportees.stream()
|
||||
.map(teleportee -> teleport(teleportee, destination))
|
||||
.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));
|
||||
}
|
||||
|
||||
public <T extends Entity> AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>> teleport(
|
||||
public <T extends Entity> Async<List<Attempt<Void, TeleportResult.Failure>>> teleport(
|
||||
@NotNull List<T> teleportees,
|
||||
@Nullable Location location) {
|
||||
return AsyncResult.allOf(teleportees.stream()
|
||||
return AsyncAttempt.allOf(teleportees.stream()
|
||||
.map(teleportee -> teleport(teleportee, location))
|
||||
.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,34 +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);
|
||||
}).mapAttempt(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 Attempt.success(null);
|
||||
}
|
||||
return Attempt.failure(TeleportResult.Failure.TELEPORT_FAILED);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import java.util.function.Function;
|
|||
*
|
||||
* @param <T> The type of the value.
|
||||
*/
|
||||
public final class AsyncResult<T> {
|
||||
public final class Async<T> {
|
||||
|
||||
/**
|
||||
* Returns a new AsyncResult that is completed when all of the given AsyncResult complete.
|
||||
|
@ -19,8 +19,8 @@ public final class AsyncResult<T> {
|
|||
* @param results The results to wait for.
|
||||
* @return A new AsyncResult that is completed when all of the given AsyncResult complete.
|
||||
*/
|
||||
public static AsyncResult<Void> allOf(AsyncResult<?>... results) {
|
||||
return new AsyncResult<>(CompletableFuture.allOf(Arrays.stream(results)
|
||||
public static Async<Void> allOf(Async<?>... results) {
|
||||
return new Async<>(CompletableFuture.allOf(Arrays.stream(results)
|
||||
.map(result -> result.future)
|
||||
.toArray(CompletableFuture[]::new)));
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ public final class AsyncResult<T> {
|
|||
* @param <T> The type of the AsyncResult.
|
||||
* @return A new AsyncResult that is completed when all of the given AsyncResult complete.
|
||||
*/
|
||||
public static <T> AsyncResult<List<T>> allOf(List<AsyncResult<T>> results) {
|
||||
return new AsyncResult<>(CompletableFuture.allOf(results.stream()
|
||||
public static <T> Async<List<T>> allOf(List<Async<T>> results) {
|
||||
return new Async<>(CompletableFuture.allOf(results.stream()
|
||||
.map(result -> result.future)
|
||||
.toArray(CompletableFuture[]::new))
|
||||
.thenApply(v -> results.stream()
|
||||
|
@ -48,8 +48,8 @@ public final class AsyncResult<T> {
|
|||
* @param <T> The type of the future.
|
||||
* @return A new AsyncResult that is completed when the given future completes.
|
||||
*/
|
||||
public static <T> AsyncResult<T> of(CompletableFuture<T> future) {
|
||||
return new AsyncResult<>(future);
|
||||
public static <T> Async<T> of(CompletableFuture<T> future) {
|
||||
return new Async<>(future);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -59,8 +59,8 @@ public final class AsyncResult<T> {
|
|||
* @param <T> The type of the value.
|
||||
* @return The completed AsyncResult.
|
||||
*/
|
||||
public static <T> AsyncResult<T> completedFuture(T value) {
|
||||
return new AsyncResult<>(CompletableFuture.completedFuture(value));
|
||||
public static <T> Async<T> completedFuture(T value) {
|
||||
return new Async<>(CompletableFuture.completedFuture(value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -70,8 +70,8 @@ public final class AsyncResult<T> {
|
|||
* @param <T> The type of the value.
|
||||
* @return The completed AsyncResult.
|
||||
*/
|
||||
public static <T> AsyncResult<T> failedFuture(Throwable throwable) {
|
||||
return new AsyncResult<>(CompletableFuture.failedFuture(throwable));
|
||||
public static <T> Async<T> failedFuture(Throwable throwable) {
|
||||
return new Async<>(CompletableFuture.failedFuture(throwable));
|
||||
}
|
||||
|
||||
private final CompletableFuture<T> future;
|
||||
|
@ -79,11 +79,11 @@ public final class AsyncResult<T> {
|
|||
/**
|
||||
* Creates a new AsyncResult.
|
||||
*/
|
||||
public AsyncResult() {
|
||||
public Async() {
|
||||
this(new CompletableFuture<>());
|
||||
}
|
||||
|
||||
private AsyncResult(CompletableFuture<T> future) {
|
||||
private Async(CompletableFuture<T> future) {
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
|
@ -113,8 +113,8 @@ public final class AsyncResult<T> {
|
|||
* @param consumer The action to perform.
|
||||
* @return This AsyncResult.
|
||||
*/
|
||||
public AsyncResult<Void> thenAccept(Consumer<T> consumer) {
|
||||
return new AsyncResult<>(future.thenAccept(consumer));
|
||||
public Async<Void> thenAccept(Consumer<T> consumer) {
|
||||
return new Async<>(future.thenAccept(consumer));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,8 +123,8 @@ public final class AsyncResult<T> {
|
|||
* @param runnable The action to perform.
|
||||
* @return This AsyncResult.
|
||||
*/
|
||||
public AsyncResult<Void> thenRun(Runnable runnable) {
|
||||
return new AsyncResult<>(future.thenRun(runnable));
|
||||
public Async<Void> thenRun(Runnable runnable) {
|
||||
return new Async<>(future.thenRun(runnable));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -134,8 +134,8 @@ public final class AsyncResult<T> {
|
|||
* @param <U> The type of the new value.
|
||||
* @return A new AsyncResult with the new value.
|
||||
*/
|
||||
public <U> AsyncResult<U> thenApply(Function<T, U> function) {
|
||||
return new AsyncResult<>(future.thenApply(function));
|
||||
public <U> Async<U> thenApply(Function<T, U> function) {
|
||||
return new Async<>(future.thenApply(function));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -144,8 +144,8 @@ public final class AsyncResult<T> {
|
|||
* @param consumer The action to perform.
|
||||
* @return This AsyncResult.
|
||||
*/
|
||||
public AsyncResult<T> exceptionally(Consumer<Throwable> consumer) {
|
||||
return new AsyncResult<>(future.exceptionally(throwable -> {
|
||||
public Async<T> exceptionally(Consumer<Throwable> consumer) {
|
||||
return new Async<>(future.exceptionally(throwable -> {
|
||||
consumer.accept(throwable);
|
||||
return null;
|
||||
}));
|
||||
|
@ -157,7 +157,7 @@ public final class AsyncResult<T> {
|
|||
* @param function The action to perform.
|
||||
* @return A new AsyncResult with the new value.
|
||||
*/
|
||||
public AsyncResult<T> exceptionally(Function<Throwable, T> function) {
|
||||
return new AsyncResult<>(future.exceptionally(function));
|
||||
public Async<T> exceptionally(Function<Throwable, T> function) {
|
||||
return new Async<>(future.exceptionally(function));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package org.mvplugins.multiverse.core.utils.result;
|
||||
|
||||
import java.util.List;
|
||||
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> Async<List<Attempt<T, F>>> allOf(List<AsyncAttempt<T, F>> attempts) {
|
||||
return Async.of(CompletableFuture.allOf(attempts.stream()
|
||||
.map(attempt -> attempt.future)
|
||||
.toArray(CompletableFuture[]::new))
|
||||
.thenApply(v -> attempts.stream()
|
||||
.map(attempt -> attempt.future.join())
|
||||
.toList()));
|
||||
}
|
||||
|
||||
public static <T, F extends FailureReason> AsyncAttempt<T, F> of(
|
||||
CompletableFuture<T> future,
|
||||
BiFunction<T, Throwable, Attempt<T, F>> completionHandler) {
|
||||
return new AsyncAttempt<>(future.handle(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) -> exception != null
|
||||
? exceptionHandler.apply(exception)
|
||||
: 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) {
|
||||
return new AsyncAttempt<>(future.thenApply(attempt -> attempt.map(mapper)));
|
||||
}
|
||||
|
||||
public <U> AsyncAttempt<U, F> mapAttempt(Function<? super T, Attempt<U, F>> mapper) {
|
||||
return new AsyncAttempt<>(future.thenApply(attempt -> attempt.mapAttempt(mapper)));
|
||||
}
|
||||
|
||||
public <U> AsyncAttempt<U, F> mapAsyncAttempt(Function<? super T, AsyncAttempt<U, F>> mapper) {
|
||||
return new AsyncAttempt<>(future.thenApplyAsync(
|
||||
attempt -> attempt.mapAttempt(rasult -> mapper.apply(rasult).toAttempt())));
|
||||
}
|
||||
|
||||
public AsyncAttempt<T, F> onSuccess(Runnable runnable) {
|
||||
return new AsyncAttempt<>(future.thenApply(attempt -> attempt.onSuccess(runnable)));
|
||||
}
|
||||
|
||||
public Attempt<T, F> toAttempt() {
|
||||
return future.join();
|
||||
}
|
||||
}
|
|
@ -669,12 +669,13 @@ public class WorldManager {
|
|||
unloadTracker.add(world.getName());
|
||||
if (!Bukkit.unloadWorld(world, save)) {
|
||||
// TODO: Localize this, maybe with MultiverseException
|
||||
if (!world.getPlayers().isEmpty()) {
|
||||
throw new Exception("There are still players in the world! Please use --remove-players flag to "
|
||||
+ "your command if wish to teleport all players out of the world.");
|
||||
}
|
||||
throw new Exception("Is this the default world? You can't unload the default world!");
|
||||
}
|
||||
Logging.fine("Bukkit unloaded world: " + world.getName());
|
||||
}).onFailure(exception -> {
|
||||
Logging.severe("Failed to unload bukkit world: " + world.getName());
|
||||
exception.printStackTrace();
|
||||
}).andFinally(() -> unloadTracker.remove(world.getName()));
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ import org.jvnet.hk2.annotations.Service;
|
|||
|
||||
import org.mvplugins.multiverse.core.teleportation.AsyncSafetyTeleporter;
|
||||
import org.mvplugins.multiverse.core.teleportation.TeleportResult;
|
||||
import org.mvplugins.multiverse.core.utils.result.AsyncResult;
|
||||
import org.mvplugins.multiverse.core.utils.result.Result;
|
||||
import org.mvplugins.multiverse.core.utils.result.Async;
|
||||
import org.mvplugins.multiverse.core.utils.result.Attempt;
|
||||
import org.mvplugins.multiverse.core.world.LoadedMultiverseWorld;
|
||||
|
||||
/**
|
||||
|
@ -32,9 +32,9 @@ public class PlayerWorldTeleporter {
|
|||
* Removes all players from the given world.
|
||||
*
|
||||
* @param world The world to remove all players from.
|
||||
* @return A list of async futures that represent the teleportation result of each player.
|
||||
*/
|
||||
public AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>>
|
||||
removeFromWorld(@NotNull LoadedMultiverseWorld world) {
|
||||
public Async<List<Attempt<Void, TeleportResult.Failure>>> removeFromWorld(@NotNull LoadedMultiverseWorld world) {
|
||||
// TODO: Better handling of fallback world
|
||||
World toWorld = Bukkit.getWorlds().get(0);
|
||||
return transferFromWorldTo(world, toWorld);
|
||||
|
@ -45,9 +45,11 @@ public class PlayerWorldTeleporter {
|
|||
*
|
||||
* @param from The world to transfer players from.
|
||||
* @param to The location to transfer players to.
|
||||
* @return A list of async futures that represent the teleportation result of each player.
|
||||
*/
|
||||
public AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>>
|
||||
transferFromWorldTo(@NotNull LoadedMultiverseWorld from, @NotNull LoadedMultiverseWorld to) {
|
||||
public Async<List<Attempt<Void, TeleportResult.Failure>>> transferFromWorldTo(
|
||||
@NotNull LoadedMultiverseWorld from,
|
||||
@NotNull LoadedMultiverseWorld to) {
|
||||
return transferAllFromWorldToLocation(from, to.getSpawnLocation());
|
||||
}
|
||||
|
||||
|
@ -56,9 +58,11 @@ public class PlayerWorldTeleporter {
|
|||
*
|
||||
* @param from The world to transfer players from.
|
||||
* @param to The world to transfer players to.
|
||||
* @return A list of async futures that represent the teleportation result of each player.
|
||||
*/
|
||||
public AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>>
|
||||
transferFromWorldTo(@NotNull LoadedMultiverseWorld from, @NotNull World to) {
|
||||
public Async<List<Attempt<Void, TeleportResult.Failure>>> transferFromWorldTo(
|
||||
@NotNull LoadedMultiverseWorld from,
|
||||
@NotNull World to) {
|
||||
return transferAllFromWorldToLocation(from, to.getSpawnLocation());
|
||||
}
|
||||
|
||||
|
@ -67,13 +71,14 @@ public class PlayerWorldTeleporter {
|
|||
*
|
||||
* @param world The world to transfer players from.
|
||||
* @param location The location to transfer players to.
|
||||
* @return A list of futures that represent the teleportation of each player.
|
||||
* @return A list of async futures that represent the teleportation result of each player.
|
||||
*/
|
||||
public AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>>
|
||||
transferAllFromWorldToLocation(@NotNull LoadedMultiverseWorld world, @NotNull Location location) {
|
||||
public Async<List<Attempt<Void, TeleportResult.Failure>>> transferAllFromWorldToLocation(
|
||||
@NotNull LoadedMultiverseWorld world,
|
||||
@NotNull Location location) {
|
||||
return world.getPlayers()
|
||||
.map(players -> safetyTeleporter.teleport(players, location))
|
||||
.getOrElse(() -> AsyncResult.failedFuture(
|
||||
.getOrElse(() -> Async.failedFuture(
|
||||
new IllegalStateException("Unable to get players from world" + world.getName())));
|
||||
}
|
||||
|
||||
|
@ -82,9 +87,11 @@ public class PlayerWorldTeleporter {
|
|||
*
|
||||
* @param players The players to teleport.
|
||||
* @param world The world to teleport players to.
|
||||
* @return A list of async futures that represent the teleportation result of each player.
|
||||
*/
|
||||
public AsyncResult<List<Result<TeleportResult.Success, TeleportResult.Failure>>>
|
||||
teleportPlayersToWorld(@NotNull List<Player> players, @NotNull LoadedMultiverseWorld world) {
|
||||
public Async<List<Attempt<Void, TeleportResult.Failure>>> teleportPlayersToWorld(
|
||||
@NotNull List<Player> players,
|
||||
@NotNull LoadedMultiverseWorld world) {
|
||||
Location spawnLocation = world.getSpawnLocation();
|
||||
return safetyTeleporter.teleport(players, spawnLocation);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue