Merge branch 'v6' into feature/v6/pipeline-queue

# Conflicts:
#	Core/src/main/java/com/plotsquared/core/command/Trim.java
#	Core/src/main/java/com/plotsquared/core/queue/BasicLocalBlockQueue.java
#	Core/src/main/java/com/plotsquared/core/queue/GlobalBlockQueue.java
This commit is contained in:
dordsor21 2020-07-17 17:16:49 +01:00
commit 74c6fc954e
No known key found for this signature in database
GPG Key ID: 1E53E88969FFCF0B
35 changed files with 889 additions and 309 deletions

View File

@ -44,11 +44,13 @@ import com.plotsquared.bukkit.placeholder.PlaceholderFormatter;
import com.plotsquared.bukkit.placeholder.Placeholders; import com.plotsquared.bukkit.placeholder.Placeholders;
import com.plotsquared.bukkit.player.BukkitPlayerManager; import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.util.BukkitChatManager; 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.BukkitUtil;
import com.plotsquared.bukkit.util.BukkitWorld; import com.plotsquared.bukkit.util.BukkitWorld;
import com.plotsquared.bukkit.util.SetGenCB; import com.plotsquared.bukkit.util.SetGenCB;
import com.plotsquared.bukkit.util.UpdateUtility; 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.BungeePermsUUIDService;
import com.plotsquared.bukkit.uuid.EssentialsUUIDService; import com.plotsquared.bukkit.uuid.EssentialsUUIDService;
import com.plotsquared.bukkit.uuid.LuckPermsUUIDService; import com.plotsquared.bukkit.uuid.LuckPermsUUIDService;
@ -104,6 +106,7 @@ import com.plotsquared.core.util.ReflectionUtils;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.TaskManager; 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.CacheUUIDService;
import com.plotsquared.core.uuid.UUIDPipeline; import com.plotsquared.core.uuid.UUIDPipeline;
import com.plotsquared.core.uuid.offline.OfflineModeUUIDService; import com.plotsquared.core.uuid.offline.OfflineModeUUIDService;
@ -216,9 +219,16 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
@Override public void onEnable() { @Override public void onEnable() {
this.pluginName = getDescription().getName(); 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 // Stuff that needs to be created before the PlotSquared instance
PlotPlayer.registerConverter(Player.class, BukkitUtil::getPlayer); PlotPlayer.registerConverter(Player.class, BukkitUtil::getPlayer);
TaskManager.setImplementation(new BukkitTaskManager(this)); TaskManager.setPlatformImplementation(new BukkitTaskManager(this, timeConverter));
final PlotSquared plotSquared = new PlotSquared(this, "Bukkit"); final PlotSquared plotSquared = new PlotSquared(this, "Bukkit");
@ -380,7 +390,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
this.setGenerator(world); this.setGenerator(world);
} }
} }
}, 1); }, TaskTime.ticks(1L));
} }
// Services are accessed in order // Services are accessed in order
@ -513,7 +523,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
this.startMetrics(); this.startMetrics();
if (Settings.Enabled_Components.WORLDS) { if (Settings.Enabled_Components.WORLDS) {
TaskManager.getImplementation().taskRepeat(this::unload, 20); TaskManager.getPlatformImplementation().taskRepeat(this::unload, TaskTime.seconds(1L));
try { try {
singleWorldListener = getInjector().getInstance(SingleWorldListener.class); singleWorldListener = getInjector().getInstance(SingleWorldListener.class);
} catch (Exception e) { } catch (Exception e) {
@ -978,7 +988,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
}), 20); }), TaskTime.seconds(1L));
} }
@Override @Nullable @Override @Nullable

View File

@ -26,6 +26,8 @@
package com.plotsquared.bukkit.inject; package com.plotsquared.bukkit.inject;
import com.google.inject.AbstractModule; 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.assistedinject.FactoryModuleBuilder;
import com.google.inject.util.Providers; import com.google.inject.util.Providers;
import com.plotsquared.bukkit.BukkitPlatform; 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.BukkitRegionManager;
import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitSetupUtils;
import com.plotsquared.bukkit.util.BukkitUtil; 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.PlotPlatform;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.generator.HybridGen; import com.plotsquared.core.generator.HybridGen;

View File

