From 7f412f5472eb79d241569e3c14e61b5575cdcab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20S=C3=B6derberg?= Date: Wed, 15 Jul 2020 13:18:09 +0200 Subject: [PATCH] Begin work on the task system --- .../plotsquared/bukkit/BukkitPlatform.java | 20 ++- .../bukkit/inject/BukkitModule.java | 6 + .../bukkit/listener/ChunkListener.java | 17 +- .../bukkit/listener/PlayerEvents.java | 5 +- .../bukkit/queue/ChunkCoordinator.java | 4 +- .../bukkit/util/BukkitRegionManager.java | 7 +- .../bukkit/util/BukkitTaskManager.java | 81 ---------- .../util/task/BukkitPlotSquaredTask.java | 46 ++++++ .../bukkit/util/task/BukkitTaskManager.java | 94 +++++++++++ .../bukkit/util/task/PaperTimeConverter.java | 47 ++++++ .../bukkit/util/task/SpigotTimeConverter.java | 47 ++++++ .../plotsquared/core/command/CmdConfirm.java | 11 +- .../plotsquared/core/command/Condense.java | 4 +- .../core/configuration/Settings.java | 6 +- .../core/generator/HybridUtils.java | 5 +- .../core/listener/PlotListener.java | 5 +- .../java/com/plotsquared/core/plot/Plot.java | 15 +- .../core/plot/comment/CommentManager.java | 3 +- .../core/plot/expiration/ExpireManager.java | 17 +- .../core/queue/GlobalBlockQueue.java | 3 +- .../plotsquared/core/util/ChunkManager.java | 3 +- .../core/util/SchematicHandler.java | 3 +- .../core/util/task/ObjectTaskRunnable.java | 4 +- .../core/util/task/PlotSquaredTask.java | 90 +++++++++++ .../core/util/task/TaskManager.java | 136 ++++++++++++---- .../plotsquared/core/util/task/TaskTime.java | 150 ++++++++++++++++++ 26 files changed, 666 insertions(+), 163 deletions(-) delete mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitTaskManager.java create mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitPlotSquaredTask.java create mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitTaskManager.java create mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/util/task/PaperTimeConverter.java create mode 100644 Bukkit/src/main/java/com/plotsquared/bukkit/util/task/SpigotTimeConverter.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/task/PlotSquaredTask.java create mode 100644 Core/src/main/java/com/plotsquared/core/util/task/TaskTime.java diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java index e40b6698e..256736ff7 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitPlatform.java @@ -44,11 +44,13 @@ import com.plotsquared.bukkit.placeholder.PlaceholderFormatter; import com.plotsquared.bukkit.placeholder.Placeholders; import com.plotsquared.bukkit.player.BukkitPlayerManager; import com.plotsquared.bukkit.util.BukkitChatManager; -import com.plotsquared.bukkit.util.BukkitTaskManager; +import com.plotsquared.bukkit.util.task.BukkitTaskManager; import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitWorld; import com.plotsquared.bukkit.util.SetGenCB; import com.plotsquared.bukkit.util.UpdateUtility; +import com.plotsquared.bukkit.util.task.PaperTimeConverter; +import com.plotsquared.bukkit.util.task.SpigotTimeConverter; import com.plotsquared.bukkit.uuid.BungeePermsUUIDService; import com.plotsquared.bukkit.uuid.EssentialsUUIDService; import com.plotsquared.bukkit.uuid.LuckPermsUUIDService; @@ -105,6 +107,7 @@ import com.plotsquared.core.util.ReflectionUtils; import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.plotsquared.core.uuid.CacheUUIDService; import com.plotsquared.core.uuid.UUIDPipeline; import com.plotsquared.core.uuid.offline.OfflineModeUUIDService; @@ -215,9 +218,16 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass; @Override public void onEnable() { this.pluginName = getDescription().getName(); + final TaskTime.TimeConverter timeConverter; + if (PaperLib.isPaper()) { + timeConverter = new PaperTimeConverter(); + } else { + timeConverter = new SpigotTimeConverter(); + } + // Stuff that needs to be created before the PlotSquared instance PlotPlayer.registerConverter(Player.class, BukkitUtil::getPlayer); - TaskManager.setImplementation(new BukkitTaskManager(this)); + TaskManager.setImplementation(new BukkitTaskManager(this, timeConverter)); final PlotSquared plotSquared = new PlotSquared(this, "Bukkit"); @@ -370,7 +380,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass; this.setGenerator(world); } } - }, 1); + }, TaskTime.ticks(1L)); } // Services are accessed in order @@ -500,7 +510,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass; this.startMetrics(); if (Settings.Enabled_Components.WORLDS) { - TaskManager.getImplementation().taskRepeat(this::unload, 20); + TaskManager.getImplementation().taskRepeat(this::unload, TaskTime.seconds(1L)); try { singleWorldListener = getInjector().getInstance(SingleWorldListener.class); } catch (Exception e) { @@ -960,7 +970,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass; } catch (Throwable e) { e.printStackTrace(); } - }), 20); + }), TaskTime.seconds(1L)); } @Override @Nullable diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java index c6fe99ba7..e3e18b04b 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java @@ -26,6 +26,8 @@ package com.plotsquared.bukkit.inject; import com.google.inject.AbstractModule; +import com.google.inject.Provides; +import com.google.inject.Singleton; import com.google.inject.assistedinject.FactoryModuleBuilder; import com.google.inject.util.Providers; import com.plotsquared.bukkit.BukkitPlatform; @@ -39,6 +41,8 @@ import com.plotsquared.bukkit.util.BukkitPermHandler; import com.plotsquared.bukkit.util.BukkitRegionManager; import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitUtil; +import com.plotsquared.bukkit.util.task.PaperTimeConverter; +import com.plotsquared.bukkit.util.task.SpigotTimeConverter; import com.plotsquared.core.PlotPlatform; import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.generator.HybridGen; @@ -60,8 +64,10 @@ import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.WorldUtil; +import com.plotsquared.core.util.task.TaskTime; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.extension.platform.Actor; +import io.papermc.lib.PaperLib; import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit; import org.bukkit.command.ConsoleCommandSender; diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ChunkListener.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ChunkListener.java index c22df7c54..7f7143758 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ChunkListener.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/ChunkListener.java @@ -26,7 +26,6 @@ package com.plotsquared.bukkit.listener; import com.google.inject.Inject; -import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.location.Location; import com.plotsquared.core.plot.Plot; @@ -34,7 +33,9 @@ import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.util.ReflectionUtils.RefClass; import com.plotsquared.core.util.ReflectionUtils.RefField; import com.plotsquared.core.util.ReflectionUtils.RefMethod; +import com.plotsquared.core.util.task.PlotSquaredTask; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import io.papermc.lib.PaperLib; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -53,10 +54,10 @@ import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkUnloadEvent; -import javax.annotation.Nonnull; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; import java.lang.reflect.Method; import java.util.HashSet; @@ -132,7 +133,7 @@ public class ChunkListener implements Listener { } catch (Throwable e) { e.printStackTrace(); } - }, 1); + }, TaskTime.ticks(1L)); } public boolean unloadChunk(String world, Chunk chunk, boolean safe) { @@ -254,16 +255,16 @@ public class ChunkListener implements Listener { private void cleanChunk(final Chunk chunk) { TaskManager.index.incrementAndGet(); final Integer currentIndex = TaskManager.index.get(); - Integer task = TaskManager.runTaskRepeat(() -> { + PlotSquaredTask task = TaskManager.runTaskRepeat(() -> { if (!chunk.isLoaded()) { - Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); + TaskManager.tasks.get(currentIndex).cancel(); TaskManager.tasks.remove(currentIndex); chunk.unload(true); return; } BlockState[] tiles = chunk.getTileEntities(); if (tiles.length == 0) { - Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); + TaskManager.tasks.get(currentIndex).cancel(); TaskManager.tasks.remove(currentIndex); chunk.unload(true); return; @@ -272,7 +273,7 @@ public class ChunkListener implements Listener { int i = 0; while (System.currentTimeMillis() - start < 250) { if (i >= tiles.length - Settings.Chunk_Processor.MAX_TILES) { - Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); + TaskManager.tasks.get(currentIndex).cancel(); TaskManager.tasks.remove(currentIndex); chunk.unload(true); return; @@ -280,7 +281,7 @@ public class ChunkListener implements Listener { tiles[i].getBlock().setType(Material.AIR, false); i++; } - }, 5); + }, TaskTime.ticks(5L)); TaskManager.tasks.put(currentIndex, task); } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java index ce868a61e..61e40742f 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/listener/PlayerEvents.java @@ -111,6 +111,7 @@ import com.plotsquared.core.util.RegExUtil; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.world.block.BlockType; @@ -281,7 +282,7 @@ import java.util.regex.Pattern; ((BukkitPlayer) player).player.sendBlockChange(bloc, data); } } - }, 3); + }, TaskTime.ticks(3L)); } public static boolean checkEntity(Entity entity, Plot plot) { @@ -701,7 +702,7 @@ import java.util.regex.Pattern; player.saveData(); } this.eventDispatcher.doJoinTask(pp); - }, 20); + }, TaskTime.seconds(1L)); if (pp.hasPermission(Captions.PERMISSION_ADMIN_UPDATE_NOTIFICATION.getTranslated()) && Settings.Enabled_Components.UPDATE_NOTIFICATIONS && PremiumVerification.isPremium() diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/ChunkCoordinator.java b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/ChunkCoordinator.java index cc5c1f72f..adb597202 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/queue/ChunkCoordinator.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/queue/ChunkCoordinator.java @@ -26,7 +26,7 @@ package com.plotsquared.bukkit.queue; import com.google.common.base.Preconditions; -import com.plotsquared.bukkit.BukkitMain; +import com.plotsquared.bukkit.BukkitPlatform; import com.sk89q.worldedit.math.BlockVector2; import io.papermc.lib.PaperLib; import org.bukkit.Chunk; @@ -100,7 +100,7 @@ public final class ChunkCoordinator extends BukkitRunnable { this.maxIterationTime = maxIterationTime; this.whenDone = whenDone; this.throwableConsumer = throwableConsumer; - this.plugin = JavaPlugin.getPlugin(BukkitMain.class); + this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class); } /** diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java index 55dc45512..f9b0eb563 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java @@ -44,6 +44,7 @@ import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.math.BlockVector2; @@ -399,9 +400,9 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE; }); } if (!chunks.isEmpty()) { - TaskManager.runTaskLater(this, 1); + TaskManager.runTaskLater(this, TaskTime.ticks(1L)); } else { - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); } } }); @@ -456,7 +457,7 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE; PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(() -> { for (ContentMap map : maps) { map.restoreEntities(world1, 0, 0); - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); } }); } diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitTaskManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitTaskManager.java deleted file mode 100644 index c5928c261..000000000 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitTaskManager.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * _____ _ _ _____ _ - * | __ \| | | | / ____| | | - * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | - * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | - * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | - * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| - * | | - * |_| - * PlotSquared plot management system for Minecraft - * Copyright (C) 2020 IntellectualSites - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.plotsquared.bukkit.util; - -import com.google.inject.Inject; -import com.google.inject.Singleton; -import com.plotsquared.bukkit.BukkitPlatform; -import com.plotsquared.core.util.task.TaskManager; -import org.bukkit.Bukkit; - -@Singleton public class BukkitTaskManager extends TaskManager { - - private final BukkitPlatform bukkitMain; - - @Inject public BukkitTaskManager(BukkitPlatform bukkitMain) { - this.bukkitMain = bukkitMain; - } - - @Override public int taskRepeat(Runnable runnable, int interval) { - return this.bukkitMain.getServer().getScheduler() - .scheduleSyncRepeatingTask(this.bukkitMain, runnable, interval, interval); - } - - @SuppressWarnings("deprecation") @Override - public int taskRepeatAsync(Runnable runnable, int interval) { - return this.bukkitMain.getServer().getScheduler() - .scheduleAsyncRepeatingTask(this.bukkitMain, runnable, interval, interval); - } - - @Override public void taskAsync(Runnable runnable) { - if (this.bukkitMain.isEnabled()) { - this.bukkitMain.getServer().getScheduler() - .runTaskAsynchronously(this.bukkitMain, runnable); - } else { - runnable.run(); - } - } - - @Override public void task(Runnable runnable) { - this.bukkitMain.getServer().getScheduler().runTask(this.bukkitMain, runnable).getTaskId(); - } - - @Override public void taskLater(Runnable runnable, int delay) { - this.bukkitMain.getServer().getScheduler().runTaskLater(this.bukkitMain, runnable, delay) - .getTaskId(); - } - - @Override public void taskLaterAsync(Runnable runnable, int delay) { - this.bukkitMain.getServer().getScheduler() - .runTaskLaterAsynchronously(this.bukkitMain, runnable, delay); - } - - @Override public void cancelTask(int task) { - if (task != -1) { - Bukkit.getScheduler().cancelTask(task); - } - } -} diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitPlotSquaredTask.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitPlotSquaredTask.java new file mode 100644 index 000000000..d6b2cc7bf --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitPlotSquaredTask.java @@ -0,0 +1,46 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.bukkit.util.task; + +import com.plotsquared.core.util.task.PlotSquaredTask; +import lombok.RequiredArgsConstructor; +import org.bukkit.scheduler.BukkitRunnable; + +import javax.annotation.Nonnull; + +/** + * Bukkit implementation of {@link PlotSquaredTask} + */ +@RequiredArgsConstructor +public final class BukkitPlotSquaredTask extends BukkitRunnable implements PlotSquaredTask { + + @Nonnull private final Runnable runnable; + + @Override public void runTask() { + this.runnable.run(); + } + +} diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitTaskManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitTaskManager.java new file mode 100644 index 000000000..dd1168ab0 --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/BukkitTaskManager.java @@ -0,0 +1,94 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.bukkit.util.task; + +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.plotsquared.bukkit.BukkitPlatform; +import com.plotsquared.core.util.task.PlotSquaredTask; +import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; + +import javax.annotation.Nonnull; + +/** + * Bukkit implementation of {@link TaskManager} using + * by {@link org.bukkit.scheduler.BukkitScheduler} and {@link BukkitPlotSquaredTask} + */ +@Singleton public class BukkitTaskManager extends TaskManager { + + private final BukkitPlatform bukkitMain; + private final TaskTime.TimeConverter timeConverter; + + @Inject public BukkitTaskManager(@Nonnull final BukkitPlatform bukkitMain, + @Nonnull final TaskTime.TimeConverter timeConverter) { + this.bukkitMain = bukkitMain; + this.timeConverter = timeConverter; + } + + @Override + public PlotSquaredTask taskRepeat(@Nonnull final Runnable runnable, + @Nonnull final TaskTime taskTime) { + final long ticks = this.timeConverter.toTicks(taskTime); + final BukkitPlotSquaredTask bukkitPlotSquaredTask = new BukkitPlotSquaredTask(runnable); + bukkitPlotSquaredTask.runTaskTimer(this.bukkitMain, ticks, ticks); + return bukkitPlotSquaredTask; + } + + @Override + public PlotSquaredTask taskRepeatAsync(@Nonnull final Runnable runnable, + @Nonnull final TaskTime taskTime) { + final long ticks = this.timeConverter.toTicks(taskTime); + final BukkitPlotSquaredTask bukkitPlotSquaredTask = new BukkitPlotSquaredTask(runnable); + bukkitPlotSquaredTask.runTaskTimerAsynchronously(this.bukkitMain, ticks, ticks); + return bukkitPlotSquaredTask; + } + + @Override public void taskAsync(@Nonnull final Runnable runnable) { + if (this.bukkitMain.isEnabled()) { + new BukkitPlotSquaredTask(runnable).runTaskAsynchronously(this.bukkitMain); + } else { + runnable.run(); + } + } + + @Override public void task(@Nonnull final Runnable runnable) { + new BukkitPlotSquaredTask(runnable).runTaskAsynchronously(this.bukkitMain); + } + + @Override public void taskLater(@Nonnull final Runnable runnable, + @Nonnull final TaskTime taskTime) { + final long delay = this.timeConverter.toTicks(taskTime); + new BukkitPlotSquaredTask(runnable).runTaskLater(this.bukkitMain, delay); + } + + @Override public void taskLaterAsync(@Nonnull final Runnable runnable, + @Nonnull final TaskTime taskTime) { + final long delay = this.timeConverter.toTicks(taskTime); + new BukkitPlotSquaredTask(runnable).runTaskLaterAsynchronously(this.bukkitMain, delay); + } + +} diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/PaperTimeConverter.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/PaperTimeConverter.java new file mode 100644 index 000000000..883708f5f --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/PaperTimeConverter.java @@ -0,0 +1,47 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.bukkit.util.task; + +import com.plotsquared.core.util.task.TaskTime; +import org.bukkit.Bukkit; + +import javax.annotation.Nonnegative; + +/** + * Time converter that uses the server MSPT count to convert between + * different time units + */ +public final class PaperTimeConverter implements TaskTime.TimeConverter { + + @Override public long msToTicks(@Nonnegative final long ms) { + return (long) (ms / Bukkit.getAverageTickTime()); + } + + @Override public long ticksToMs(@Nonnegative final long ticks) { + return (long) (ticks * Bukkit.getAverageTickTime()); + } + +} diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/SpigotTimeConverter.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/SpigotTimeConverter.java new file mode 100644 index 000000000..86c9673d8 --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/task/SpigotTimeConverter.java @@ -0,0 +1,47 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.bukkit.util.task; + +import com.plotsquared.core.util.task.TaskTime; + +import javax.annotation.Nonnegative; + +/** + * Naive time converter that assumes that all ticks are 50 milliseconds + */ +public final class SpigotTimeConverter implements TaskTime.TimeConverter { + + private static final long MS_PER_TICKS = 50L; + + @Override public long msToTicks(@Nonnegative final long ms) { + return ms / MS_PER_TICKS; + } + + @Override public long ticksToMs(@Nonnegative final long ticks) { + return ticks * MS_PER_TICKS; + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/command/CmdConfirm.java b/Core/src/main/java/com/plotsquared/core/command/CmdConfirm.java index f7096834b..c8aee497c 100644 --- a/Core/src/main/java/com/plotsquared/core/command/CmdConfirm.java +++ b/Core/src/main/java/com/plotsquared/core/command/CmdConfirm.java @@ -29,6 +29,7 @@ import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; public class CmdConfirm { @@ -46,11 +47,9 @@ public class CmdConfirm { if (commandStr != null) { MainUtil.sendMessage(player, Captions.REQUIRES_CONFIRM, commandStr); } - TaskManager.runTaskLater(new Runnable() { - @Override public void run() { - CmdInstance cmd = new CmdInstance(runnable); - player.setMeta("cmdConfirm", cmd); - } - }, 1); + TaskManager.runTaskLater(() -> { + CmdInstance cmd = new CmdInstance(runnable); + player.setMeta("cmdConfirm", cmd); + }, TaskTime.ticks(1L)); } } diff --git a/Core/src/main/java/com/plotsquared/core/command/Condense.java b/Core/src/main/java/com/plotsquared/core/command/Condense.java index 180e26581..2b93b6839 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Condense.java +++ b/Core/src/main/java/com/plotsquared/core/command/Condense.java @@ -35,6 +35,8 @@ import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; + import javax.annotation.Nonnull; import java.util.ArrayList; @@ -177,7 +179,7 @@ public class Condense extends SubCommand { if (result.get()) { MainUtil.sendMessage(player, "Moving: " + origin + " -> " + possible); - TaskManager.runTaskLater(task, 1); + TaskManager.runTaskLater(task, TaskTime.ticks(1L)); } }, false).get()); } catch (InterruptedException | ExecutionException e) { diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java index e2fdfde60..366609cb2 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -482,9 +482,9 @@ public class Settings extends Config { @Comment("Teleport to your plot on death") public static boolean ON_DEATH = false; @Comment("Teleport to your plot on login") public static boolean ON_LOGIN = false; @Comment("Teleport to your plot on claim") public static boolean ON_CLAIM = true; - @Comment({"Add a delay to all teleport commands", - "Assign `plots.teleport.delay.bypass` to bypass the cooldown."}) public static int - DELAY = 0; + @Comment({"Add a delay to all teleport commands (in seconds)", + "Assign `plots.teleport.delay.bypass` to bypass the cooldown"}) + public static int DELAY = 0; @Comment("The visit command is ordered by world instead of globally") public static boolean PER_WORLD_VISIT = false; } diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java index 30586db05..5da96f94b 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridUtils.java @@ -54,6 +54,7 @@ import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; @@ -366,7 +367,7 @@ public class HybridUtils { analyzeRegion(origin.getWorldName(), region, new RunnableVal() { @Override public void run(PlotAnalysis value) { analysis.add(value); - TaskManager.runTaskLater(task, 1); + TaskManager.runTaskLater(task, TaskTime.ticks(1L)); } }); } @@ -511,7 +512,7 @@ public class HybridUtils { } } } - blockQueue.addEmptyTask(() -> TaskManager.runTaskLater(task, 20)); + blockQueue.addEmptyTask(() -> TaskManager.runTaskLater(task, TaskTime.seconds(1L))); }); } } diff --git a/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java b/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java index f01253053..d534dfa4b 100644 --- a/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java +++ b/Core/src/main/java/com/plotsquared/core/listener/PlotListener.java @@ -61,6 +61,7 @@ import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.sk89q.worldedit.world.gamemode.GameMode; import com.sk89q.worldedit.world.gamemode.GameModes; import com.sk89q.worldedit.world.item.ItemType; @@ -125,7 +126,7 @@ public class PlotListener { } } } - }, 20); + }, TaskTime.seconds(1L)); } public boolean plotEntry(final PlotPlayer player, final Plot plot) { @@ -279,7 +280,7 @@ public class PlotListener { replacements); player.sendTitle(main, sub); } - }, 20); + }, TaskTime.seconds(1L)); } } diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java index 70f39aa08..6b5d9d723 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java +++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java @@ -66,6 +66,7 @@ import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.plotsquared.core.uuid.UUIDPipeline; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.function.pattern.Pattern; @@ -1946,7 +1947,7 @@ public class Plot { this.getId().recalculateHash(); this.area.addPlotAbs(this); DBFunc.movePlot(this, plot); - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); return true; } @@ -2909,7 +2910,7 @@ public class Plot { this.plotListener.plotExit(pp, Plot.this); this.plotListener.plotEntry(pp, Plot.this); } - }, 1); + }, TaskTime.ticks(1L)); } public void debug(@Nonnull final String message) { @@ -3004,7 +3005,7 @@ public class Plot { MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT); player.teleport(location, cause); } - }, Settings.Teleport.DELAY * 20); + }, TaskTime.seconds(Settings.Teleport.DELAY)); resultConsumer.accept(true); }; if (this.area.isHomeAllowNonmember() || plot.isAdded(player.getUUID())) { @@ -3154,7 +3155,7 @@ public class Plot { final int offsetX = db.getX() - ob.getX(); final int offsetZ = db.getZ() - ob.getZ(); if (!this.hasOwner()) { - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); return CompletableFuture.completedFuture(false); } AtomicBoolean occupied = new AtomicBoolean(false); @@ -3163,7 +3164,7 @@ public class Plot { Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); if (other.hasOwner()) { if (!allowSwap) { - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); return CompletableFuture.completedFuture(false); } occupied.set(true); @@ -3270,14 +3271,14 @@ public class Plot { final int offsetX = db.getX() - ob.getX(); final int offsetZ = db.getZ() - ob.getZ(); if (!this.hasOwner()) { - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); return false; } Set plots = this.getConnectedPlots(); for (Plot plot : plots) { Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); if (other.hasOwner()) { - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); return false; } } diff --git a/Core/src/main/java/com/plotsquared/core/plot/comment/CommentManager.java b/Core/src/main/java/com/plotsquared/core/plot/comment/CommentManager.java index 141d729c7..c751fe54a 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/comment/CommentManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/comment/CommentManager.java @@ -32,6 +32,7 @@ import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import java.util.Collection; import java.util.HashMap; @@ -72,7 +73,7 @@ import java.util.concurrent.atomic.AtomicInteger; } }); } - }, 20); + }, TaskTime.seconds(1L)); } public static long getTimestamp(PlotPlayer player, String inbox) { diff --git a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java index e805ff87a..af14ed3eb 100644 --- a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java +++ b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java @@ -43,15 +43,15 @@ import com.plotsquared.core.plot.flag.implementations.KeepFlag; import com.plotsquared.core.plot.message.PlotMessage; import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.MainUtil; -import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import javax.annotation.Nonnull; +import javax.annotation.Nonnull; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -326,7 +326,8 @@ public class ExpireManager { } for (ExpiryTask expiryTask : expired) { if (!expiryTask.needsAnalysis()) { - expiredTask.run(newPlot, () -> TaskManager.getImplementation().taskLaterAsync(task, 1), + expiredTask.run(newPlot, () -> TaskManager.getImplementation() + .taskLaterAsync(task, TaskTime.ticks(1L)), expiryTask.requiresConfirmation()); return; } @@ -337,7 +338,7 @@ public class ExpireManager { passesComplexity(changed, expired, new RunnableVal() { @Override public void run(Boolean confirmation) { expiredTask.run(newPlot, - () -> TaskManager.getImplementation().taskLaterAsync(task, 1), + () -> TaskManager.getImplementation().taskLaterAsync(task, TaskTime.ticks(1L)), confirmation); } }, () -> { @@ -350,7 +351,7 @@ public class ExpireManager { return; } newPlot.setFlag(event.getFlag()); - TaskManager.runTaskLaterAsync(task, 20); + TaskManager.runTaskLaterAsync(task, TaskTime.seconds(1L)); }); } }; @@ -363,7 +364,7 @@ public class ExpireManager { @Override public void run(Boolean value) { doAnalysis.run(); } - }, () -> TaskManager.getImplementation().taskLaterAsync(task, 1)); + }, () -> TaskManager.getImplementation().taskLaterAsync(task, TaskTime.ticks(1L))); } else { doAnalysis.run(); } @@ -376,9 +377,9 @@ public class ExpireManager { ExpireManager.this.running = 2; runTask(expiredTask); } - }, 86400000); + }, TaskTime.ticks(86400000)); } else { - TaskManager.runTaskLaterAsync(task, 20 * 10); + TaskManager.runTaskLaterAsync(task, TaskTime.seconds(10L)); } } }); diff --git a/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java b/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java index 9f79102b0..1ef62a4eb 100644 --- a/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java +++ b/Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java @@ -28,6 +28,7 @@ package com.plotsquared.core.queue; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import java.util.ArrayList; import java.util.ConcurrentModificationException; @@ -165,7 +166,7 @@ public class GlobalBlockQueue { SET_TASK.value2.endSet(true); } } - }, 1); + }, TaskTime.ticks(1L)); return true; } diff --git a/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java b/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java index f9809840f..438f60940 100644 --- a/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/ChunkManager.java @@ -32,6 +32,7 @@ import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.queue.ScopedLocalBlockQueue; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.regions.CuboidRegion; @@ -172,7 +173,7 @@ public abstract class ChunkManager { task.run(); } if (!chunks.isEmpty()) { - TaskManager.runTaskLater(this, 1); + TaskManager.runTaskLater(this, TaskTime.ticks(1L)); } else { TaskManager.runTask(whenDone); } diff --git a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java index 7f933df24..fde4a7008 100644 --- a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java +++ b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java @@ -35,6 +35,7 @@ import com.plotsquared.core.plot.schematic.Schematic; import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; +import com.plotsquared.core.util.task.TaskTime; import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.IntArrayTag; @@ -661,7 +662,7 @@ public abstract class SchematicHandler { zTask.run(); } if (yiter.hasNext()) { - TaskManager.runTaskLater(this, 1); + TaskManager.runTaskLater(this, TaskTime.ticks(1L)); } else { regionTask.run(); } diff --git a/Core/src/main/java/com/plotsquared/core/util/task/ObjectTaskRunnable.java b/Core/src/main/java/com/plotsquared/core/util/task/ObjectTaskRunnable.java index 63c0ebc8c..547541332 100644 --- a/Core/src/main/java/com/plotsquared/core/util/task/ObjectTaskRunnable.java +++ b/Core/src/main/java/com/plotsquared/core/util/task/ObjectTaskRunnable.java @@ -44,9 +44,9 @@ public class ObjectTaskRunnable implements Runnable { task.run(); } if (!hasNext) { - TaskManager.runTaskLater(whenDone, 1); + TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L)); } else { - TaskManager.runTaskLater(this, 1); + TaskManager.runTaskLater(this, TaskTime.ticks(1L)); } } diff --git a/Core/src/main/java/com/plotsquared/core/util/task/PlotSquaredTask.java b/Core/src/main/java/com/plotsquared/core/util/task/PlotSquaredTask.java new file mode 100644 index 000000000..3f1f9a16b --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/task/PlotSquaredTask.java @@ -0,0 +1,90 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.task; + +/** + * A task that can be run and cancelled (if repeating) + */ +public interface PlotSquaredTask extends Runnable { + + /** + * Run the task. Don't override this, instead + * implement {@link #runTask()} + */ + @Override default void run() { + if (isCancelled()) { + return; + } + this.runTask(); + } + + /** + * Run the task + */ + void runTask(); + + /** + * Check if the task has been cancelled + * + * @return {@code true} if the tasks is cancelled, + * {@code false} if not + */ + boolean isCancelled(); + + /** + * Cancel the task + */ + void cancel(); + + /** + * Get a new {@link NullTask} + * + * @return Null task instance + */ + static NullTask nullTask() { + return new NullTask(); + } + + + /** + * Task that does nothing and is always cancelled + */ + class NullTask implements PlotSquaredTask { + + @Override public void runTask() { + } + + @Override public boolean isCancelled() { + return true; + } + + @Override public void cancel() { + } + + } + +} + diff --git a/Core/src/main/java/com/plotsquared/core/util/task/TaskManager.java b/Core/src/main/java/com/plotsquared/core/util/task/TaskManager.java index 0e2a923e2..e39d8182b 100644 --- a/Core/src/main/java/com/plotsquared/core/util/task/TaskManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/task/TaskManager.java @@ -29,7 +29,10 @@ import com.plotsquared.core.PlotSquared; import com.plotsquared.core.util.RuntimeExceptionRunnableVal; import lombok.Getter; import lombok.Setter; +import org.jetbrains.annotations.NotNull; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -40,32 +43,55 @@ import java.util.concurrent.atomic.AtomicInteger; public abstract class TaskManager { public static final HashSet TELEPORT_QUEUE = new HashSet<>(); - public static final HashMap tasks = new HashMap<>(); + public static final HashMap tasks = new HashMap<>(); public static AtomicInteger index = new AtomicInteger(0); @Getter @Setter private static TaskManager implementation; - public static int runTaskRepeat(Runnable runnable, int interval) { + /** + * Run a repeating synchronous task. If using a platform scheduler, + * this is guaranteed to run on the server thread + * + * @param runnable Task to run + * @param taskTime Task interval + * @return Created task object, can be used to cancel the task + */ + @Nonnull public static PlotSquaredTask runTaskRepeat(@Nullable final Runnable runnable, + @Nonnull final TaskTime taskTime) { if (runnable != null) { if (getImplementation() == null) { throw new IllegalArgumentException("disabled"); } - return getImplementation().taskRepeat(runnable, interval); + return getImplementation().taskRepeat(runnable, taskTime); } - return -1; + return PlotSquaredTask.nullTask(); } - public static int runTaskRepeatAsync(Runnable runnable, int interval) { + /** + * Run a repeating asynchronous task. This will never run on the + * server thread + * + * @param runnable Task to run + * @param taskTime Task interval + * @return Created task object, can be used to cancel the task + */ + @Nonnull public static PlotSquaredTask runTaskRepeatAsync(@Nullable final Runnable runnable, + @NotNull final TaskTime taskTime) { if (runnable != null) { if (getImplementation() == null) { throw new IllegalArgumentException("disabled"); } - return getImplementation().taskRepeatAsync(runnable, interval); + return getImplementation().taskRepeatAsync(runnable, taskTime); } - return -1; + return PlotSquaredTask.nullTask(); } - public static void runTaskAsync(Runnable runnable) { + /** + * Run an asynchronous task. This will never run on the server thread + * + * @param runnable Task to run + */ + public static void runTaskAsync(@Nullable final Runnable runnable) { if (runnable != null) { if (getImplementation() == null) { runnable.run(); @@ -75,7 +101,13 @@ public abstract class TaskManager { } } - public static void runTask(Runnable runnable) { + /** + * Run a synchronous task. If using a platform scheduler, this is guaranteed + * to run on the server thread + * + * @param runnable Task to run + */ + public static void runTask(@Nullable final Runnable runnable) { if (runnable != null) { if (getImplementation() == null) { runnable.run(); @@ -86,37 +118,43 @@ public abstract class TaskManager { } /** - * Run task later. + * Run a synchronous task after a given delay. + * If using a platform scheduler, this is guaranteed to run on the server thread * - * @param runnable The task - * @param delay The delay in ticks + * @param runnable Task to run + * @param taskTime Task delay */ - public static void runTaskLater(Runnable runnable, int delay) { + public static void runTaskLater(@Nullable final Runnable runnable, + @Nonnull final TaskTime taskTime) { if (runnable != null) { if (getImplementation() == null) { runnable.run(); return; } - getImplementation().taskLater(runnable, delay); + getImplementation().taskLater(runnable, taskTime); } } - public static void runTaskLaterAsync(Runnable runnable, int delay) { + /** + * Run an asynchronous task after a given delay. This will never + * run on the server thread + * + * @param runnable Task to run + * @param taskTime Task delay + */ + public static void runTaskLaterAsync(@Nullable final Runnable runnable, + @Nonnull final TaskTime taskTime) { if (runnable != null) { if (getImplementation() == null) { runnable.run(); return; } - getImplementation().taskLaterAsync(runnable, delay); + getImplementation().taskLaterAsync(runnable, taskTime); } } /** * Break up a series of tasks so that they can run without lagging the server. - * - * @param objects - * @param task - * @param whenDone */ public static void objectTask(Collection objects, final RunnableVal task, final Runnable whenDone) { @@ -152,17 +190,61 @@ public abstract class TaskManager { return function.value; } - public abstract int taskRepeat(Runnable runnable, int interval); + /** + * Run a repeating synchronous task. If using a platform scheduler, + * this is guaranteed to run on the server thread + * + * @param runnable Task to run + * @param taskTime Task interval + * @return Created task object, can be used to cancel the task + */ + public abstract PlotSquaredTask taskRepeat(@Nonnull Runnable runnable, + @Nonnull TaskTime taskTime); - public abstract int taskRepeatAsync(Runnable runnable, int interval); + /** + * Run a repeating asynchronous task. This will never run on the + * server thread + * + * @param runnable Task to run + * @param taskTime Task interval + * @return Created task object, can be used to cancel the task + */ + public abstract PlotSquaredTask taskRepeatAsync(@Nonnull Runnable runnable, + @Nonnull TaskTime taskTime); - public abstract void taskAsync(Runnable runnable); + /** + * Run an asynchronous task. This will never run on the server thread + * + * @param runnable Task to run + */ + public abstract void taskAsync(@Nonnull Runnable runnable); - public abstract void task(Runnable runnable); + /** + * Run a synchronous task. If using a platform scheduler, this is guaranteed + * to run on the server thread + * + * @param runnable Task to run + */ + public abstract void task(@Nonnull Runnable runnable); - public abstract void taskLater(Runnable runnable, int delay); + /** + * Run a synchronous task after a given delay. + * If using a platform scheduler, this is guaranteed to run on the server thread + * + * @param runnable Task to run + * @param taskTime Task delay + */ + public abstract void taskLater(@Nonnull Runnable runnable, + @Nonnull TaskTime taskTime); - public abstract void taskLaterAsync(Runnable runnable, int delay); + /** + * Run an asynchronous task after a given delay. This will never + * run on the server thread + * + * @param runnable Task to run + * @param taskTime Task delay + */ + public abstract void taskLaterAsync(@Nonnull Runnable runnable, + @Nonnull TaskTime taskTime); - public abstract void cancelTask(int task); } diff --git a/Core/src/main/java/com/plotsquared/core/util/task/TaskTime.java b/Core/src/main/java/com/plotsquared/core/util/task/TaskTime.java new file mode 100644 index 000000000..d11a0b111 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/task/TaskTime.java @@ -0,0 +1,150 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2020 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.task; + +import lombok.EqualsAndHashCode; +import lombok.ToString; + +import javax.annotation.Nonnegative; +import javax.annotation.Nonnull; + +/** + * Task timings + */ +@EqualsAndHashCode @ToString @SuppressWarnings("unused") +public final class TaskTime { + + private final long time; + private final TaskUnit unit; + + private TaskTime(@Nonnegative final long time, @Nonnull final TaskUnit unit) { + this.time = time; + this.unit = unit; + } + + /** + * Create a new task time in seconds + * + * @param seconds Seconds + * @return Created task time instance + */ + @Nonnull public static TaskTime seconds(@Nonnegative final long seconds) { + return new TaskTime(seconds * 1000L, TaskUnit.MILLISECONDS); + } + + /** + * Create a new task time in server ticks + * + * @param ticks Server ticks + * @return Created task time instance + */ + @Nonnull public static TaskTime ticks(@Nonnegative final long ticks) { + return new TaskTime(ticks, TaskUnit.TICKS); + } + + /** + * Create a new task time in milliseconds + * + * @param ms Milliseconds + * @return Created task time instance + */ + @Nonnull public static TaskTime ms(@Nonnegative final long ms) { + return new TaskTime(ms, TaskUnit.MILLISECONDS); + } + + /** + * Get the task time + * + * @return Task time + */ + @Nonnegative public long getTime() { + return this.time; + } + + /** + * Get the time unit + * + * @return Time unit + */ + @Nonnull public TaskUnit getUnit() { + return this.unit; + } + + + public enum TaskUnit { + TICKS, MILLISECONDS + } + + + public interface TimeConverter { + + /** + * Convert from milliseconds to server ticks + * + * @param ms Milliseconds + * @return Server ticks + */ + @Nonnegative long msToTicks(@Nonnegative final long ms); + + /** + * Convert from server ticks to milliseconds + * + * @param ticks Server ticks + * @return Milliseconds + */ + @Nonnegative long ticksToMs(@Nonnegative final long ticks); + + /** + * Convert the task time to server ticks + * + * @param taskTime Task time + * @return Server ticks + */ + @Nonnegative default long toTicks(@Nonnull final TaskTime taskTime) { + if (taskTime.getUnit() == TaskUnit.TICKS) { + return taskTime.getTime(); + } else { + return this.msToTicks(taskTime.getTime()); + } + } + + /** + * Convert the task time to milliseconds + * + * @param taskTime Task time + * @return Milliseconds + */ + @Nonnegative default long toMs(@Nonnull final TaskTime taskTime) { + if (taskTime.getUnit() == TaskUnit.MILLISECONDS) { + return taskTime.getTime(); + } else { + return this.ticksToMs(taskTime.getTime()); + } + } + + } + +}