1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-20 11:45:51 +00:00

Some refactoring, requested changes

This commit is contained in:
TheBusyBiscuit 2020-08-06 00:30:33 +02:00
parent 32849ca563
commit ef01c85888
4 changed files with 146 additions and 123 deletions

View File

@ -62,6 +62,7 @@ public interface EnergyNetComponent extends ItemAttribute {
* @return The charge stored at that {@link Location} * @return The charge stored at that {@link Location}
*/ */
default int getCharge(Location l) { default int getCharge(Location l) {
Validate.notNull(l, "Location was null!");
String charge = BlockStorage.getLocationInfo(l, "energy-charge"); String charge = BlockStorage.getLocationInfo(l, "energy-charge");
if (charge != null) { if (charge != null) {
@ -83,6 +84,8 @@ public interface EnergyNetComponent extends ItemAttribute {
* The new charge * The new charge
*/ */
default void setCharge(Location l, int 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(); int capacity = getCapacity();
// This method only makes sense if we can actually store energy // 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) { default void addCharge(Location l, int charge) {
Validate.notNull(l, "Location was null!");
Validate.isTrue(charge > 0, "You can only add a positive charge!"); Validate.isTrue(charge > 0, "You can only add a positive charge!");
int capacity = getCapacity(); int capacity = getCapacity();
@ -123,6 +127,7 @@ public interface EnergyNetComponent extends ItemAttribute {
} }
default void removeCharge(Location l, int charge) { 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!"); Validate.isTrue(charge > 0, "The charge to remove must be greater than zero!");
int capacity = getCapacity(); int capacity = getCapacity();

View File

@ -43,35 +43,6 @@ public class EnergyNet extends Network {
private static final int RANGE = 6; 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<EnergyNet> 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<Location, EnergyNetComponent> generators = new HashMap<>(); private final Map<Location, EnergyNetComponent> generators = new HashMap<>();
private final Map<Location, EnergyNetComponent> capacitors = new HashMap<>(); private final Map<Location, EnergyNetComponent> capacitors = new HashMap<>();
private final Map<Location, EnergyNetComponent> consumers = new HashMap<>(); private final Map<Location, EnergyNetComponent> consumers = new HashMap<>();
@ -154,10 +125,10 @@ public class EnergyNet extends Network {
int demand = 0; int demand = 0;
for (Map.Entry<Location, EnergyNetComponent> entry : consumers.entrySet()) { for (Map.Entry<Location, EnergyNetComponent> entry : consumers.entrySet()) {
Location l = entry.getKey(); Location loc = entry.getKey();
EnergyNetComponent component = entry.getValue(); EnergyNetComponent component = entry.getValue();
int capacity = component.getCapacity(); int capacity = component.getCapacity();
int charge = component.getCharge(l); int charge = component.getCharge(loc);
if (charge < capacity) { if (charge < capacity) {
int availableSpace = capacity - charge; int availableSpace = capacity - charge;
@ -165,11 +136,11 @@ public class EnergyNet extends Network {
if (remainingEnergy > 0) { if (remainingEnergy > 0) {
if (remainingEnergy > availableSpace) { if (remainingEnergy > availableSpace) {
component.setCharge(l, capacity); component.setCharge(loc, capacity);
remainingEnergy -= availableSpace; remainingEnergy -= availableSpace;
} }
else { else {
component.setCharge(l, charge + remainingEnergy); component.setCharge(loc, charge + remainingEnergy);
remainingEnergy = 0; remainingEnergy = 0;
} }
} }
@ -186,74 +157,75 @@ public class EnergyNet extends Network {
private void storeRemainingEnergy(int remainingEnergy) { private void storeRemainingEnergy(int remainingEnergy) {
for (Map.Entry<Location, EnergyNetComponent> entry : capacitors.entrySet()) { for (Map.Entry<Location, EnergyNetComponent> entry : capacitors.entrySet()) {
Location l = entry.getKey(); Location loc = entry.getKey();
EnergyNetComponent component = entry.getValue(); EnergyNetComponent component = entry.getValue();
if (remainingEnergy > 0) { if (remainingEnergy > 0) {
int capacity = component.getCapacity(); int capacity = component.getCapacity();
if (remainingEnergy > capacity) { if (remainingEnergy > capacity) {
component.setCharge(l, capacity); component.setCharge(loc, capacity);
remainingEnergy -= capacity; remainingEnergy -= capacity;
} }
else { else {
component.setCharge(l, remainingEnergy); component.setCharge(loc, remainingEnergy);
remainingEnergy = 0; remainingEnergy = 0;
} }
} }
else { else {
component.setCharge(l, 0); component.setCharge(loc, 0);
} }
} }
for (Map.Entry<Location, EnergyNetComponent> entry : generators.entrySet()) { for (Map.Entry<Location, EnergyNetComponent> entry : generators.entrySet()) {
Location l = entry.getKey(); Location loc = entry.getKey();
EnergyNetComponent component = entry.getValue(); EnergyNetComponent component = entry.getValue();
int capacity = component.getCapacity(); int capacity = component.getCapacity();
if (remainingEnergy > 0) { if (remainingEnergy > 0) {
if (remainingEnergy > capacity) { if (remainingEnergy > capacity) {
component.setCharge(l, capacity); component.setCharge(loc, capacity);
remainingEnergy -= capacity; remainingEnergy -= capacity;
} }
else { else {
component.setCharge(l, remainingEnergy); component.setCharge(loc, remainingEnergy);
remainingEnergy = 0; remainingEnergy = 0;
} }
} }
else { else {
component.setCharge(l, 0); component.setCharge(loc, 0);
} }
} }
} }
private int tickAllGenerators(LongConsumer timings) { private int tickAllGenerators(LongConsumer timings) {
Set<Location> exploded = new HashSet<>(); Set<Location> explodedBlocks = new HashSet<>();
int supply = 0; int supply = 0;
for (Map.Entry<Location, EnergyNetComponent> entry : generators.entrySet()) { for (Map.Entry<Location, EnergyNetComponent> entry : generators.entrySet()) {
long timestamp = SlimefunPlugin.getProfiler().newEntry(); long timestamp = SlimefunPlugin.getProfiler().newEntry();
Location l = entry.getKey(); Location loc = entry.getKey();
EnergyNetComponent component = entry.getValue(); EnergyNetComponent component = entry.getValue();
if (component instanceof EnergyNetProvider) { if (component instanceof EnergyNetProvider) {
SlimefunItem item = (SlimefunItem) component; SlimefunItem item = (SlimefunItem) component;
try { try {
EnergyNetProvider provider = (EnergyNetProvider) component; EnergyNetProvider provider = (EnergyNetProvider) component;
Config config = BlockStorage.getLocationInfo(l); Config config = BlockStorage.getLocationInfo(loc);
int energy = provider.getGeneratedOutput(l, config); int energy = provider.getGeneratedOutput(loc, config);
if (provider.isChargeable()) { if (provider.isChargeable()) {
energy += provider.getCharge(l); energy += provider.getCharge(loc);
} }
if (provider.willExplode(l, config)) { if (provider.willExplode(loc, config)) {
exploded.add(l); explodedBlocks.add(loc);
BlockStorage.clearBlockInfo(l); BlockStorage.clearBlockInfo(loc);
Slimefun.runSync(() -> { Slimefun.runSync(() -> {
l.getBlock().setType(Material.LAVA); loc.getBlock().setType(Material.LAVA);
l.getWorld().createExplosion(l, 0F, false); loc.getWorld().createExplosion(loc, 0F, false);
}); });
} }
else { else {
@ -261,21 +233,21 @@ public class EnergyNet extends Network {
} }
} }
catch (Exception | LinkageError t) { catch (Exception | LinkageError t) {
exploded.add(l); explodedBlocks.add(loc);
new ErrorReport(t, l, item); new ErrorReport(t, loc, item);
} }
long time = SlimefunPlugin.getProfiler().closeEntry(l, item, timestamp); long time = SlimefunPlugin.getProfiler().closeEntry(loc, item, timestamp);
timings.accept(time); timings.accept(time);
} }
else { else {
// This block seems to be gone now, better remove it to be extra safe // 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 // Remove all generators which have exploded
generators.keySet().removeAll(exploded); generators.keySet().removeAll(explodedBlocks);
return supply; return supply;
} }
@ -299,4 +271,36 @@ public class EnergyNet extends Network {
SimpleHologram.update(b, "&2&l+ &a" + netGain + " &7J &e\u26A1"); 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<EnergyNet> 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;
}
}
} }

View File

@ -50,6 +50,7 @@ public class EnergyRegulator extends SlimefunItem {
@Override @Override
public void preRegister() { public void preRegister() {
addItemHandler(onPlace()); addItemHandler(onPlace());
addItemHandler(new BlockTicker() { addItemHandler(new BlockTicker() {
@Override @Override
@ -59,7 +60,8 @@ public class EnergyRegulator extends SlimefunItem {
@Override @Override
public void tick(Block b, SlimefunItem item, Config data) { public void tick(Block b, SlimefunItem item, Config data) {
EnergyNet.getNetworkFromLocationOrCreate(b.getLocation()).tick(b); EnergyNet network = EnergyNet.getNetworkFromLocationOrCreate(b.getLocation());
network.tick(b);
} }
}); });
} }

View File

@ -12,6 +12,7 @@ import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.scheduler.BukkitScheduler;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition; import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
import io.github.thebusybiscuit.slimefun4.api.ErrorReport; import io.github.thebusybiscuit.slimefun4.api.ErrorReport;
@ -25,8 +26,6 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
public class TickerTask implements Runnable { public class TickerTask implements Runnable {
private final Set<BlockTicker> tickers = new HashSet<>();
// These are "Queues" of blocks that need to be removed or moved // These are "Queues" of blocks that need to be removed or moved
private final Map<Location, Location> movingQueue = new ConcurrentHashMap<>(); private final Map<Location, Location> movingQueue = new ConcurrentHashMap<>();
private final Map<Location, Boolean> deletionQueue = new ConcurrentHashMap<>(); private final Map<Location, Boolean> deletionQueue = new ConcurrentHashMap<>();
@ -36,66 +35,93 @@ public class TickerTask implements Runnable {
private boolean halted = false; private boolean halted = false;
private boolean running = 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; running = false;
} }
@Override @Override
public void run() { public void run() {
if (running) { try {
return; // If this method is actually still running... DON'T
} if (running) {
return;
}
running = true; running = true;
SlimefunPlugin.getProfiler().start(); SlimefunPlugin.getProfiler().start();
Set<BlockTicker> tickers = new HashSet<>();
Iterator<Map.Entry<Location, Boolean>> removals = deletionQueue.entrySet().iterator(); Iterator<Map.Entry<Location, Boolean>> removals = deletionQueue.entrySet().iterator();
while (removals.hasNext()) { while (removals.hasNext()) {
Map.Entry<Location, Boolean> entry = removals.next(); Map.Entry<Location, Boolean> entry = removals.next();
BlockStorage.deleteLocationInfoUnsafely(entry.getKey(), entry.getValue()); BlockStorage.deleteLocationInfoUnsafely(entry.getKey(), entry.getValue());
removals.remove(); removals.remove();
} }
if (!halted) { if (!halted) {
for (String chunk : BlockStorage.getTickingChunks()) { for (String chunk : BlockStorage.getTickingChunks()) {
try { tickChunk(tickers, chunk);
Set<Location> 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);
}
}
} }
catch (ArrayIndexOutOfBoundsException | NumberFormatException x) { }
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception has occured while trying to parse Chunk: " + chunk);
Iterator<Map.Entry<Location, Location>> moves = movingQueue.entrySet().iterator();
while (moves.hasNext()) {
Map.Entry<Location, Location> 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<BlockTicker> tickers, String chunk) {
try {
Set<Location> 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);
} }
} }
} }
catch (ArrayIndexOutOfBoundsException | NumberFormatException x) {
Iterator<Map.Entry<Location, Location>> moves = movingQueue.entrySet().iterator(); Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception has occured while trying to parse Chunk: " + chunk);
while (moves.hasNext()) {
Map.Entry<Location, Location> entry = moves.next();
BlockStorage.moveLocationInfoUnsafely(entry.getKey(), entry.getValue());
moves.remove();
} }
Iterator<BlockTicker> 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<BlockTicker> tickers, Location l) {
Config data = BlockStorage.getLocationInfo(l); Config data = BlockStorage.getLocationInfo(l);
SlimefunItem item = SlimefunItem.getByID(data.getString("id")); SlimefunItem item = SlimefunItem.getByID(data.getString("id"));
@ -170,11 +196,6 @@ public class TickerTask implements Runnable {
halted = true; 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) { public void queueMove(Location from, Location to) {
movingQueue.put(from, to); movingQueue.put(from, to);
} }
@ -183,22 +204,13 @@ public class TickerTask implements Runnable {
deletionQueue.put(l, destroy); 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() { public int getTickRate() {
return tickRate; return tickRate;
} }
@Override
public String toString() {
return "TickerTask {\n" + " HALTED = " + halted + "\n" + " move = " + movingQueue + "\n" + " delete = " + deletionQueue + "}";
}
} }