@ -26,7 +26,6 @@
package com.plotsquared.bukkit.listener; package com.plotsquared.bukkit.listener;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.Plot; 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.RefClass;
import com.plotsquared.core.util.ReflectionUtils.RefField; import com.plotsquared.core.util.ReflectionUtils.RefField;
import com.plotsquared.core.util.ReflectionUtils.RefMethod; 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.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
@ -53,12 +54,13 @@ import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.ItemSpawnEvent; import org.bukkit.event.entity.ItemSpawnEvent;
import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.event.world.ChunkUnloadEvent; import org.bukkit.event.world.ChunkUnloadEvent;
import javax.annotation.Nonnull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashSet; import java.util.HashSet;
import java.util.Objects;
import static com.plotsquared.core.util.ReflectionUtils.getRefClass; import static com.plotsquared.core.util.ReflectionUtils.getRefClass;
@ -132,7 +134,7 @@ public class ChunkListener implements Listener {
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); e.printStackTrace();
} }
}, 1); }, TaskTime.ticks(1L));
} }
public boolean unloadChunk(String world, Chunk chunk, boolean safe) { public boolean unloadChunk(String world, Chunk chunk, boolean safe) {
@ -254,17 +256,15 @@ public class ChunkListener implements Listener {
private void cleanChunk(final Chunk chunk) { private void cleanChunk(final Chunk chunk) {
TaskManager.index.incrementAndGet(); TaskManager.index.incrementAndGet();
final Integer currentIndex = TaskManager.index.get(); final Integer currentIndex = TaskManager.index.get();
Integer task = TaskManager.runTaskRepeat(() -> { PlotSquaredTask task = TaskManager.runTaskRepeat(() -> {
if (!chunk.isLoaded()) { if (!chunk.isLoaded()) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); Objects.requireNonNull(TaskManager.removeTask(currentIndex)).cancel();
TaskManager.tasks.remove(currentIndex);
chunk.unload(true); chunk.unload(true);
return; return;
} }
BlockState[] tiles = chunk.getTileEntities(); BlockState[] tiles = chunk.getTileEntities();
if (tiles.length == 0) { if (tiles.length == 0) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); Objects.requireNonNull(TaskManager.removeTask(currentIndex)).cancel();
TaskManager.tasks.remove(currentIndex);
chunk.unload(true); chunk.unload(true);
return; return;
} }
@ -272,16 +272,15 @@ public class ChunkListener implements Listener {
int i = 0; int i = 0;
while (System.currentTimeMillis() - start < 250) { while (System.currentTimeMillis() - start < 250) {
if (i >= tiles.length - Settings.Chunk_Processor.MAX_TILES) { if (i >= tiles.length - Settings.Chunk_Processor.MAX_TILES) {
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex)); Objects.requireNonNull(TaskManager.removeTask(currentIndex)).cancel();
TaskManager.tasks.remove(currentIndex);
chunk.unload(true); chunk.unload(true);
return; return;
} }
tiles[i].getBlock().setType(Material.AIR, false); tiles[i].getBlock().setType(Material.AIR, false);
i++; i++;
} }
}, 5); }, TaskTime.ticks(5L));
TaskManager.tasks.put(currentIndex, task); TaskManager.addTask(task, currentIndex);
} }
public boolean processChunk(Chunk chunk, boolean unload) { public boolean processChunk(Chunk chunk, boolean unload) {

View File

@ -111,6 +111,7 @@ import com.plotsquared.core.util.RegExUtil;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
@ -281,7 +282,7 @@ import java.util.regex.Pattern;
((BukkitPlayer) player).player.sendBlockChange(bloc, data); ((BukkitPlayer) player).player.sendBlockChange(bloc, data);
} }
} }
}, 3); }, TaskTime.ticks(3L));
} }
public static boolean checkEntity(Entity entity, Plot plot) { public static boolean checkEntity(Entity entity, Plot plot) {
@ -701,7 +702,7 @@ import java.util.regex.Pattern;
player.saveData(); player.saveData();
} }
this.eventDispatcher.doJoinTask(pp); this.eventDispatcher.doJoinTask(pp);
}, 20); }, TaskTime.seconds(1L));
if (pp.hasPermission(Captions.PERMISSION_ADMIN_UPDATE_NOTIFICATION.getTranslated()) if (pp.hasPermission(Captions.PERMISSION_ADMIN_UPDATE_NOTIFICATION.getTranslated())
&& Settings.Enabled_Components.UPDATE_NOTIFICATIONS && PremiumVerification.isPremium() && Settings.Enabled_Components.UPDATE_NOTIFICATIONS && PremiumVerification.isPremium()
@ -841,7 +842,7 @@ import java.util.regex.Pattern;
Player player = event.getPlayer(); Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.getPlayer(player); BukkitPlayer pp = BukkitUtil.getPlayer(player);
// Cancel teleport // Cancel teleport
if (TaskManager.TELEPORT_QUEUE.remove(pp.getName())) { if (TaskManager.removeFromTeleportQueue(pp.getName())) {
MainUtil.sendMessage(pp, Captions.TELEPORT_FAILED); MainUtil.sendMessage(pp, Captions.TELEPORT_FAILED);
} }
// Set last location // Set last location
@ -903,7 +904,7 @@ import java.util.regex.Pattern;
Player player = event.getPlayer(); Player player = event.getPlayer();
BukkitPlayer pp = BukkitUtil.getPlayer(player); BukkitPlayer pp = BukkitUtil.getPlayer(player);
// Cancel teleport // Cancel teleport
if (TaskManager.TELEPORT_QUEUE.remove(pp.getName())) { if (TaskManager.removeFromTeleportQueue(pp.getName())) {
MainUtil.sendMessage(pp, Captions.TELEPORT_FAILED); MainUtil.sendMessage(pp, Captions.TELEPORT_FAILED);
} }
// Set last location // Set last location
@ -2416,7 +2417,7 @@ import java.util.regex.Pattern;
} }
@EventHandler(priority = EventPriority.MONITOR) public void onLeave(PlayerQuitEvent event) { @EventHandler(priority = EventPriority.MONITOR) public void onLeave(PlayerQuitEvent event) {
TaskManager.TELEPORT_QUEUE.remove(event.getPlayer().getName()); TaskManager.removeFromTeleportQueue(event.getPlayer().getName());
BukkitPlayer pp = BukkitUtil.getPlayer(event.getPlayer()); BukkitPlayer pp = BukkitUtil.getPlayer(event.getPlayer());
pp.unregister(); pp.unregister();
this.logout(pp.getUUID()); this.logout(pp.getUUID());

View File

@ -44,6 +44,7 @@ import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; 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.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
@ -402,9 +403,9 @@ public class BukkitRegionManager extends RegionManager {
}); });
} }
if (!chunks.isEmpty()) { if (!chunks.isEmpty()) {
TaskManager.runTaskLater(this, 1); TaskManager.runTaskLater(this, TaskTime.ticks(1L));
} else { } else {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
} }
} }
}); });
@ -458,7 +459,7 @@ public class BukkitRegionManager extends RegionManager {
PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(() -> { PlotSquared.platform().getGlobalBlockQueue().addEmptyTask(() -> {
for (ContentMap map : maps) { for (ContentMap map : maps) {
map.restoreEntities(world1, 0, 0); map.restoreEntities(world1, 0, 0);
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
} }
}); });
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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);
}
}
}

View File

@ -42,7 +42,6 @@ import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.StringComparison; import com.plotsquared.core.util.StringComparison;
import com.plotsquared.core.util.WorldUtil; 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.TaskManager;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
@ -54,7 +53,6 @@ import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.Material; import org.bukkit.Material;
@ -96,11 +94,11 @@ import org.bukkit.entity.Snowman;
import org.bukkit.entity.Tameable; import org.bukkit.entity.Tameable;
import org.bukkit.entity.Vehicle; import org.bukkit.entity.Vehicle;
import org.bukkit.entity.WaterMob; import org.bukkit.entity.WaterMob;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@ -423,14 +421,18 @@ import java.util.stream.Stream;
@Override @Nullable public String[] getSignSynchronous(@Nonnull final Location location) { @Override @Nullable public String[] getSignSynchronous(@Nonnull final Location location) {
Block block = getWorld(location.getWorldName()) Block block = getWorld(location.getWorldName())
.getBlockAt(location.getX(), location.getY(), location.getZ()); .getBlockAt(location.getX(), location.getY(), location.getZ());
return TaskManager.getImplementation().sync(new RunnableVal<String[]>() { try {
@Override public void run(String[] value) { return TaskManager.getPlatformImplementation().sync(() -> {
if (block.getState() instanceof Sign) { if (block.getState() instanceof Sign) {
Sign sign = (Sign) block.getState(); Sign sign = (Sign) block.getState();
this.value = sign.getLines(); return sign.getLines();
}
} }
return new String[0];
}); });
} catch (final Exception e) {
e.printStackTrace();
}
return new String[0];
} }
@Override public Location getSpawn(@Nonnull final String world) { @Override public Location getSpawn(@Nonnull final String world) {

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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();
}
}

View File

@ -0,0 +1,111 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* 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 <http://www.gnu.org/licenses/>.
*/
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.PlotSquared;
import com.plotsquared.core.util.task.PlotSquaredTask;
import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nonnull;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* 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 <T> T sync(@Nonnull final Callable<T> function, final int timeout) throws Exception {
if (PlotSquared.get().isMainThread(Thread.currentThread())) {
return function.call();
}
return this.callMethodSync(function).get(timeout, TimeUnit.MILLISECONDS);
}
@Override public <T> Future<T> callMethodSync(@NotNull final Callable<T> method) {
return Bukkit.getScheduler().callSyncMethod(this.bukkitMain, method);
}
@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);
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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 Math.max(1L, (long) (ms / Bukkit.getAverageTickTime()));
}
@Override public long ticksToMs(@Nonnegative final long ticks) {
return Math.max(1L, (long) (ticks * Bukkit.getAverageTickTime()));
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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 Math.max(1L, ms / MS_PER_TICKS);
}
@Override public long ticksToMs(@Nonnegative final long ticks) {
return Math.max(1L, ticks * MS_PER_TICKS);
}
}

View File

@ -147,13 +147,17 @@ public class Auto extends SubCommand {
* @param start * @param start
* @param schematic * @param schematic
*/ */
public static void autoClaimSafe(final PlotPlayer player, final PlotArea area, PlotId start, public static void autoClaimSafe(final PlotPlayer<?> player, final PlotArea area, PlotId start,
final String schematic) { final String schematic) {
player.setMeta(Auto.class.getName(), true); player.setMeta(Auto.class.getName(), true);
autoClaimFromDatabase(player, area, start, new RunnableVal<Plot>() { autoClaimFromDatabase(player, area, start, new RunnableVal<Plot>() {
@Override public void run(final Plot plot) { @Override public void run(final Plot plot) {
TaskManager.getImplementation().sync(new AutoClaimFinishTask(player, plot, area, schematic, try {
TaskManager.getPlatformImplementation().sync(new AutoClaimFinishTask(player, plot, area, schematic,
PlotSquared.get().getEventDispatcher())); PlotSquared.get().getEventDispatcher()));
} catch (final Exception e) {
e.printStackTrace();
}
} }
}); });
} }

View File

@ -27,7 +27,6 @@ package com.plotsquared.core.command;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.CaptionUtility; import com.plotsquared.core.configuration.CaptionUtility;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
@ -44,23 +43,18 @@ import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.Expression; import com.plotsquared.core.util.Expression;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@CommandDeclaration(command = "claim", import javax.annotation.Nonnull;
aliases = "c", import javax.annotation.Nullable;
description = "Claim the current plot you're standing on",
category = CommandCategory.CLAIMING, @CommandDeclaration(command = "claim", aliases = "c", description = "Claim the current plot you're standing on", category = CommandCategory.CLAIMING, requiredType = RequiredType.PLAYER, permission = "plots.claim", usage = "/plot claim")
requiredType = RequiredType.PLAYER,
permission = "plots.claim",
usage = "/plot claim")
public class Claim extends SubCommand { public class Claim extends SubCommand {
private static final Logger logger = LoggerFactory.getLogger("P2/" + Claim.class.getSimpleName()); private static final Logger logger =
LoggerFactory.getLogger("P2/" + Claim.class.getSimpleName());
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final EconHandler econHandler; private final EconHandler econHandler;
@ -146,24 +140,29 @@ public class Claim extends SubCommand {
} }
plot.setOwnerAbs(player.getUUID()); plot.setOwnerAbs(player.getUUID());
final String finalSchematic = schematic; final String finalSchematic = schematic;
DBFunc.createPlotSafe(plot, () -> TaskManager.getImplementation().sync(new RunnableVal<Object>() { DBFunc.createPlotSafe(plot, () -> {
@Override public void run(Object value) { try {
TaskManager.getPlatformImplementation().sync(() -> {
if (!plot.claim(player, true, finalSchematic, false)) { if (!plot.claim(player, true, finalSchematic, false)) {
logger.info(Captions.PREFIX.getTranslated() + String logger.info(Captions.PREFIX.getTranslated() + String
.format("Failed to claim plot %s", plot.getId().toCommaSeparatedString())); .format("Failed to claim plot %s", plot.getId().toCommaSeparatedString()));
sendMessage(player, Captions.PLOT_NOT_CLAIMED); sendMessage(player, Captions.PLOT_NOT_CLAIMED);
plot.setOwnerAbs(null); plot.setOwnerAbs(null);
} else if (area.isAutoMerge()) { } else if (area.isAutoMerge()) {
PlotMergeEvent event = Claim.this.eventDispatcher PlotMergeEvent mergeEvent = Claim.this.eventDispatcher
.callMerge(plot, Direction.ALL, Integer.MAX_VALUE, player); .callMerge(plot, Direction.ALL, Integer.MAX_VALUE, player);
if (event.getEventResult() == Result.DENY) { if (mergeEvent.getEventResult() == Result.DENY) {
sendMessage(player, Captions.EVENT_DENIED, "Auto merge on claim"); sendMessage(player, Captions.EVENT_DENIED, "Auto merge on claim");
} else { } else {
plot.autoMerge(event.getDir(), event.getMax(), player.getUUID(), true); plot.autoMerge(mergeEvent.getDir(), mergeEvent.getMax(), player.getUUID(), true);
} }
} }
return null;
});
} catch (final Exception e) {
e.printStackTrace();
} }
}), () -> { }, () -> {
logger.info(Captions.PREFIX.getTranslated() + String logger.info(Captions.PREFIX.getTranslated() + String
.format("Failed to add plot %s to the database", .format("Failed to add plot %s to the database",
plot.getId().toCommaSeparatedString())); plot.getId().toCommaSeparatedString()));

View File

@ -29,6 +29,7 @@ import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
public class CmdConfirm { public class CmdConfirm {
@ -46,11 +47,9 @@ public class CmdConfirm {
if (commandStr != null) { if (commandStr != null) {
MainUtil.sendMessage(player, Captions.REQUIRES_CONFIRM, commandStr); MainUtil.sendMessage(player, Captions.REQUIRES_CONFIRM, commandStr);
} }
TaskManager.runTaskLater(new Runnable() { TaskManager.runTaskLater(() -> {
@Override public void run() {
CmdInstance cmd = new CmdInstance(runnable); CmdInstance cmd = new CmdInstance(runnable);
player.setMeta("cmdConfirm", cmd); player.setMeta("cmdConfirm", cmd);
} }, TaskTime.ticks(1L));
}, 1);
} }
} }

View File

@ -35,6 +35,8 @@ import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.ArrayList; import java.util.ArrayList;
@ -177,7 +179,7 @@ public class Condense extends SubCommand {
if (result.get()) { if (result.get()) {
MainUtil.sendMessage(player, MainUtil.sendMessage(player,
"Moving: " + origin + " -> " + possible); "Moving: " + origin + " -> " + possible);
TaskManager.runTaskLater(task, 1); TaskManager.runTaskLater(task, TaskTime.ticks(1L));
} }
}, false).get()); }, false).get());
} catch (InterruptedException | ExecutionException e) { } catch (InterruptedException | ExecutionException e) {

View File

@ -182,7 +182,7 @@ public class DebugExec extends SubCommand {
if (this.worldEdit != null) { if (this.worldEdit != null) {
this.scope.put("WEManager", new WEManager()); this.scope.put("WEManager", new WEManager());
} }
this.scope.put("TaskManager", TaskManager.getImplementation()); this.scope.put("TaskManager", TaskManager.getPlatformImplementation());
this.scope.put("ConsolePlayer", ConsolePlayer.getConsole()); this.scope.put("ConsolePlayer", ConsolePlayer.getConsole());
this.scope.put("SchematicHandler", this.schematicHandler); this.scope.put("SchematicHandler", this.schematicHandler);
this.scope.put("ChunkManager", this.chunkManager); this.scope.put("ChunkManager", this.chunkManager);

View File

@ -40,7 +40,7 @@ import com.plotsquared.core.util.task.TaskManager;
public class PluginCmd extends SubCommand { public class PluginCmd extends SubCommand {
@Override public boolean onCommand(final PlotPlayer<?> player, String[] args) { @Override public boolean onCommand(final PlotPlayer<?> player, String[] args) {
TaskManager.getImplementation().taskAsync(() -> { TaskManager.getPlatformImplementation().taskAsync(() -> {
MainUtil.sendMessage(player, String.format( MainUtil.sendMessage(player, String.format(
"$2>> $1&l" + PlotSquared.platform().getPluginName() + " $2($1Version$2: $1%s$2)", "$2>> $1&l" + PlotSquared.platform().getPluginName() + " $2($1Version$2: $1%s$2)",
PlotSquared.get().getVersion())); PlotSquared.get().getVersion()));

View File

@ -43,6 +43,7 @@ import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.RunnableVal2; import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -102,7 +103,7 @@ public class Trim extends SubCommand {
MainUtil.sendMessage(null, " - MCA #: " + result.value1.size()); MainUtil.sendMessage(null, " - MCA #: " + result.value1.size());
MainUtil.sendMessage(null, " - CHUNKS: " + (result.value1.size() * 1024) + " (max)"); MainUtil.sendMessage(null, " - CHUNKS: " + (result.value1.size() * 1024) + " (max)");
MainUtil.sendMessage(null, " - TIME ESTIMATE: 12 Parsecs"); MainUtil.sendMessage(null, " - TIME ESTIMATE: 12 Parsecs");
TaskManager.objectTask(plots, new RunnableVal<Plot>() { TaskManager.getPlatformImplementation().objectTask(plots, new RunnableVal<Plot>() {
@Override public void run(Plot plot) { @Override public void run(Plot plot) {
Location pos1 = plot.getCorners()[0]; Location pos1 = plot.getCorners()[0];
Location pos2 = plot.getCorners()[1]; Location pos2 = plot.getCorners()[1];
@ -119,7 +120,8 @@ public class Trim extends SubCommand {
} }
} }
} }
}, result); }).thenAccept(ignore ->
TaskManager.getPlatformImplementation().taskLater(result, TaskTime.ticks(1L)));
return true; return true;
} }
@ -189,11 +191,12 @@ public class Trim extends SubCommand {
} }
} }
final QueueCoordinator queue = blockQueue.getNewQueue(world, false); final QueueCoordinator queue = blockQueue.getNewQueue(world, false);
TaskManager.objectTask(chunks, new RunnableVal<BlockVector2>() { TaskManager.getPlatformImplementation().objectTask(chunks, new RunnableVal<BlockVector2>() {
@Override public void run(BlockVector2 value) { @Override public void run(BlockVector2 value) {
queue.regenChunk(value.getX(), value.getZ()); queue.regenChunk(value.getX(), value.getZ());
} }
}, this); }).thenAccept(ignore -> TaskManager.getPlatformImplementation()
.taskLater(this, TaskTime.ticks(1L)));
} }
}; };
} else { } else {

View File

@ -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 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 login") public static boolean ON_LOGIN = false;
@Comment("Teleport to your plot on claim") public static boolean ON_CLAIM = true; @Comment("Teleport to your plot on claim") public static boolean ON_CLAIM = true;
@Comment({"Add a delay to all teleport commands", @Comment({"Add a delay to all teleport commands (in seconds)",
"Assign `plots.teleport.delay.bypass` to bypass the cooldown."}) public static int "Assign `plots.teleport.delay.bypass` to bypass the cooldown"})
DELAY = 0; public static int DELAY = 0;
@Comment("The visit command is ordered by world instead of globally") public static boolean @Comment("The visit command is ordered by world instead of globally") public static boolean
PER_WORLD_VISIT = false; PER_WORLD_VISIT = false;
} }

