diff --git a/plugin/src/main/java/de/epiceric/shopchest/action/ActionManager.java b/plugin/src/main/java/de/epiceric/shopchest/action/ActionManager.java new file mode 100644 index 0000000..a2d0589 --- /dev/null +++ b/plugin/src/main/java/de/epiceric/shopchest/action/ActionManager.java @@ -0,0 +1,44 @@ +package de.epiceric.shopchest.action; + +import java.util.*; + +public class ActionManager { + + private final Map playerActions; + + public ActionManager() { + playerActions = new HashMap<>(); + } + + /** + * Submit a {@link PendingAction} for a {@link org.bukkit.entity.Player} + * + * @param playerId the {@link org.bukkit.entity.Player}'s {@link UUID} + * @param action The {@link PendingAction} that he will do + * @return An {@link Optional} {@link PendingAction} which is : + * - empty if the action was correctly submitted + * - filled by the current action that has not been executed (mean that the submitted action is rejected) + */ + public Optional submitAction(UUID playerId, PendingAction action) { + Objects.requireNonNull(playerId); + Objects.requireNonNull(action); + final PendingAction registeredAction = playerActions.compute( + playerId, + (k, v) -> (v == null || v.hasExpired() ? action : v) + ); + return registeredAction == action ? Optional.empty() : Optional.of(registeredAction); + } + + /** + * Get the current action of a {@link org.bukkit.entity.Player} + * + * @param uuid {@link org.bukkit.entity.Player}'s {@link UUID} + * @return An {@link Optional} {@link PendingAction} which is : + * - empty if there is no pending action for this player + * - filled by the current valid pending action if there is one + */ + public Optional getAction(UUID uuid) { + return Optional.ofNullable(playerActions.computeIfPresent(uuid, (k, v) -> v.hasExpired() ? null : v)); + } + +} diff --git a/plugin/src/main/java/de/epiceric/shopchest/action/PendingAction.java b/plugin/src/main/java/de/epiceric/shopchest/action/PendingAction.java new file mode 100644 index 0000000..8fe5118 --- /dev/null +++ b/plugin/src/main/java/de/epiceric/shopchest/action/PendingAction.java @@ -0,0 +1,42 @@ +package de.epiceric.shopchest.action; + +import org.bukkit.block.Block; + +import java.util.concurrent.CompletableFuture; + +public abstract class PendingAction { + + protected final Block block; + protected final long endTime; + + public PendingAction(Block block, long duration) { + this.block = block; + this.endTime = System.currentTimeMillis() + duration; + } + + /** + * Check if the action is applicable to a specific {@link Block} + * + * @param block The block to check + * @return {@code true} if this action is applicable to this {@link Block}, {@code false} otherwise + */ + public abstract boolean canApply(Block block); + + /** + * Check if this action is still valid + * + * @return {@code true} if this action is valid, {@code false} otherwise + */ + public boolean hasExpired() { + return System.currentTimeMillis() > endTime; + } + + /** + * Execute the action + * + * @param block The targeted block by this action + * @return A {@link CompletableFuture} that symbolize the execute action + */ + public abstract CompletableFuture execute(Block block); + +}