Created
October 10, 2019 00:16
-
-
Save Cryptite/fd48b752ec83eaa6bf505c8b497b8b53 to your computer and use it in GitHub Desktop.
ChunkTaskHandler - A system for registering sync repeatable Bukkit Tasks on Chunks
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ChunkTaskHandler implements Listener { | |
private static ChunkTaskHandler instance = new ChunkTaskHandler(); | |
private final TheArtifact plugin; | |
private Map<Integer, Map<Object, WorldRunnable>> registeredChunks = new HashMap<>(); | |
public boolean debug = true; | |
private class WorldRunnable { | |
private final Object key; | |
private final Runnable runnable; | |
private final int delay; | |
private final int frequency; | |
private final StringLocation location; | |
private int taskId; | |
WorldRunnable(Object key, StringLocation l, Runnable runnable, int delay, int frequency) { | |
this.key = key; | |
this.location = l; | |
this.runnable = runnable; | |
this.delay = delay; | |
this.frequency = frequency; | |
start(); | |
} | |
void start() { | |
if (taskId != 0) { | |
cancel(); | |
} | |
if (location.isChunkLoaded()) { | |
taskId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, runnable, delay, frequency); | |
if (debug) { | |
TheArtifact.log.info("Chunk Runnable STARTED: " + key + " (" + RPGUtil.getLocationFancyName(location) + ")"); | |
} | |
} | |
} | |
void cancel() { | |
Bukkit.getScheduler().cancelTask(taskId); | |
taskId = 0; | |
if (debug) { | |
TheArtifact.log.info("Chunk Runnable STOPPED: " + key + " (" + RPGUtil.getLocationFancyName(location) + ")"); | |
} | |
} | |
@Override | |
public int hashCode() { | |
return Objects.hashCode(location); | |
} | |
@Override | |
public boolean equals(Object obj) { | |
return obj instanceof WorldRunnable && location.equals(((WorldRunnable) obj).location); | |
} | |
} | |
private ChunkTaskHandler() { | |
this.plugin = (TheArtifact) Bukkit.getPluginManager().getPlugin("TheArtifact"); | |
Bukkit.getPluginManager().registerEvents(this, plugin); | |
} | |
public static ChunkTaskHandler getInstance() { | |
return instance; | |
} | |
@EventHandler(priority = EventPriority.MONITOR) | |
private void onChunkLoad(ChunkLoadEvent e) { | |
Map<Object, WorldRunnable> effects = registeredChunks.get(getChunkHash(e.getChunk())); | |
if (effects != null) { | |
for (WorldRunnable entry : effects.values()) { | |
entry.start(); | |
} | |
} | |
} | |
@EventHandler(priority = EventPriority.MONITOR) | |
private void onChunkUnload(ChunkUnloadEvent e) { | |
Map<Object, WorldRunnable> effects = registeredChunks.get(getChunkHash(e.getChunk())); | |
if (effects != null) { | |
for (WorldRunnable entry : effects.values()) { | |
entry.cancel(); | |
} | |
} | |
} | |
public void registerTask(Object key, Location location, Runnable runnable, int delay, int frequency) { | |
int chunkKey = getChunkHash(location.getChunk()); | |
Map<Object, WorldRunnable> effects = registeredChunks.getOrDefault(chunkKey, new HashMap<>()); | |
//If we had an effect already here, remove first | |
if (removeTask(key)) { | |
TheArtifact.log.warning("Task Key Clash - Already had a task called " + key + "!"); | |
} | |
StringLocation l = new StringLocation(location); | |
WorldRunnable effect = new WorldRunnable(key, l, runnable, delay, frequency); | |
effects.put(key, effect); | |
registeredChunks.put(chunkKey, effects); | |
if (debug) { | |
TheArtifact.log.info("Chunk Task REGISTERED: " + key + " (" + totalTasks() + ") at " + RPGUtil.getLocationFancyName(location)); | |
} | |
} | |
private int totalTasks() { | |
return (int) registeredChunks.values().stream() | |
.map(Map::values) | |
.count(); | |
} | |
public boolean removeTask(Object key) { | |
for (Map.Entry<Integer, Map<Object, WorldRunnable>> entry : registeredChunks.entrySet()) { | |
WorldRunnable remove = entry.getValue().remove(key); | |
if (remove != null) { | |
remove.cancel(); | |
return true; | |
} | |
} | |
return false; | |
} | |
private int getChunkHash(Chunk c) { | |
return Objects.hash(c.getWorld(), c.getX(), c.getZ()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment