Improves chunk unloading
Adds all chunk unloading to a queue Adds a thread which unloads chunks Updates chunk unload requests such that a chunk won't be unloaded twice, and an old unloading request cannot unload a chunk too soon
This commit is contained in:
parent
69a62c921c
commit
38ea543b80
@ -3,6 +3,7 @@ package net.knarcraft.stargate;
|
||||
import net.knarcraft.stargate.command.CommandStarGate;
|
||||
import net.knarcraft.stargate.command.StarGateTabCompleter;
|
||||
import net.knarcraft.stargate.container.BlockChangeRequest;
|
||||
import net.knarcraft.stargate.container.ChunkUnloadRequest;
|
||||
import net.knarcraft.stargate.listener.BlockEventListener;
|
||||
import net.knarcraft.stargate.listener.BungeeCordListener;
|
||||
import net.knarcraft.stargate.listener.EntityEventListener;
|
||||
@ -15,6 +16,7 @@ import net.knarcraft.stargate.portal.GateHandler;
|
||||
import net.knarcraft.stargate.portal.Portal;
|
||||
import net.knarcraft.stargate.portal.PortalHandler;
|
||||
import net.knarcraft.stargate.thread.BlockChangeThread;
|
||||
import net.knarcraft.stargate.thread.ChunkUnloadThread;
|
||||
import net.knarcraft.stargate.thread.StarGateThread;
|
||||
import net.knarcraft.stargate.utility.EconomyHandler;
|
||||
import net.knarcraft.stargate.utility.FileHelper;
|
||||
@ -31,6 +33,7 @@ import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||
import org.bukkit.plugin.messaging.Messenger;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -38,6 +41,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.logging.Level;
|
||||
@ -50,6 +54,7 @@ public class Stargate extends JavaPlugin {
|
||||
public static final Queue<BlockChangeRequest> blockChangeRequestQueue = new LinkedList<>();
|
||||
public static final ConcurrentLinkedQueue<Portal> openPortalsQueue = new ConcurrentLinkedQueue<>();
|
||||
public static final ConcurrentLinkedQueue<Portal> activePortalsQueue = new ConcurrentLinkedQueue<>();
|
||||
public static final Queue<ChunkUnloadRequest> chunkUnloadQueue = new PriorityQueue<>();
|
||||
|
||||
//Amount of seconds before deactivating/closing portals
|
||||
private static final int activeTime = 10;
|
||||
@ -334,8 +339,10 @@ public class Stargate extends JavaPlugin {
|
||||
setupVaultEconomy();
|
||||
|
||||
//Run necessary threads
|
||||
getServer().getScheduler().runTaskTimer(this, new StarGateThread(), 0L, 100L);
|
||||
getServer().getScheduler().runTaskTimer(this, new BlockChangeThread(), 0L, 1L);
|
||||
BukkitScheduler scheduler = getServer().getScheduler();
|
||||
scheduler.runTaskTimer(this, new StarGateThread(), 0L, 100L);
|
||||
scheduler.runTaskTimer(this, new BlockChangeThread(), 0L, 1L);
|
||||
scheduler.runTaskTimer(this, new ChunkUnloadThread(), 0L, 100L);
|
||||
|
||||
this.registerCommands();
|
||||
}
|
||||
@ -615,4 +622,23 @@ public class Stargate extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chunk unload queue containing chunks to unload
|
||||
*
|
||||
* @return <p>The chunk unload queue</p>
|
||||
*/
|
||||
public static Queue<ChunkUnloadRequest> getChunkUnloadQueue() {
|
||||
return chunkUnloadQueue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new chunk unload request to the chunk unload queue
|
||||
*
|
||||
* @param request <p>The new chunk unload request to add</p>
|
||||
*/
|
||||
public static void addChunkUnloadRequest(ChunkUnloadRequest request) {
|
||||
chunkUnloadQueue.removeIf((item) -> item.getChunkToUnload().equals(request.getChunkToUnload()));
|
||||
chunkUnloadQueue.add(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,54 @@
|
||||
package net.knarcraft.stargate.container;
|
||||
|
||||
import org.bukkit.Chunk;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Requests the unloading of a chunk which has been previously loaded by the Stargate plugin
|
||||
*/
|
||||
public class ChunkUnloadRequest implements Comparable<ChunkUnloadRequest> {
|
||||
|
||||
private final Long unloadNanoTime;
|
||||
private final Chunk chunkToUnload;
|
||||
|
||||
/**
|
||||
* Instantiates a new chunk unloading request
|
||||
*
|
||||
* @param chunkToUnload <p>The chunk to request the unloading of</p>
|
||||
* @param timeUntilUnload <p>The time in milliseconds to wait before unloading the chunk</p>
|
||||
*/
|
||||
public ChunkUnloadRequest(Chunk chunkToUnload, Long timeUntilUnload) {
|
||||
this.chunkToUnload = chunkToUnload;
|
||||
long systemNanoTime = System.nanoTime();
|
||||
this.unloadNanoTime = systemNanoTime + (timeUntilUnload * 1000000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the chunk to unload
|
||||
*
|
||||
* @return <p>The chunk to unload</p>
|
||||
*/
|
||||
public Chunk getChunkToUnload() {
|
||||
return this.chunkToUnload;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time system nano time denoting at which time the unload request should be executed
|
||||
*
|
||||
* @return <p>The system nano time denoting when the chunk is to be unloaded</p>
|
||||
*/
|
||||
public Long getUnloadNanoTime() {
|
||||
return this.unloadNanoTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{" + chunkToUnload + ", " + unloadNanoTime + "}";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull ChunkUnloadRequest otherRequest) {
|
||||
return unloadNanoTime.compareTo(otherRequest.unloadNanoTime);
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ package net.knarcraft.stargate.portal;
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.BlockChangeRequest;
|
||||
import net.knarcraft.stargate.container.BlockLocation;
|
||||
import net.knarcraft.stargate.container.ChunkUnloadRequest;
|
||||
import net.knarcraft.stargate.container.RelativeBlockVector;
|
||||
import net.knarcraft.stargate.event.StargateActivateEvent;
|
||||
import net.knarcraft.stargate.event.StargateCloseEvent;
|
||||
@ -501,8 +502,6 @@ public class Portal {
|
||||
|
||||
//Load chunks to make sure not to teleport to the void
|
||||
loadChunks();
|
||||
Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate,
|
||||
this::unloadChunks, 4000);
|
||||
|
||||
//If no event is passed in, assume it's a teleport, and act as such
|
||||
if (event == null) {
|
||||
@ -551,8 +550,6 @@ public class Portal {
|
||||
|
||||
//Load chunks to make sure not to teleport to the void
|
||||
loadChunks();
|
||||
Stargate.server.getScheduler().scheduleSyncDelayedTask(Stargate.stargate,
|
||||
this::unloadChunks, 4000);
|
||||
|
||||
if (!passengers.isEmpty()) {
|
||||
if (vehicle instanceof RideableMinecart || vehicle instanceof Boat) {
|
||||
@ -628,7 +625,7 @@ public class Portal {
|
||||
* but there needs to be a delay between teleporting the vehicle and teleporting and adding the passenger.</p>
|
||||
*
|
||||
* @param targetVehicle <p>The vehicle to add the passenger to</p>
|
||||
* @param passenger <p>The passenger to teleport and add</p>
|
||||
* @param passenger <p>The passenger to teleport and add</p>
|
||||
*/
|
||||
private void teleportAndAddPassenger(Vehicle targetVehicle, Entity passenger) {
|
||||
if (!passenger.teleport(targetVehicle.getLocation())) {
|
||||
@ -770,21 +767,15 @@ public class Portal {
|
||||
return traveller;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unloads the chunks outside the portal's entrance
|
||||
*/
|
||||
private void unloadChunks() {
|
||||
for (Chunk chunk : getChunksToLoad()) {
|
||||
chunk.removePluginChunkTicket(Stargate.stargate);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the chunks outside the portal's entrance
|
||||
*/
|
||||
private void loadChunks() {
|
||||
for (Chunk chunk : getChunksToLoad()) {
|
||||
chunk.addPluginChunkTicket(Stargate.stargate);
|
||||
//Allow the chunk to unload after 3 seconds
|
||||
Stargate.addChunkUnloadRequest(new ChunkUnloadRequest(chunk, 3000L));
|
||||
Stargate.debug("loadChunks", "Added chunk unloading request for chunk " + chunk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
package net.knarcraft.stargate.thread;
|
||||
|
||||
import net.knarcraft.stargate.Stargate;
|
||||
import net.knarcraft.stargate.container.ChunkUnloadRequest;
|
||||
import org.bukkit.Chunk;
|
||||
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* Unloads chunks which should no longer be forced to stay loaded
|
||||
*/
|
||||
public class ChunkUnloadThread implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
long systemNanoTime = System.nanoTime();
|
||||
Queue<ChunkUnloadRequest> unloadQueue = Stargate.getChunkUnloadQueue();
|
||||
|
||||
//Peek at the first element to check if the chunk should be unloaded
|
||||
ChunkUnloadRequest firstElement = unloadQueue.peek();
|
||||
if (firstElement != null) {
|
||||
Stargate.debug("ChunkUnloadThread", "Found chunk unload request: " + firstElement);
|
||||
Stargate.debug("ChunkUnloadThread", "Current time: " + systemNanoTime);
|
||||
}
|
||||
//Repeat until all un-loadable chunks have been processed
|
||||
while (firstElement != null && firstElement.getUnloadNanoTime() < systemNanoTime) {
|
||||
unloadQueue.remove();
|
||||
Chunk chunkToUnload = firstElement.getChunkToUnload();
|
||||
//Allow the chunk to be unloaded
|
||||
chunkToUnload.removePluginChunkTicket(Stargate.stargate);
|
||||
Stargate.debug("ChunkUnloadThread", "Unloaded chunk " + chunkToUnload);
|
||||
firstElement = unloadQueue.peek();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user