Final optimization

This commit is contained in:
Roch Blonndiaux 2023-03-13 17:59:27 +01:00
parent 9be8d9eb18
commit 7f0b29fd28
4 changed files with 138 additions and 39 deletions

View File

@ -254,7 +254,6 @@ public class MMOItems extends JavaPlugin {
@Override
public void onDisable() {
// Support for early plugin disabling
if (!hasLoadedSuccessfully)
return;
@ -269,6 +268,9 @@ public class MMOItems extends JavaPlugin {
for (Player player : Bukkit.getOnlinePlayers())
if (player.getOpenInventory() != null && player.getOpenInventory().getTopInventory().getHolder() instanceof PluginInventory)
player.closeInventory();
// WorldGen
this.worldGenManager.unload();
}
public String getPrefix() {

View File

@ -0,0 +1,27 @@
package net.Indyuce.mmoitems.listener;
import net.Indyuce.mmoitems.manager.WorldGenManager;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkLoadEvent;
/**
* mmoitems
* 13/03/2023
*
* @author Roch Blondiaux (Kiwix).
*/
public class WorldGenerationListener implements Listener {
private final WorldGenManager manager;
public WorldGenerationListener(WorldGenManager manager) {
this.manager = manager;
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent e) {
if (!e.isNewChunk()) return;
manager.populate(e);
}
}

View File

@ -4,6 +4,8 @@ import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.block.CustomBlock;
import net.Indyuce.mmoitems.api.block.WorldGenTemplate;
import net.Indyuce.mmoitems.listener.WorldGenerationListener;
import net.Indyuce.mmoitems.tasks.CustomBlocksPopulateTask;
import net.Indyuce.mmoitems.util.Pair;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
@ -11,10 +13,10 @@ import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.HandlerList;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.scheduler.BukkitRunnable;
import org.jetbrains.annotations.Blocking;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
import java.util.Map;
@ -23,7 +25,7 @@ import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Level;
public class WorldGenManager implements Listener, Reloadable {
public class WorldGenManager implements Reloadable {
private final Map<String, WorldGenTemplate> templates = new HashMap<>();
/*
@ -37,6 +39,9 @@ public class WorldGenManager implements Listener, Reloadable {
private static final BlockFace[] faces = {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST, BlockFace.DOWN, BlockFace.UP};
private static final Random random = new Random();
private WorldGenerationListener listener;
private CustomBlocksPopulateTask task;
public WorldGenManager() {
/*
* load the worldGenManager even if world gen is not enabled so that if
@ -44,9 +49,6 @@ public class WorldGenManager implements Listener, Reloadable {
* MI could not find corresponding gen template in config
*/
reload();
if (MMOItems.plugin.getLanguage().worldGenEnabled)
Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin);
}
public WorldGenTemplate getOrThrow(String id) {
@ -65,18 +67,17 @@ public class WorldGenManager implements Listener, Reloadable {
assigned.put(block, template);
}
@EventHandler
public void onChunkLoad(ChunkLoadEvent e) {
if (e.isNewChunk())
public void populate(@NotNull ChunkLoadEvent e) {
Bukkit.getScheduler().runTaskAsynchronously(MMOItems.plugin, () -> {
preprocess(e);
if (task != null && task.isRunning())
return;
if (e.isAsynchronous())
generate(e);
else
Bukkit.getScheduler().runTaskAsynchronously(MMOItems.plugin, () -> generate(e));
task = new CustomBlocksPopulateTask(this);
task.start();
});
}
private void generate(ChunkLoadEvent e) {
private @Blocking void preprocess(ChunkLoadEvent e) {
assigned.entrySet()
.stream()
.filter(entry -> entry.getValue().canGenerateInWorld(e.getWorld()))
@ -102,34 +103,20 @@ public class WorldGenManager implements Listener, Reloadable {
}
}
});
new BukkitRunnable() {
@Override
public void run() {
if (modificationsQueue.isEmpty()) {
this.cancel();
return;
}
Pair<Location, CustomBlock> pair = modificationsQueue.poll();
if (Bukkit.isPrimaryThread())
setBlockData(pair.getKey().getBlock(), pair.getValue());
else
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> setBlockData(pair.getKey().getBlock(), pair.getValue()));
}
}.runTaskTimer(MMOItems.plugin, 0, 5);
}
private void setBlockData(Block fModify, CustomBlock block) {
fModify.setType(block.getState().getType(), false);
fModify.setBlockData(block.getState().getBlockData(), false);
public Queue<Pair<Location, CustomBlock>> getModificationsQueue() {
return modificationsQueue;
}
public void reload() {
// Listener
if (listener != null)
HandlerList.unregisterAll(listener);
assigned.clear();
templates.clear();
modificationsQueue.clear();
FileConfiguration config = new ConfigFile("gen-templates").getConfig();
for (String key : config.getKeys(false)) {
@ -140,5 +127,16 @@ public class WorldGenManager implements Listener, Reloadable {
MMOItems.plugin.getLogger().log(Level.WARNING, "An error occurred when loading gen template '" + key + "': " + exception.getMessage());
}
}
// Listeners
if (MMOItems.plugin.getLanguage().worldGenEnabled)
Bukkit.getPluginManager().registerEvents(listener = new WorldGenerationListener(this), MMOItems.plugin);
}
public void unload() {
if (listener != null)
HandlerList.unregisterAll(listener);
if (task != null)
task.stop();
}
}

View File

@ -0,0 +1,72 @@
package net.Indyuce.mmoitems.tasks;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.block.CustomBlock;
import net.Indyuce.mmoitems.manager.WorldGenManager;
import net.Indyuce.mmoitems.util.Pair;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Queue;
/**
* mmoitems
* 13/03/2023
*
* @author Roch Blondiaux (Kiwix).
*/
public class CustomBlocksPopulateTask extends BukkitRunnable {
private final WorldGenManager manager;
private boolean running = false;
public CustomBlocksPopulateTask(WorldGenManager manager) {
this.manager = manager;
}
@Override
public void run() {
final Queue<Pair<Location, CustomBlock>> modificationsQueue = manager.getModificationsQueue();
final Pair<Location, CustomBlock> pair = modificationsQueue.poll();
// If the queue is empty, cancel the task
if (pair == null) {
this.stop();
return;
}
// If the chunk is not loaded, skip it
if (!pair.getKey().getChunk().isLoaded())
return;
// If the block is already modified, skip it
if (pair.getKey().getBlock().getBlockData().equals(pair.getValue().getState().getBlockData()))
return;
// Change the block
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> setBlockData(pair.getKey().getBlock(), pair.getValue()));
}
private void setBlockData(Block fModify, CustomBlock block) {
fModify.setType(block.getState().getType(), false);
fModify.setBlockData(block.getState().getBlockData(), false);
}
public void start() {
if (running) return;
running = true;
this.runTaskTimerAsynchronously(MMOItems.plugin, 0, 1);
}
public void stop() {
if (!running) return;
running = false;
this.cancel();
}
public boolean isRunning() {
return running;
}
}