View File

@ -26,7 +26,6 @@
package com.plotsquared.core.generator; package com.plotsquared.core.generator;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.events.PlotFlagAddEvent; import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
@ -54,6 +53,7 @@ import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
@ -366,7 +366,7 @@ public class HybridUtils {
analyzeRegion(origin.getWorldName(), region, new RunnableVal<PlotAnalysis>() { analyzeRegion(origin.getWorldName(), region, new RunnableVal<PlotAnalysis>() {
@Override public void run(PlotAnalysis value) { @Override public void run(PlotAnalysis value) {
analysis.add(value); analysis.add(value);
TaskManager.runTaskLater(task, 1); TaskManager.runTaskLater(task, TaskTime.ticks(1L));
} }
}); });
} }
@ -478,8 +478,7 @@ public class HybridUtils {
} }
} }
if (!chunks.isEmpty()) { if (!chunks.isEmpty()) {
TaskManager.getImplementation().sync(new RunnableVal<Object>() { TaskManager.getPlatformImplementation().sync(() -> {
@Override public void run(Object value) {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
Iterator<BlockVector2> iterator = chunks.iterator(); Iterator<BlockVector2> iterator = chunks.iterator();
while (System.currentTimeMillis() - start < 20 && !chunks while (System.currentTimeMillis() - start < 20 && !chunks
@ -492,7 +491,7 @@ public class HybridUtils {
logger.info("[P2] Failed to regenerate road"); logger.info("[P2] Failed to regenerate road");
} }
} }
} return null;
}); });
} }
} catch (Exception e) { } catch (Exception e) {
@ -511,7 +510,7 @@ public class HybridUtils {
} }
} }
} }
blockQueue.addEmptyTask(() -> TaskManager.runTaskLater(task, 20)); blockQueue.addEmptyTask(() -> TaskManager.runTaskLater(task, TaskTime.seconds(1L)));
}); });
} }
} }

View File

@ -61,6 +61,7 @@ import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; 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.GameMode;
import com.sk89q.worldedit.world.gamemode.GameModes; import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemType; 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) { public boolean plotEntry(final PlotPlayer<?> player, final Plot plot) {
@ -279,7 +280,7 @@ public class PlotListener {
replacements); replacements);
player.sendTitle(main, sub); player.sendTitle(main, sub);
} }
}, 20); }, TaskTime.seconds(1L));
} }
} }

View File

