1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

Merge pull request #3015 from Slimefun/performance/networks

Improved memory usage of cargo/energy networks and fixed #3013
This commit is contained in:
TheBusyBiscuit 2021-05-10 18:44:01 +02:00 committed by GitHub
commit 8a8b8ce577
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 11 deletions

View File

@ -46,6 +46,7 @@
* Magical Glass can no longer be placed
* (API) Removed deprecated "SlimefunBlockHandler"
* Removed Automated Crafting Chamber
* Memory and performance improvements for Cargo and Energy networks
#### Fixes
* Fixed #2987
@ -57,6 +58,7 @@
* Fixed #2927
* Fixed #3007
* Fixed #3012
* Fixed #3013
* Fixed #3027
* Fixed #2978
* Possibly fixed #2927

View File

@ -370,7 +370,7 @@
<!-- Shaded packages -->
<dependency>
<groupId>com.github.TheBusyBiscuit</groupId>
<groupId>com.github.thebusybiscuit</groupId>
<artifactId>CS-CoreLib2</artifactId>
<version>0.31.0</version>
<scope>compile</scope>

View File

@ -4,6 +4,7 @@ import java.util.ArrayDeque;
import java.util.HashSet;
import java.util.Queue;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@ -11,7 +12,9 @@ import javax.annotation.Nullable;
import org.apache.commons.lang.Validate;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
@ -20,6 +23,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListen
* An abstract Network class to manage networks in a stateful way
*
* @author meiamsome
* @author TheBusyBiscuit
*
* @see NetworkListener
* @see NetworkManager
@ -37,8 +41,19 @@ public abstract class Network {
*/
protected Location regulator;
/**
* The {@link UUID} of the {@link World} this {@link Network} exists within.
*/
private final UUID worldId;
/**
* This {@link Set} holds all {@link Network} positions that are part of this {@link Network}.
* The {@link World} should be equal for all positions, therefore we can save memory by simply
* storing {@link BlockPosition#getAsLong(int, int, int)}.
*/
private final Set<Long> positions = new HashSet<>();
private final Queue<Location> nodeQueue = new ArrayDeque<>();
protected final Set<Location> connectedLocations = new HashSet<>();
protected final Set<Location> regulatorNodes = new HashSet<>();
protected final Set<Location> connectorNodes = new HashSet<>();
protected final Set<Location> terminusNodes = new HashSet<>();
@ -57,8 +72,9 @@ public abstract class Network {
this.manager = manager;
this.regulator = regulator;
this.worldId = regulator.getWorld().getUID();
connectedLocations.add(regulator);
positions.add(BlockPosition.getAsLong(regulator));
nodeQueue.add(regulator.clone());
}
@ -115,7 +131,10 @@ public abstract class Network {
* The {@link Location} to add
*/
protected void addLocationToNetwork(@Nonnull Location l) {
if (connectedLocations.add(l.clone())) {
Validate.notNull(l, "You cannot add a Location to a Network which is null!");
Validate.isTrue(l.getWorld().getUID().equals(worldId), "Networks cannot exist in multiple worlds!");
if (positions.add(BlockPosition.getAsLong(l))) {
markDirty(l);
}
}
@ -144,10 +163,14 @@ public abstract class Network {
* @return Whether the given {@link Location} is part of this {@link Network}
*/
public boolean connectsTo(@Nonnull Location l) {
if (regulator.equals(l)) {
Validate.notNull(l, "The Location cannot be null.");
if (this.regulator.equals(l)) {
return true;
} else if (!l.getWorld().getUID().equals(this.worldId)) {
return false;
} else {
return connectedLocations.contains(l);
return positions.contains(BlockPosition.getAsLong(l));
}
}

View File

@ -13,9 +13,12 @@ import org.bukkit.Location;
import org.bukkit.Server;
import io.github.thebusybiscuit.cscorelib2.config.Config;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.core.networks.cargo.CargoNet;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener;
import me.mrCookieSlime.Slimefun.api.BlockStorage;
/**
* The {@link NetworkManager} is responsible for holding all instances of {@link Network}
@ -169,11 +172,26 @@ public class NetworkManager {
public void updateAllNetworks(@Nonnull Location l) {
Validate.notNull(l, "The Location cannot be null");
// No need to create a sublist and loop through it if there are no Networks
if (!networks.isEmpty()) {
for (Network network : getNetworksFromLocation(l, Network.class)) {
network.markDirty(l);
}
/*
* No need to create a sublist and loop through it if
* there aren't even any networks on the server.
*/
if (networks.isEmpty()) {
return;
}
/*
* Only a Slimefun block can be part of a Network.
* This check helps to speed up performance.
*
* (Skip for Unit Tests as they don't support block info yet)
*/
if (!BlockStorage.hasBlockInfo(l) && SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) {
return;
}
for (Network network : getNetworksFromLocation(l, Network.class)) {
network.markDirty(l);
}
}

View File

@ -2,12 +2,14 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import javax.annotation.Nonnull;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import io.github.thebusybiscuit.slimefun4.api.events.ExplosiveToolBreakBlocksEvent;
import io.github.thebusybiscuit.slimefun4.api.network.Network;
import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager;
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
@ -16,6 +18,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
* This {@link Listener} is responsible for all updates to a {@link Network}.
*
* @author meiamsome
* @author TheBusyBiscuit
*
* @see Network
* @see NetworkManager
@ -23,6 +26,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
*/
public class NetworkListener implements Listener {
/**
* Our {@link NetworkManager} instance.
*/
private final NetworkManager manager;
public NetworkListener(@Nonnull SlimefunPlugin plugin, @Nonnull NetworkManager manager) {
@ -39,4 +45,12 @@ public class NetworkListener implements Listener {
public void onBlockPlace(BlockPlaceEvent e) {
manager.updateAllNetworks(e.getBlock().getLocation());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onExplosiveToolUse(ExplosiveToolBreakBlocksEvent e) {
// Fixes #3013 - Also update networks when using an explosive tool
for (Block b : e.getAdditionalBlocks()) {
manager.updateAllNetworks(b.getLocation());
}
}
}