mirror of
https://github.com/StarWishsama/Slimefun4.git
synced 2024-09-19 19:25:48 +00:00
A ton of performance improvements
This commit is contained in:
parent
94752a9027
commit
7e657c9810
@ -42,6 +42,8 @@
|
||||
* Magnets can no longer be placed down
|
||||
* Electromagnets can no longer be placed down
|
||||
* Performance improvements to Cargo network visualizations
|
||||
* General performance improvements
|
||||
* Improved performance for radioactive items
|
||||
|
||||
#### Fixes
|
||||
* Fixed #2448
|
||||
|
2
pom.xml
2
pom.xml
@ -337,7 +337,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.TheBusyBiscuit</groupId>
|
||||
<artifactId>CS-CoreLib2</artifactId>
|
||||
<version>0.27</version>
|
||||
<version>0.27.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
@ -10,6 +10,7 @@ import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponen
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.NumberUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
import me.mrCookieSlime.Slimefun.api.BlockStorage;
|
||||
|
||||
@ -65,14 +66,36 @@ public interface EnergyNetComponent extends ItemAttribute {
|
||||
* @return The charge stored at that {@link Location}
|
||||
*/
|
||||
default int getCharge(@Nonnull Location l) {
|
||||
// Emergency fallback, this cannot hold a charge, so we'll just return zero
|
||||
if (!isChargeable()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return getCharge(l, BlockStorage.getLocationInfo(l));
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the currently stored charge at a given {@link Location}.
|
||||
* This is a more performance saving option if you already have a {@link Config}
|
||||
* object for this {@link Location}.
|
||||
*
|
||||
* @param l
|
||||
* The target {@link Location}
|
||||
* @param data
|
||||
* The data at this {@link Location}
|
||||
*
|
||||
* @return The charge stored at that {@link Location}
|
||||
*/
|
||||
default int getCharge(@Nonnull Location l, @Nonnull Config data) {
|
||||
Validate.notNull(l, "Location was null!");
|
||||
Validate.notNull(data, "data was null!");
|
||||
|
||||
// Emergency fallback, this cannot hold a charge, so we'll just return zero
|
||||
if (!isChargeable()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
String charge = BlockStorage.getLocationInfo(l, "energy-charge");
|
||||
String charge = data.getString("energy-charge");
|
||||
|
||||
if (charge != null) {
|
||||
return Integer.parseInt(charge);
|
||||
|
@ -210,14 +210,14 @@ public class EnergyNet extends Network {
|
||||
SlimefunItem item = (SlimefunItem) provider;
|
||||
|
||||
try {
|
||||
Config config = BlockStorage.getLocationInfo(loc);
|
||||
int energy = provider.getGeneratedOutput(loc, config);
|
||||
Config data = BlockStorage.getLocationInfo(loc);
|
||||
int energy = provider.getGeneratedOutput(loc, data);
|
||||
|
||||
if (provider.isChargeable()) {
|
||||
energy += provider.getCharge(loc);
|
||||
energy += provider.getCharge(loc, data);
|
||||
}
|
||||
|
||||
if (provider.willExplode(loc, config)) {
|
||||
if (provider.willExplode(loc, data)) {
|
||||
explodedBlocks.add(loc);
|
||||
BlockStorage.clearBlockInfo(loc);
|
||||
|
||||
@ -228,9 +228,9 @@ public class EnergyNet extends Network {
|
||||
} else {
|
||||
supply += energy;
|
||||
}
|
||||
} catch (Exception | LinkageError t) {
|
||||
} catch (Exception | LinkageError throwable) {
|
||||
explodedBlocks.add(loc);
|
||||
new ErrorReport<>(t, loc, item);
|
||||
new ErrorReport<>(throwable, loc, item);
|
||||
}
|
||||
|
||||
long time = SlimefunPlugin.getProfiler().closeEntry(loc, item, timestamp);
|
||||
|
@ -93,25 +93,31 @@ public class BlockDataService implements Keyed {
|
||||
*
|
||||
* @param b
|
||||
* The {@link Block} to retrieve data from
|
||||
*
|
||||
* @return The stored value
|
||||
*/
|
||||
public Optional<String> getBlockData(@Nonnull Block b) {
|
||||
Validate.notNull(b, "The block cannot be null!");
|
||||
|
||||
/**
|
||||
* Don't use PaperLib here, it seems to be quite buggy in block-placing scenarios
|
||||
* and it would be too tedious to check for individual build versions to circumvent this.
|
||||
*/
|
||||
BlockState state = b.getState();
|
||||
BlockState state = PaperLib.getBlockState(b, false).getState();
|
||||
PersistentDataContainer container = getPersistentDataContainer(state);
|
||||
|
||||
if (state instanceof TileState) {
|
||||
PersistentDataContainer container = ((TileState) state).getPersistentDataContainer();
|
||||
if (container != null) {
|
||||
return Optional.ofNullable(container.get(namespacedKey, PersistentDataType.STRING));
|
||||
} else {
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PersistentDataContainer getPersistentDataContainer(@Nonnull BlockState state) {
|
||||
if (state instanceof TileState) {
|
||||
return ((TileState) state).getPersistentDataContainer();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method checks whether the given {@link Material} is a Tile Entity.
|
||||
* This is used to determine whether the {@link Block} produced by this {@link Material}
|
||||
|
@ -39,10 +39,14 @@ class GitHubTask implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
gitHubService.getConnectors().forEach(GitHubConnector::download);
|
||||
connectAndCache();
|
||||
grabTextures();
|
||||
}
|
||||
|
||||
private void connectAndCache() {
|
||||
gitHubService.getConnectors().forEach(GitHubConnector::download);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will pull the skin textures for every {@link Contributor} and store
|
||||
* the {@link UUID} and received skin inside a local cache {@link File}.
|
||||
|
@ -42,11 +42,14 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
*/
|
||||
public class SlimefunProfiler {
|
||||
|
||||
// A minecraft server tick is 50ms and Slimefun ticks are stretched across
|
||||
// two ticks (sync and async blocks), so we use 100ms as a reference here
|
||||
/**
|
||||
* A minecraft server tick is 50ms and Slimefun ticks are stretched
|
||||
* across two ticks (sync and async blocks), so we use 100ms as a reference here
|
||||
*/
|
||||
private static final int MAX_TICK_DURATION = 100;
|
||||
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(5);
|
||||
private final SlimefunThreadFactory threadFactory = new SlimefunThreadFactory(5);
|
||||
private final ExecutorService executor = Executors.newFixedThreadPool(threadFactory.getThreadCount(), threadFactory);
|
||||
private final AtomicBoolean running = new AtomicBoolean(false);
|
||||
private final AtomicInteger queued = new AtomicInteger(0);
|
||||
|
||||
@ -117,7 +120,7 @@ public class SlimefunProfiler {
|
||||
|
||||
long elapsedTime = System.nanoTime() - timestamp;
|
||||
|
||||
executor.execute(() -> {
|
||||
executor.submit(() -> {
|
||||
ProfiledBlock block = new ProfiledBlock(l, item);
|
||||
|
||||
// Merge (if we have multiple samples for whatever reason)
|
||||
@ -162,6 +165,7 @@ public class SlimefunProfiler {
|
||||
iterator.next().sendMessage("Your timings report has timed out, we were still waiting for " + queued.get() + " samples to be collected :/");
|
||||
iterator.remove();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
|
@ -0,0 +1,32 @@
|
||||
package io.github.thebusybiscuit.slimefun4.core.services.profiler;
|
||||
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
/**
|
||||
* This is our {@link ThreadFactory} for the {@link SlimefunProfiler}.
|
||||
* It holds the amount of {@link Thread Threads} we dedicate towards our {@link SlimefunProfiler}
|
||||
* and provides a naming convention for our {@link Thread Threads}.
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
* @see SlimefunProfiler
|
||||
*
|
||||
*/
|
||||
final class SlimefunThreadFactory implements ThreadFactory {
|
||||
|
||||
private final int threadCount;
|
||||
|
||||
SlimefunThreadFactory(int threadCount) {
|
||||
this.threadCount = threadCount;
|
||||
}
|
||||
|
||||
int getThreadCount() {
|
||||
return threadCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable runnable) {
|
||||
return new Thread(runnable, "Slimefun Profiler");
|
||||
}
|
||||
|
||||
}
|
@ -183,7 +183,7 @@ public abstract class AbstractEntityAssembler<T extends Entity> extends SimpleSl
|
||||
return;
|
||||
}
|
||||
|
||||
if (lifetime % 60 == 0 && getCharge(b.getLocation()) >= getEnergyConsumption()) {
|
||||
if (lifetime % 60 == 0 && getCharge(b.getLocation(), data) >= getEnergyConsumption()) {
|
||||
BlockMenu menu = BlockStorage.getInventory(b);
|
||||
|
||||
boolean hasBody = findResource(menu, getBody(), bodySlots);
|
||||
|
@ -60,7 +60,7 @@ public abstract class GPSTransmitter extends SimpleSlimefunItem<BlockTicker> imp
|
||||
|
||||
@Override
|
||||
public void tick(Block b, SlimefunItem item, Config data) {
|
||||
int charge = getCharge(b.getLocation());
|
||||
int charge = getCharge(b.getLocation(), data);
|
||||
UUID owner = UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"));
|
||||
|
||||
if (charge >= getEnergyConsumption()) {
|
||||
|
@ -26,8 +26,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.armor.SlimefunArmorPiece;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.SolarHelmet;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||
import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem;
|
||||
import me.mrCookieSlime.Slimefun.api.Slimefun;
|
||||
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
|
||||
|
||||
/**
|
||||
* The {@link ArmorTask} is responsible for handling {@link PotionEffect PotionEffects} for
|
||||
@ -167,8 +169,16 @@ public class ArmorTask implements Runnable {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (SlimefunItem radioactiveItem : SlimefunPlugin.getRegistry().getRadioactiveItems()) {
|
||||
if (radioactiveItem.isItem(item) && Slimefun.isEnabled(p, radioactiveItem, true)) {
|
||||
Set<SlimefunItem> radioactiveItems = SlimefunPlugin.getRegistry().getRadioactiveItems();
|
||||
ItemStack subject = item;
|
||||
|
||||
if (!(item instanceof SlimefunItemStack) && radioactiveItems.size() > 1) {
|
||||
// Performance optimization to reduce ItemMeta calls
|
||||
subject = new ItemStackWrapper(item);
|
||||
}
|
||||
|
||||
for (SlimefunItem radioactiveItem : radioactiveItems) {
|
||||
if (radioactiveItem.isItem(subject) && Slimefun.isEnabled(p, radioactiveItem, true)) {
|
||||
// If the item is enabled in the world, then make radioactivity do its job
|
||||
SlimefunPlugin.getLocalization().sendMessage(p, "messages.radiation");
|
||||
|
||||
|
@ -0,0 +1,51 @@
|
||||
package io.github.thebusybiscuit.slimefun4.implementation.tasks;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.skull.SkullBlock;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.HeadTexture;
|
||||
|
||||
/**
|
||||
* This task is run whenever a {@link Capacitor} needs to update their texture.
|
||||
* <strong>This must be executed on the main {@link Server} {@link Thread}!</strong>
|
||||
*
|
||||
* @author TheBusyBiscuit
|
||||
*
|
||||
*/
|
||||
public class CapacitorTextureUpdateTask implements Runnable {
|
||||
|
||||
private final Location l;
|
||||
private final double filledPercentage;
|
||||
|
||||
public CapacitorTextureUpdateTask(@Nonnull Location l, double charge, double capacity) {
|
||||
Validate.notNull(l, "The Location cannot be null");
|
||||
|
||||
this.l = l;
|
||||
this.filledPercentage = charge / capacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Block b = l.getBlock();
|
||||
|
||||
if (b.getType() == Material.PLAYER_HEAD || b.getType() == Material.PLAYER_WALL_HEAD) {
|
||||
if (filledPercentage <= 0.25) {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_25.getTexture());
|
||||
} else if (filledPercentage <= 0.5) {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_50.getTexture());
|
||||
} else if (filledPercentage <= 0.75) {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_75.getTexture());
|
||||
} else {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_100.getTexture());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -14,7 +14,6 @@ import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Item;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -24,7 +23,6 @@ import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.item.ImmutableItemMeta;
|
||||
import io.github.thebusybiscuit.cscorelib2.skull.SkullBlock;
|
||||
import io.github.thebusybiscuit.cscorelib2.skull.SkullItem;
|
||||
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
|
||||
import io.github.thebusybiscuit.slimefun4.api.exceptions.PrematureCodeException;
|
||||
@ -32,6 +30,7 @@ import io.github.thebusybiscuit.slimefun4.core.attributes.Radioactive;
|
||||
import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.tasks.CapacitorTextureUpdateTask;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper;
|
||||
import me.mrCookieSlime.EmeraldEnchants.EmeraldEnchants;
|
||||
import me.mrCookieSlime.EmeraldEnchants.ItemEnchantment;
|
||||
@ -337,23 +336,7 @@ public final class SlimefunUtils {
|
||||
Validate.notNull(l, "Cannot update a texture for null");
|
||||
Validate.isTrue(capacity > 0, "Capacity must be greater than zero!");
|
||||
|
||||
SlimefunPlugin.runSync(() -> {
|
||||
Block b = l.getBlock();
|
||||
|
||||
if (b.getType() == Material.PLAYER_HEAD || b.getType() == Material.PLAYER_WALL_HEAD) {
|
||||
double level = (double) charge / capacity;
|
||||
|
||||
if (level <= 0.25) {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_25.getTexture());
|
||||
} else if (level <= 0.5) {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_50.getTexture());
|
||||
} else if (level <= 0.75) {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_75.getTexture());
|
||||
} else {
|
||||
SkullBlock.setFromHash(b, HeadTexture.CAPACITOR_100.getTexture());
|
||||
}
|
||||
}
|
||||
});
|
||||
SlimefunPlugin.runSync(new CapacitorTextureUpdateTask(l, charge, capacity));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -384,11 +384,13 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock,
|
||||
Validate.notNull(l, "Can't attempt to take charge from a null location!");
|
||||
|
||||
if (isChargeable()) {
|
||||
if (getCharge(l) < getEnergyConsumption()) {
|
||||
int charge = getCharge(l);
|
||||
|
||||
if (charge < getEnergyConsumption()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
removeCharge(l, getEnergyConsumption());
|
||||
setCharge(l, charge - getEnergyConsumption());
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
|
@ -152,7 +152,7 @@ public abstract class AGenerator extends AbstractEnergyProvider {
|
||||
ChestMenuUtils.updateProgressbar(inv, 22, timeleft, processing.get(l).getTicks(), getProgressBar());
|
||||
|
||||
if (isChargeable()) {
|
||||
int charge = getCharge(l);
|
||||
int charge = getCharge(l, data);
|
||||
|
||||
if (getCapacity() - charge >= getEnergyProduction()) {
|
||||
progress.put(l, timeleft - 1);
|
||||
|
@ -33,7 +33,6 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import io.github.thebusybiscuit.cscorelib2.blocks.BlockPosition;
|
||||
import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler;
|
||||
import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin;
|
||||
import io.github.thebusybiscuit.slimefun4.utils.PatternUtils;
|
||||
@ -677,19 +676,20 @@ public class BlockStorage {
|
||||
}
|
||||
}
|
||||
|
||||
public static SlimefunItem check(Block block) {
|
||||
return check(block.getLocation());
|
||||
@Nullable
|
||||
public static SlimefunItem check(@Nonnull Block b) {
|
||||
String id = checkID(b);
|
||||
return id == null ? null : SlimefunItem.getByID(id);
|
||||
}
|
||||
|
||||
public static SlimefunItem check(Location l) {
|
||||
if (!hasBlockInfo(l)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return SlimefunItem.getByID(getLocationInfo(l, "id"));
|
||||
@Nullable
|
||||
public static SlimefunItem check(@Nonnull Location l) {
|
||||
String id = checkID(l);
|
||||
return id == null ? null : SlimefunItem.getByID(id);
|
||||
}
|
||||
|
||||
public static String checkID(Block b) {
|
||||
@Nullable
|
||||
public static String checkID(@Nonnull Block b) {
|
||||
if (SlimefunPlugin.getBlockDataService().isTileEntity(b.getType())) {
|
||||
Optional<String> blockData = SlimefunPlugin.getBlockDataService().getBlockData(b);
|
||||
|
||||
@ -714,18 +714,13 @@ public class BlockStorage {
|
||||
return getLocationInfo(l, "id");
|
||||
}
|
||||
|
||||
public static boolean check(Location l, String slimefunItem) {
|
||||
if (slimefunItem == null || !hasBlockInfo(l)) {
|
||||
public static boolean check(@Nonnull Location l, @Nullable String slimefunItem) {
|
||||
if (slimefunItem == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
String id = getLocationInfo(l, "id");
|
||||
return id != null && id.equalsIgnoreCase(slimefunItem);
|
||||
} catch (Exception x) {
|
||||
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Exception occurred while checking " + new BlockPosition(l) + " for: \"" + slimefunItem + "\"");
|
||||
return false;
|
||||
}
|
||||
String id = checkID(l);
|
||||
return id != null && id.equals(slimefunItem);
|
||||
}
|
||||
|
||||
public static boolean isWorldRegistered(String name) {
|
||||
|
@ -91,12 +91,14 @@ public class DirtyChestMenu extends ChestMenu {
|
||||
}
|
||||
|
||||
public boolean fits(@Nonnull ItemStack item, int... slots) {
|
||||
if (getItemInSlot(slots[0]) == null) {
|
||||
// Very small optimization
|
||||
return true;
|
||||
} else {
|
||||
return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots);
|
||||
for (int slot : slots) {
|
||||
// A small optimization for empty slots
|
||||
if (getItemInSlot(slot) == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
Loading…
Reference in New Issue
Block a user