@ -66,6 +66,7 @@ import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.plotsquared.core.uuid.UUIDPipeline; import com.plotsquared.core.uuid.UUIDPipeline;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
@ -1950,7 +1951,7 @@ public class Plot {
this.getId().recalculateHash(); this.getId().recalculateHash();
this.area.addPlotAbs(this); this.area.addPlotAbs(this);
DBFunc.movePlot(this, plot); DBFunc.movePlot(this, plot);
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
return true; return true;
} }
@ -2913,7 +2914,7 @@ public class Plot {
this.plotListener.plotExit(pp, Plot.this); this.plotListener.plotExit(pp, Plot.this);
this.plotListener.plotEntry(pp, Plot.this); this.plotListener.plotEntry(pp, Plot.this);
} }
}, 1); }, TaskTime.ticks(1L));
} }
public void debug(@Nonnull final String message) { public void debug(@Nonnull final String message) {
@ -3001,16 +3002,16 @@ public class Plot {
MainUtil MainUtil
.sendMessage(player, Captions.TELEPORT_IN_SECONDS, Settings.Teleport.DELAY + ""); .sendMessage(player, Captions.TELEPORT_IN_SECONDS, Settings.Teleport.DELAY + "");
final String name = player.getName(); final String name = player.getName();
TaskManager.TELEPORT_QUEUE.add(name); TaskManager.addToTeleportQueue(name);
TaskManager.runTaskLater(() -> { TaskManager.runTaskLater(() -> {
if (!TaskManager.TELEPORT_QUEUE.remove(name)) { if (!TaskManager.removeFromTeleportQueue(name)) {
return; return;
} }
if (player.isOnline()) { if (player.isOnline()) {
MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT); MainUtil.sendMessage(player, Captions.TELEPORTED_TO_PLOT);
player.teleport(location, cause); player.teleport(location, cause);
} }
}, Settings.Teleport.DELAY * 20); }, TaskTime.seconds(Settings.Teleport.DELAY));
resultConsumer.accept(true); resultConsumer.accept(true);
}; };
if (this.area.isHomeAllowNonmember() || plot.isAdded(player.getUUID())) { if (this.area.isHomeAllowNonmember() || plot.isAdded(player.getUUID())) {
@ -3160,7 +3161,7 @@ public class Plot {
final int offsetX = db.getX() - ob.getX(); final int offsetX = db.getX() - ob.getX();
final int offsetZ = db.getZ() - ob.getZ(); final int offsetZ = db.getZ() - ob.getZ();
if (!this.hasOwner()) { if (!this.hasOwner()) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
} }
AtomicBoolean occupied = new AtomicBoolean(false); AtomicBoolean occupied = new AtomicBoolean(false);
@ -3169,7 +3170,7 @@ public class Plot {
Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y);
if (other.hasOwner()) { if (other.hasOwner()) {
if (!allowSwap) { if (!allowSwap) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
} }
occupied.set(true); occupied.set(true);
@ -3279,14 +3280,14 @@ public class Plot {
final int offsetX = db.getX() - ob.getX(); final int offsetX = db.getX() - ob.getX();
final int offsetZ = db.getZ() - ob.getZ(); final int offsetZ = db.getZ() - ob.getZ();
if (!this.hasOwner()) { if (!this.hasOwner()) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
return false; return false;
} }
Set<Plot> plots = this.getConnectedPlots(); Set<Plot> plots = this.getConnectedPlots();
for (Plot plot : plots) { for (Plot plot : plots) {
Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y); Plot other = plot.getRelative(destination.getArea(), offset.x, offset.y);
if (other.hasOwner()) { if (other.hasOwner()) {
TaskManager.runTaskLater(whenDone, 1); TaskManager.runTaskLater(whenDone, TaskTime.ticks(1L));
return false; return false;
} }
} }

View File

@ -32,6 +32,7 @@ import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; 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) { public static long getTimestamp(PlotPlayer<?> player, String inbox) {

View File

@ -43,15 +43,15 @@ import com.plotsquared.core.plot.flag.implementations.KeepFlag;
import com.plotsquared.core.plot.message.PlotMessage; import com.plotsquared.core.plot.message.PlotMessage;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.query.PlotQuery; import com.plotsquared.core.util.query.PlotQuery;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.RunnableVal3; import com.plotsquared.core.util.task.RunnableVal3;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nonnull;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -326,7 +326,8 @@ public class ExpireManager {
} }
for (ExpiryTask expiryTask : expired) { for (ExpiryTask expiryTask : expired) {
if (!expiryTask.needsAnalysis()) { if (!expiryTask.needsAnalysis()) {
expiredTask.run(newPlot, () -> TaskManager.getImplementation().taskLaterAsync(task, 1), expiredTask.run(newPlot, () -> TaskManager.getPlatformImplementation()
.taskLaterAsync(task, TaskTime.ticks(1L)),
expiryTask.requiresConfirmation()); expiryTask.requiresConfirmation());
return; return;
} }
@ -337,7 +338,7 @@ public class ExpireManager {
passesComplexity(changed, expired, new RunnableVal<Boolean>() { passesComplexity(changed, expired, new RunnableVal<Boolean>() {
@Override public void run(Boolean confirmation) { @Override public void run(Boolean confirmation) {
expiredTask.run(newPlot, expiredTask.run(newPlot,
() -> TaskManager.getImplementation().taskLaterAsync(task, 1), () -> TaskManager.getPlatformImplementation().taskLaterAsync(task, TaskTime.ticks(1L)),
confirmation); confirmation);
} }
}, () -> { }, () -> {
@ -350,7 +351,7 @@ public class ExpireManager {
return; return;
} }
newPlot.setFlag(event.getFlag()); 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) { @Override public void run(Boolean value) {
doAnalysis.run(); doAnalysis.run();
} }
}, () -> TaskManager.getImplementation().taskLaterAsync(task, 1)); }, () -> TaskManager.getPlatformImplementation().taskLaterAsync(task, TaskTime.ticks(1L)));
} else { } else {
doAnalysis.run(); doAnalysis.run();
} }
@ -376,9 +377,9 @@ public class ExpireManager {
ExpireManager.this.running = 2; ExpireManager.this.running = 2;
runTask(expiredTask); runTask(expiredTask);
} }
}, 86400000); }, TaskTime.ticks(86400000L));
} else { } else {
TaskManager.runTaskLaterAsync(task, 20 * 10); TaskManager.runTaskLaterAsync(task, TaskTime.seconds(10L));
} }
} }
}); });

View File

@ -47,11 +47,10 @@ import com.plotsquared.core.setup.PlotAreaBuilder;
import com.plotsquared.core.setup.SettingsNodesWrapper; import com.plotsquared.core.setup.SettingsNodesWrapper;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
@ -141,15 +140,18 @@ public class SinglePlotArea extends GridPlotWorld {
} }
} }
TaskManager.getImplementation().sync(new RunnableVal<Object>() { try {
@Override public void run(Object value) { TaskManager.getPlatformImplementation().sync(() -> {
String worldName = id.getX() + "." + id.getY(); final String name = id.getX() + "." + id.getY();
if (PlotSquared.platform().getWorldUtil().isWorld(worldName)) { if (!PlotSquared.platform().getWorldUtil().isWorld(name)) {
return;
}
PlotSquared.platform().getSetupUtils().setupWorld(builder); PlotSquared.platform().getSetupUtils().setupWorld(builder);
} }
return null;
}); });
} catch (final Exception e) {
e.printStackTrace();
}
// String worldName = plot.getWorldName(); // String worldName = plot.getWorldName();
// World world = Bukkit.getWorld(worldName); // World world = Bukkit.getWorld(worldName);
// if (world != null) { // if (world != null) {

View File

