package tc.oc.commons.bukkit.util; import java.util.UUID; import java.util.concurrent.Executor; import javax.inject.Inject; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import tc.oc.api.bukkit.users.OnlinePlayers; import tc.oc.api.docs.SimpleUserId; import tc.oc.api.docs.UserId; import tc.oc.minecraft.scheduler.SyncExecutor; import tc.oc.minecraft.scheduler.MainThreadExecutor; import tc.oc.commons.core.concurrent.ContextualExecutor; import tc.oc.commons.core.concurrent.ContextualExecutorImpl; /** * Creates {@link ContextualExecutor}s for {@link Player}s that will only execute * tasks when the player is online. If the same player reconnects, their current * {@link Player} instance will always be passed to the tasks. */ public class SyncPlayerExecutorFactory { private final MainThreadExecutor mainThreadExecutor; private final SyncExecutor syncExecutor; private final OnlinePlayers onlinePlayers; @Inject SyncPlayerExecutorFactory(MainThreadExecutor mainThreadExecutor, SyncExecutor syncExecutor, OnlinePlayers onlinePlayers) { this.mainThreadExecutor = mainThreadExecutor; this.syncExecutor = syncExecutor; this.onlinePlayers = onlinePlayers; } public <T extends CommandSender> ContextualExecutor<CommandSender> mainThread(T sender) { return create(sender, mainThreadExecutor); } public ContextualExecutor<Player> mainThread(Player player) { return create(player, mainThreadExecutor); } public ContextualExecutor<Player> mainThread(UserId userId) { return create(userId, mainThreadExecutor); } public <T extends CommandSender> ContextualExecutor<CommandSender> queued(T sender) { return create(sender, syncExecutor); } public ContextualExecutor<Player> queued(Player player) { return create(player, syncExecutor); } public ContextualExecutor<Player> queued(UserId userId) { return create(userId, syncExecutor); } public <T extends CommandSender> ContextualExecutor<T> create(T sender, Executor executor) { if(sender instanceof Player) { return (ContextualExecutor<T>) create((Player) sender, executor); } else { return new ContextualExecutorImpl<>(() -> sender, executor); } } public ContextualExecutor<Player> create(Player player, Executor executor) { final UUID uuid = player.getUniqueId(); return new ContextualExecutorImpl<>(() -> onlinePlayers.find(uuid), executor); } public ContextualExecutor<Player> create(UserId userId, Executor executor) { final UserId simpleUserId = SimpleUserId.copyOf(userId); return new ContextualExecutorImpl<>(() -> onlinePlayers.find(simpleUserId), executor); } }