From ef01c8588877da556798632ff7849a6a9b10354a Mon Sep 17 00:00:00 2001 From: TheBusyBiscuit Date: Thu, 6 Aug 2020 00:30:33 +0200 Subject: [PATCH] Some refactoring, requested changes --- .../core/attributes/EnergyNetComponent.java | 5 + .../core/networks/energy/EnergyNet.java | 116 +++++++------- .../items/electric/EnergyRegulator.java | 4 +- .../implementation/tasks/TickerTask.java | 144 ++++++++++-------- 4 files changed, 146 insertions(+), 123 deletions(-) diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java index 9d1ae90d7..44b6c9caf 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/EnergyNetComponent.java @@ -62,6 +62,7 @@ public interface EnergyNetComponent extends ItemAttribute { * @return The charge stored at that {@link Location} */ default int getCharge(Location l) { + Validate.notNull(l, "Location was null!"); String charge = BlockStorage.getLocationInfo(l, "energy-charge"); if (charge != null) { @@ -83,6 +84,8 @@ public interface EnergyNetComponent extends ItemAttribute { * The new charge */ default void setCharge(Location l, int charge) { + Validate.notNull(l, "Location was null!"); + Validate.isTrue(charge >= 0, "You can only set a charge of zero or more!"); int capacity = getCapacity(); // This method only makes sense if we can actually store energy @@ -102,6 +105,7 @@ public interface EnergyNetComponent extends ItemAttribute { } default void addCharge(Location l, int charge) { + Validate.notNull(l, "Location was null!"); Validate.isTrue(charge > 0, "You can only add a positive charge!"); int capacity = getCapacity(); @@ -123,6 +127,7 @@ public interface EnergyNetComponent extends ItemAttribute { } default void removeCharge(Location l, int charge) { + Validate.notNull(l, "Location was null!"); Validate.isTrue(charge > 0, "The charge to remove must be greater than zero!"); int capacity = getCapacity(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java index d995fbc9f..b034c7a17 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java @@ -43,35 +43,6 @@ public class EnergyNet extends Network { private static final int RANGE = 6; - private static EnergyNetComponent getComponent(Location l) { - String id = BlockStorage.checkID(l); - - if (id == null) { - return null; - } - - SlimefunItem item = SlimefunItem.getByID(id); - - if (item instanceof EnergyNetComponent) { - return ((EnergyNetComponent) item); - } - - return null; - } - - public static EnergyNet getNetworkFromLocationOrCreate(Location l) { - Optional cargoNetwork = SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, EnergyNet.class); - - if (cargoNetwork.isPresent()) { - return cargoNetwork.get(); - } - else { - EnergyNet network = new EnergyNet(l); - SlimefunPlugin.getNetworkManager().registerNetwork(network); - return network; - } - } - private final Map generators = new HashMap<>(); private final Map capacitors = new HashMap<>(); private final Map consumers = new HashMap<>(); @@ -154,10 +125,10 @@ public class EnergyNet extends Network { int demand = 0; for (Map.Entry entry : consumers.entrySet()) { - Location l = entry.getKey(); + Location loc = entry.getKey(); EnergyNetComponent component = entry.getValue(); int capacity = component.getCapacity(); - int charge = component.getCharge(l); + int charge = component.getCharge(loc); if (charge < capacity) { int availableSpace = capacity - charge; @@ -165,11 +136,11 @@ public class EnergyNet extends Network { if (remainingEnergy > 0) { if (remainingEnergy > availableSpace) { - component.setCharge(l, capacity); + component.setCharge(loc, capacity); remainingEnergy -= availableSpace; } else { - component.setCharge(l, charge + remainingEnergy); + component.setCharge(loc, charge + remainingEnergy); remainingEnergy = 0; } } @@ -186,74 +157,75 @@ public class EnergyNet extends Network { private void storeRemainingEnergy(int remainingEnergy) { for (Map.Entry entry : capacitors.entrySet()) { - Location l = entry.getKey(); + Location loc = entry.getKey(); EnergyNetComponent component = entry.getValue(); if (remainingEnergy > 0) { int capacity = component.getCapacity(); if (remainingEnergy > capacity) { - component.setCharge(l, capacity); + component.setCharge(loc, capacity); remainingEnergy -= capacity; } else { - component.setCharge(l, remainingEnergy); + component.setCharge(loc, remainingEnergy); remainingEnergy = 0; } } else { - component.setCharge(l, 0); + component.setCharge(loc, 0); } } for (Map.Entry entry : generators.entrySet()) { - Location l = entry.getKey(); + Location loc = entry.getKey(); EnergyNetComponent component = entry.getValue(); int capacity = component.getCapacity(); if (remainingEnergy > 0) { if (remainingEnergy > capacity) { - component.setCharge(l, capacity); + component.setCharge(loc, capacity); remainingEnergy -= capacity; } else { - component.setCharge(l, remainingEnergy); + component.setCharge(loc, remainingEnergy); remainingEnergy = 0; } } else { - component.setCharge(l, 0); + component.setCharge(loc, 0); } } } private int tickAllGenerators(LongConsumer timings) { - Set exploded = new HashSet<>(); + Set explodedBlocks = new HashSet<>(); int supply = 0; for (Map.Entry entry : generators.entrySet()) { long timestamp = SlimefunPlugin.getProfiler().newEntry(); - Location l = entry.getKey(); + Location loc = entry.getKey(); EnergyNetComponent component = entry.getValue(); if (component instanceof EnergyNetProvider) { SlimefunItem item = (SlimefunItem) component; + try { EnergyNetProvider provider = (EnergyNetProvider) component; - Config config = BlockStorage.getLocationInfo(l); - int energy = provider.getGeneratedOutput(l, config); + Config config = BlockStorage.getLocationInfo(loc); + int energy = provider.getGeneratedOutput(loc, config); if (provider.isChargeable()) { - energy += provider.getCharge(l); + energy += provider.getCharge(loc); } - if (provider.willExplode(l, config)) { - exploded.add(l); - BlockStorage.clearBlockInfo(l); + if (provider.willExplode(loc, config)) { + explodedBlocks.add(loc); + BlockStorage.clearBlockInfo(loc); Slimefun.runSync(() -> { - l.getBlock().setType(Material.LAVA); - l.getWorld().createExplosion(l, 0F, false); + loc.getBlock().setType(Material.LAVA); + loc.getWorld().createExplosion(loc, 0F, false); }); } else { @@ -261,21 +233,21 @@ public class EnergyNet extends Network { } } catch (Exception | LinkageError t) { - exploded.add(l); - new ErrorReport(t, l, item); + explodedBlocks.add(loc); + new ErrorReport(t, loc, item); } - long time = SlimefunPlugin.getProfiler().closeEntry(l, item, timestamp); + long time = SlimefunPlugin.getProfiler().closeEntry(loc, item, timestamp); timings.accept(time); } else { // This block seems to be gone now, better remove it to be extra safe - exploded.add(l); + explodedBlocks.add(loc); } } // Remove all generators which have exploded - generators.keySet().removeAll(exploded); + generators.keySet().removeAll(explodedBlocks); return supply; } @@ -299,4 +271,36 @@ public class EnergyNet extends Network { SimpleHologram.update(b, "&2&l+ &a" + netGain + " &7J &e\u26A1"); } } + + private static EnergyNetComponent getComponent(Location l) { + SlimefunItem item = BlockStorage.check(l); + + if (item instanceof EnergyNetComponent) { + return ((EnergyNetComponent) item); + } + + return null; + } + + /** + * This attempts to get an {@link EnergyNet} from a given {@link Location}. + * If no suitable {@link EnergyNet} could be found, a new one will be created. + * + * @param l + * The target {@link Location} + * + * @return The {@link EnergyNet} at that {@link Location}, or a new one + */ + public static EnergyNet getNetworkFromLocationOrCreate(Location l) { + Optional energyNetwork = SlimefunPlugin.getNetworkManager().getNetworkFromLocation(l, EnergyNet.class); + + if (energyNetwork.isPresent()) { + return energyNetwork.get(); + } + else { + EnergyNet network = new EnergyNet(l); + SlimefunPlugin.getNetworkManager().registerNetwork(network); + return network; + } + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java index c26043fde..4a1a65110 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/EnergyRegulator.java @@ -50,6 +50,7 @@ public class EnergyRegulator extends SlimefunItem { @Override public void preRegister() { addItemHandler(onPlace()); + addItemHandler(new BlockTicker() { @Override @@ -59,7 +60,8 @@ public class EnergyRegulator extends SlimefunItem { @Override public void tick(Block b, SlimefunItem item, Config data) { - EnergyNet.getNetworkFromLocationOrCreate(b.getLocation()).tick(b); + EnergyNet network = EnergyNet.getNetworkFromLocationOrCreate(b.getLocation()); + network.tick(b); } }); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java index f90b0a937..2519a24ba 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java @@ -12,6 +12,7 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.scheduler.BukkitScheduler; import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition; import io.github.thebusybiscuit.slimefun4.api.ErrorReport; @@ -25,8 +26,6 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; public class TickerTask implements Runnable { - private final Set tickers = new HashSet<>(); - // These are "Queues" of blocks that need to be removed or moved private final Map movingQueue = new ConcurrentHashMap<>(); private final Map deletionQueue = new ConcurrentHashMap<>(); @@ -36,66 +35,93 @@ public class TickerTask implements Runnable { private boolean halted = false; private boolean running = false; - public void abortTick() { + /** + * This method starts the {@link TickerTask} on an asynchronous schedule. + * + * @param plugin + * The instance of our {@link SlimefunPlugin} + */ + public void start(SlimefunPlugin plugin) { + this.tickRate = SlimefunPlugin.getCfg().getInt("URID.custom-ticker-delay"); + + BukkitScheduler scheduler = plugin.getServer().getScheduler(); + scheduler.runTaskTimerAsynchronously(plugin, this, 100L, tickRate); + } + + /** + * This method resets this {@link TickerTask} to run again. + */ + public void reset() { running = false; } @Override public void run() { - if (running) { - return; - } + try { + // If this method is actually still running... DON'T + if (running) { + return; + } - running = true; - SlimefunPlugin.getProfiler().start(); + running = true; + SlimefunPlugin.getProfiler().start(); + Set tickers = new HashSet<>(); - Iterator> removals = deletionQueue.entrySet().iterator(); - while (removals.hasNext()) { - Map.Entry entry = removals.next(); - BlockStorage.deleteLocationInfoUnsafely(entry.getKey(), entry.getValue()); - removals.remove(); - } + Iterator> removals = deletionQueue.entrySet().iterator(); + while (removals.hasNext()) { + Map.Entry entry = removals.next(); + BlockStorage.deleteLocationInfoUnsafely(entry.getKey(), entry.getValue()); + removals.remove(); + } - if (!halted) { - for (String chunk : BlockStorage.getTickingChunks()) { - try { - Set locations = BlockStorage.getTickingLocations(chunk); - String[] components = PatternUtils.SEMICOLON.split(chunk); - - World world = Bukkit.getWorld(components[0]); - int x = Integer.parseInt(components[components.length - 2]); - int z = Integer.parseInt(components[components.length - 1]); - - if (world != null && world.isChunkLoaded(x, z)) { - for (Location l : locations) { - tick(l); - } - } + if (!halted) { + for (String chunk : BlockStorage.getTickingChunks()) { + tickChunk(tickers, chunk); } - catch (ArrayIndexOutOfBoundsException | NumberFormatException x) { - Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception has occured while trying to parse Chunk: " + chunk); + } + + Iterator> moves = movingQueue.entrySet().iterator(); + while (moves.hasNext()) { + Map.Entry entry = moves.next(); + BlockStorage.moveLocationInfoUnsafely(entry.getKey(), entry.getValue()); + moves.remove(); + } + + // Start a new tick cycle for every BlockTicker + for (BlockTicker ticker : tickers) { + ticker.startNewTick(); + } + + reset(); + SlimefunPlugin.getProfiler().stop(); + } + catch (Exception | LinkageError x) { + Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion()); + reset(); + } + } + + private void tickChunk(Set tickers, String chunk) { + try { + Set locations = BlockStorage.getTickingLocations(chunk); + String[] components = PatternUtils.SEMICOLON.split(chunk); + + World world = Bukkit.getWorld(components[0]); + int x = Integer.parseInt(components[components.length - 2]); + int z = Integer.parseInt(components[components.length - 1]); + + if (world != null && world.isChunkLoaded(x, z)) { + for (Location l : locations) { + tick(tickers, l); } } } - - Iterator> moves = movingQueue.entrySet().iterator(); - while (moves.hasNext()) { - Map.Entry entry = moves.next(); - BlockStorage.moveLocationInfoUnsafely(entry.getKey(), entry.getValue()); - moves.remove(); + catch (ArrayIndexOutOfBoundsException | NumberFormatException x) { + Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception has occured while trying to parse Chunk: " + chunk); } - - Iterator iterator = tickers.iterator(); - while (iterator.hasNext()) { - iterator.next().startNewTick(); - iterator.remove(); - } - - running = false; - SlimefunPlugin.getProfiler().stop(); } - private void tick(Location l) { + private void tick(Set tickers, Location l) { Config data = BlockStorage.getLocationInfo(l); SlimefunItem item = SlimefunItem.getByID(data.getString("id")); @@ -170,11 +196,6 @@ public class TickerTask implements Runnable { halted = true; } - @Override - public String toString() { - return "TickerTask {\n" + " HALTED = " + halted + "\n" + " tickers = " + tickers + "\n" + " move = " + movingQueue + "\n" + " delete = " + deletionQueue + "}"; - } - public void queueMove(Location from, Location to) { movingQueue.put(from, to); } @@ -183,22 +204,13 @@ public class TickerTask implements Runnable { deletionQueue.put(l, destroy); } - public void start(SlimefunPlugin plugin) { - this.tickRate = SlimefunPlugin.getCfg().getInt("URID.custom-ticker-delay"); - - plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> { - try { - run(); - } - catch (Exception | LinkageError x) { - plugin.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion()); - abortTick(); - } - }, 100L, tickRate); - } - public int getTickRate() { return tickRate; } + @Override + public String toString() { + return "TickerTask {\n" + " HALTED = " + halted + "\n" + " move = " + movingQueue + "\n" + " delete = " + deletionQueue + "}"; + } + }