@ -64,7 +64,7 @@ public class SinglePlotManager extends PlotManager {
@Override public boolean clearPlot(Plot plot, final Runnable whenDone) { @Override public boolean clearPlot(Plot plot, final Runnable whenDone) {
PlotSquared.platform().getSetupUtils().unload(plot.getWorldName(), false); PlotSquared.platform().getSetupUtils().unload(plot.getWorldName(), false);
final File worldFolder = new File(PlotSquared.platform().getWorldContainer(), plot.getWorldName()); final File worldFolder = new File(PlotSquared.platform().getWorldContainer(), plot.getWorldName());
TaskManager.getImplementation().taskAsync(() -> { TaskManager.getPlatformImplementation().taskAsync(() -> {
MainUtil.deleteDirectory(worldFolder); MainUtil.deleteDirectory(worldFolder);
if (whenDone != null) { if (whenDone != null) {
whenDone.run(); whenDone.run();

View File

@ -26,8 +26,13 @@
package com.plotsquared.core.queue; package com.plotsquared.core.queue;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
<<<<<<< HEAD
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
=======
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.ArrayList;
import java.util.List; import java.util.List;

View File

@ -32,6 +32,7 @@ import com.plotsquared.core.queue.QueueCoordinator;
import com.plotsquared.core.queue.ScopedQueueCoordinator; import com.plotsquared.core.queue.ScopedQueueCoordinator;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
@ -174,7 +175,7 @@ public abstract class ChunkManager {
task.run(); task.run();
} }
if (!chunks.isEmpty()) { if (!chunks.isEmpty()) {
TaskManager.runTaskLater(this, 1); TaskManager.runTaskLater(this, TaskTime.ticks(1L));
} else { } else {
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
} }

View File

@ -33,6 +33,7 @@ import com.plotsquared.core.plot.PlotManager;
import com.plotsquared.core.queue.QueueCoordinator; import com.plotsquared.core.queue.QueueCoordinator;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
@ -94,11 +95,12 @@ public abstract class RegionManager {
} }
} }
} }
TaskManager.objectTask(chunks, new RunnableVal<BlockVector2>() { TaskManager.getPlatformImplementation().objectTask(chunks, new RunnableVal<BlockVector2>() {
@Override public void run(BlockVector2 value) { @Override public void run(BlockVector2 value) {
chunkManager.loadChunk(world, value, false).thenRun(() -> task.run(value)); chunkManager.loadChunk(world, value, false).thenRun(() -> task.run(value));
} }
}, whenDone); }).thenAccept(ignore ->
TaskManager.getPlatformImplementation().taskLater(whenDone, TaskTime.ticks(1L)));
}); });
} }

View File

@ -35,6 +35,7 @@ import com.plotsquared.core.plot.schematic.Schematic;
import com.plotsquared.core.queue.QueueCoordinator; import com.plotsquared.core.queue.QueueCoordinator;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import com.plotsquared.core.util.task.TaskTime;
import com.sk89q.jnbt.ByteArrayTag; import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.IntArrayTag; import com.sk89q.jnbt.IntArrayTag;
@ -662,7 +663,7 @@ public abstract class SchematicHandler {
zTask.run(); zTask.run();
} }
if (yiter.hasNext()) { if (yiter.hasNext()) {
TaskManager.runTaskLater(this, 1); TaskManager.runTaskLater(this, TaskTime.ticks(1L));
} else { } else {
regionTask.run(); regionTask.run();
} }

View File

@ -36,10 +36,12 @@ import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import java.util.concurrent.Callable;
import static com.plotsquared.core.util.MainUtil.sendMessage; import static com.plotsquared.core.util.MainUtil.sendMessage;
@RequiredArgsConstructor @RequiredArgsConstructor
public final class AutoClaimFinishTask extends RunnableVal<Object> { public final class AutoClaimFinishTask implements Callable<Boolean> {
private final PlotPlayer player; private final PlotPlayer player;
private final Plot plot; private final Plot plot;
@ -47,11 +49,11 @@ public final class AutoClaimFinishTask extends RunnableVal<Object> {
private final String schematic; private final String schematic;
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
@Override public void run(Object value) { @Override public Boolean call() {
player.deleteMeta(Auto.class.getName()); player.deleteMeta(Auto.class.getName());
if (plot == null) { if (plot == null) {
sendMessage(player, Captions.NO_FREE_PLOTS); sendMessage(player, Captions.NO_FREE_PLOTS);
return; return false;
} }
plot.claim(player, true, schematic, false); plot.claim(player, true, schematic, false);
if (area.isAutoMerge()) { if (area.isAutoMerge()) {
@ -62,5 +64,7 @@ public final class AutoClaimFinishTask extends RunnableVal<Object> {
plot.autoMerge(event.getDir(), event.getMax(), player.getUUID(), true); plot.autoMerge(event.getDir(), event.getMax(), player.getUUID(), true);
} }
} }
return true;
} }
} }

View File

@ -25,16 +25,19 @@
*/ */
package com.plotsquared.core.util.task; package com.plotsquared.core.util.task;
import lombok.Getter;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.CompletableFuture;
@RequiredArgsConstructor @RequiredArgsConstructor
public class ObjectTaskRunnable<T> implements Runnable { public class ObjectTaskRunnable<T> implements Runnable {
@Getter private final CompletableFuture<Void> completionFuture = new CompletableFuture<>();
private final Iterator<T> iterator; private final Iterator<T> iterator;
private final RunnableVal<T> task; private final RunnableVal<T> task;
private final Runnable whenDone;
@Override public void run() { @Override public void run() {
long start = System.currentTimeMillis(); long start = System.currentTimeMillis();
@ -44,9 +47,9 @@ public class ObjectTaskRunnable<T> implements Runnable {
task.run(); task.run();
} }
if (!hasNext) { if (!hasNext) {
TaskManager.runTaskLater(whenDone, 1); completionFuture.complete(null);
} else { } else {
TaskManager.runTaskLater(this, 1); TaskManager.runTaskLater(this, TaskTime.ticks(1L));
} }
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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() {
}
}
}

View File

@ -25,144 +25,269 @@
*/ */
package com.plotsquared.core.util.task; package com.plotsquared.core.util.task;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.util.RuntimeExceptionRunnableVal;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
/**
* Task manager that handles scheduling of tasks.
* Synchronous methods make no guarantee of being scheduled on the
* server thread, instead they guarantee that no two synchronous
* operations happen at the same time. Implementations of
* the task manager might make other guarantees. All asynchronous
* operations will happen on another thread, no matter where
* they're scheduled from.
*/
public abstract class TaskManager { public abstract class TaskManager {
public static final HashSet<String> TELEPORT_QUEUE = new HashSet<>(); private static final Set<String> teleportQueue = new HashSet<>();
public static final HashMap<Integer, Integer> tasks = new HashMap<>(); private static final Map<Integer, PlotSquaredTask> tasks = new HashMap<>();
public static AtomicInteger index = new AtomicInteger(0); public static AtomicInteger index = new AtomicInteger(0);
@Getter @Setter private static TaskManager implementation; @Getter @Setter private static TaskManager platformImplementation;
public static int runTaskRepeat(Runnable runnable, int interval) { /**
* Add a string to the teleport queue
*
* @param string String to add
*/
public static void addToTeleportQueue(@Nonnull final String string) {
teleportQueue.add(string);
}
/**
* Remove a string from the teleport queue
*
* @param string String to remove
* return {@code true} if the value was stored in the map, or {@code false}
*/
public static boolean removeFromTeleportQueue(@Nonnull final String string) {
return teleportQueue.remove(string);
}
/**
* Add a task to the task map
*
* @param task Task
* @param id Task ID
*/
public static void addTask(@Nonnull final PlotSquaredTask task, final int id) {
tasks.put(id, task);
}
/**
* Remove a task from the task map and return the stored value
*
* @param id Task ID
* @return Task if stored, or {@code null}
*/
@Nullable public static PlotSquaredTask removeTask(final int id) {
return tasks.remove(id);
}
/**
* 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 (runnable != null) {
if (getImplementation() == null) { if (getPlatformImplementation() == null) {
throw new IllegalArgumentException("disabled"); throw new IllegalArgumentException("disabled");
} }
return getImplementation().taskRepeat(runnable, interval); return getPlatformImplementation().taskRepeat(runnable, taskTime);
} }
return -1; return PlotSquaredTask.nullTask();
} }
public static int runTaskRepeatAsync(Runnable runnable, int interval) { /**
* 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 (runnable != null) {
if (getImplementation() == null) { if (getPlatformImplementation() == null) {
throw new IllegalArgumentException("disabled");
}
return getImplementation().taskRepeatAsync(runnable, interval);
}
return -1;
}
public static void runTaskAsync(Runnable runnable) {
if (runnable != null) {
if (getImplementation() == null) {
runnable.run(); runnable.run();
return; return;
} }
getImplementation().taskAsync(runnable); getPlatformImplementation().taskAsync(runnable);
}
}
public static void runTask(Runnable runnable) {
if (runnable != null) {
if (getImplementation() == null) {
runnable.run();
return;
}
getImplementation().task(runnable);
} }
} }
/** /**
* Run task later. * Run a synchronous task. If using a platform scheduler, this is guaranteed
* to run on the server thread
* *
* @param runnable The task * @param runnable Task to run
* @param delay The delay in ticks
*/ */
public static void runTaskLater(Runnable runnable, int delay) { public static void runTask(@Nullable final Runnable runnable) {
if (runnable != null) { if (runnable != null) {
if (getImplementation() == null) { if (getPlatformImplementation() == null) {
runnable.run(); runnable.run();
return; return;
} }
getImplementation().taskLater(runnable, delay); getPlatformImplementation().task(runnable);
}
}
public static void runTaskLaterAsync(Runnable runnable, int delay) {
if (runnable != null) {
if (getImplementation() == null) {
runnable.run();
return;
}
getImplementation().taskLaterAsync(runnable, delay);
} }
} }
/** /**
* Break up a series of tasks so that they can run without lagging the server. * Run a synchronous task after a given delay.
* If using a platform scheduler, this is guaranteed to run on the server thread
* *
* @param objects * @param runnable Task to run
* @param task * @param taskTime Task delay
* @param whenDone
*/ */
public static <T> void objectTask(Collection<T> objects, final RunnableVal<T> task, public static void runTaskLater(@Nullable final Runnable runnable,
final Runnable whenDone) { @Nonnull final TaskTime taskTime) {
if (runnable != null) {
if (getPlatformImplementation() == null) {
runnable.run();
return;
}
getPlatformImplementation().taskLater(runnable, taskTime);
}
}
/**
* 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 (getPlatformImplementation() == null) {
runnable.run();
return;
}
getPlatformImplementation().taskLaterAsync(runnable, taskTime);
}
}
/**
* Break up a series of tasks so that they can run without lagging the server
*
* @param objects Objects to perform the task on
* @param task Task to perform
* @param <T> Object type
* @return Future that completes when the tasks are done
*/
public <T> CompletableFuture<Void> objectTask(@Nonnull final Collection<T> objects,
@Nonnull final RunnableVal<T> task) {
final Iterator<T> iterator = objects.iterator(); final Iterator<T> iterator = objects.iterator();
TaskManager.runTask(new ObjectTaskRunnable<>(iterator, task, whenDone)); final ObjectTaskRunnable<T> taskRunnable = new ObjectTaskRunnable<>(iterator, task);
TaskManager.runTask(taskRunnable);
return taskRunnable.getCompletionFuture();
} }
public <T> T sync(final RunnableVal<T> function) { /**
* Make a synchronous method call and return the result
*
* @param function Method to call
* @param <T> Return type
* @return Method result
* @throws Exception If the call fails
*/
public <T> T sync(@Nonnull final Callable<T> function) throws Exception {
return sync(function, Integer.MAX_VALUE); return sync(function, Integer.MAX_VALUE);
} }
public <T> T sync(final RunnableVal<T> function, int timeout) { /**
if (PlotSquared.get().isMainThread(Thread.currentThread())) { * Make a synchronous method call and return the result
function.run(); *
return function.value; * @param function Method to call
} * @param timeout Timeout (ms)
final AtomicBoolean running = new AtomicBoolean(true); * @param <T> Return type
final RuntimeExceptionRunnableVal<T> run = * @return Method result
new RuntimeExceptionRunnableVal<>(function, running); * @throws Exception If the call fails
TaskManager.getImplementation().task(run); */
try { public abstract <T> T sync(@Nonnull final Callable<T> function, final int timeout)
synchronized (function) { throws Exception;
while (running.get()) {
function.wait(timeout);
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (run.value != null) {
throw run.value;
}
return function.value;
}
public abstract int taskRepeat(Runnable runnable, int interval); /**
* Call a method synchronously and return a future with
* the result of the result
*
* @param method Method to be ran synchronously
* @param <T> Return type
* @return Future completing with the result
*/
public abstract <T> Future<T> callMethodSync(@Nonnegative final Callable<T> method);
public abstract int taskRepeatAsync(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 void taskAsync(Runnable runnable); /**
* 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 task(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 taskLater(Runnable runnable, int delay); /**
* 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 taskLaterAsync(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);
/**
* 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);
} }

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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());
}
}
}
}