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

Improvements to block ticking

This commit is contained in:
TheBusyBiscuit 2020-09-29 20:38:41 +02:00
parent e7097e2c2b
commit 20de967306
5 changed files with 53 additions and 57 deletions

View File

@ -32,6 +32,7 @@
#### Changes
* Improved Auto-Updater (Multi-Threading and more)
* General performance improvements
#### Fixes
* Fixed #2300

View File

@ -11,7 +11,6 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
@ -70,7 +69,6 @@ public class SlimefunRegistry {
private final Set<String> tickers = new HashSet<>();
private final Set<SlimefunItem> radioactive = new HashSet<>();
private final Set<String> activeChunks = ConcurrentHashMap.newKeySet();
private final Set<ItemStack> barterDrops = new HashSet<>();
private final KeyMap<GEOResource> geoResources = new KeyMap<>();
@ -86,8 +84,6 @@ public class SlimefunRegistry {
private final Map<Class<? extends ItemHandler>, Set<ItemHandler>> globalItemHandlers = new HashMap<>();
private final Map<String, SlimefunBlockHandler> blockHandlers = new HashMap<>();
private final Map<String, Set<Location>> activeTickers = new ConcurrentHashMap<>();
private final Map<String, ItemStack> automatedCraftingChamberRecipes = new HashMap<>();
public void load(Config cfg) {
@ -226,10 +222,6 @@ public class SlimefunRegistry {
return tickers;
}
public Set<String> getActiveChunks() {
return activeChunks;
}
public Map<String, SlimefunItem> getSlimefunItemIds() {
return slimefunIds;
}
@ -262,10 +254,6 @@ public class SlimefunRegistry {
return chunks;
}
public Map<String, Set<Location>> getActiveTickers() {
return activeTickers;
}
public KeyMap<GEOResource> getGEOResources() {
return geoResources;
}

View File

@ -7,6 +7,8 @@ import java.util.Optional;
import java.util.function.Predicate;
import java.util.logging.Level;
import javax.annotation.ParametersAreNonnullByDefault;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.Location;
@ -220,6 +222,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
});
}
@ParametersAreNonnullByDefault
public void openScript(Player p, Block b, String sourceCode) {
ChestMenu menu = new ChestMenu(ChatColor.DARK_AQUA + SlimefunPlugin.getLocalization().getMessage(p, "android.scripts.editor"));
menu.setEmptySlotsClickable(false);
@ -290,6 +293,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock,
menu.open(p);
}
@ParametersAreNonnullByDefault
private String addInstruction(String[] script, int index, Instruction instruction) {
int i = 0;
StringBuilder builder = new StringBuilder(Instruction.START.name() + '-');

View File

@ -38,6 +38,9 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class TickerTask implements Runnable {
// This Map holds all currently actively ticking locations
private final Map<String, Set<Location>> activeTickers = new ConcurrentHashMap<>();
// These are "Queues" of blocks that need to be removed or moved
private final Map<Location, Location> movingQueue = new ConcurrentHashMap<>();
private final Map<Location, Boolean> deletionQueue = new ConcurrentHashMap<>();
@ -90,8 +93,8 @@ public class TickerTask implements Runnable {
}
if (!halted) {
for (String chunk : BlockStorage.getTickingChunks()) {
tickChunk(tickers, chunk);
for (Map.Entry<String, Set<Location>> entry : activeTickers.entrySet()) {
tickChunk(tickers, entry.getKey(), entry.getValue());
}
}
@ -116,9 +119,9 @@ public class TickerTask implements Runnable {
}
}
private void tickChunk(@Nonnull Set<BlockTicker> tickers, @Nonnull String chunk) {
@ParametersAreNonnullByDefault
private void tickChunk(Set<BlockTicker> tickers, String chunk, Set<Location> locations) {
try {
Set<Location> locations = BlockStorage.getTickingLocations(chunk);
String[] components = PatternUtils.SEMICOLON.split(chunk);
World world = Bukkit.getWorld(components[0]);
@ -223,13 +226,24 @@ public class TickerTask implements Runnable {
deletionQueue.put(l, destroy);
}
/**
* This returns the delay between ticks
*
* @return The tick delay
*/
public int getTickRate() {
return tickRate;
}
@Override
public String toString() {
return "TickerTask {\n" + " HALTED = " + halted + "\n" + " move = " + movingQueue + "\n" + " delete = " + deletionQueue + "}";
/**
* This method returns the {@link Map} of actively ticking locations according to
* their chunk id.
*
* @return The {@link Map} of active tickers
*/
@Nonnull
public Map<String, Set<Location>> getActiveTickers() {
return activeTickers;
}
}

View File

@ -15,6 +15,10 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@ -56,11 +60,11 @@ public class BlockStorage {
private static int chunkChanges = 0;
private int changes = 0;
public static BlockStorage getStorage(World world) {
public static BlockStorage getStorage(@Nonnull World world) {
return SlimefunPlugin.getRegistry().getWorlds().get(world.getName());
}
public static BlockStorage getForcedStorage(World world) {
public static BlockStorage getForcedStorage(@Nonnull World world) {
return isWorldRegistered(world.getName()) ? SlimefunPlugin.getRegistry().getWorlds().get(world.getName()) : new BlockStorage(world);
}
@ -196,13 +200,9 @@ public class BlockStorage {
storage.put(l, blockInfo);
if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunkString, new HashSet<>());
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>());
locations.add(l);
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
if (!SlimefunPlugin.getRegistry().getActiveChunks().contains(chunkString)) {
SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString);
}
}
}
}
@ -377,22 +377,22 @@ public class BlockStorage {
/**
* Retrieves the SlimefunItem's ItemStack from the specified Block.
* If the specified Block is registered in BlockStorage, its data will be erased from it, regardless of the returned
* value.
* If the specified Block is registered in BlockStorage,
* its data will be erased from it, regardless of the returned value.
*
* @param block
* the block to retrieve the ItemStack from
*
* @return the SlimefunItem's ItemStack corresponding to the block if it has one, otherwise null
*
* @since 4.0
*/
@Nullable
public static ItemStack retrieve(Block block) {
if (!hasBlockInfo(block)) {
return null;
}
else {
SlimefunItem item = SlimefunItem.getByID(getLocationInfo(block.getLocation(), "id"));
String id = getLocationInfo(block.getLocation(), "id");
SlimefunItem item = SlimefunItem.getByID(id);
clearBlockInfo(block);
if (item == null) {
@ -404,6 +404,7 @@ public class BlockStorage {
}
}
@Nonnull
public static Config getLocationInfo(Location l) {
BlockStorage storage = getStorage(l.getWorld());
@ -415,6 +416,7 @@ public class BlockStorage {
return cfg == null ? emptyBlockData : cfg;
}
@Nonnull
private static Map<String, String> parseJSON(String json) {
Map<String, String> map = new HashMap<>();
@ -608,22 +610,20 @@ public class BlockStorage {
}
String chunkString = locationToChunkString(l);
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.get(chunkString);
if (SlimefunPlugin.getRegistry().getActiveTickers().containsKey(chunkString)) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().get(chunkString);
if (locations != null) {
locations.remove(l);
if (locations.isEmpty()) {
SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString);
SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString);
}
else {
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
tickers.remove(chunkString);
}
}
}
}
@ParametersAreNonnullByDefault
public static void moveBlockInfo(Location from, Location to) {
SlimefunPlugin.getTickerTask().queueMove(from, to);
}
@ -637,6 +637,7 @@ public class BlockStorage {
* @param to
* The destination {@link Location}
*/
@ParametersAreNonnullByDefault
public static void moveLocationInfoUnsafely(Location from, Location to) {
if (!hasBlockInfo(from)) {
return;
@ -657,17 +658,14 @@ public class BlockStorage {
storage.storage.remove(from);
String chunkString = locationToChunkString(from);
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.get(chunkString);
if (SlimefunPlugin.getRegistry().getActiveTickers().containsKey(chunkString)) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().get(chunkString);
if (locations != null) {
locations.remove(from);
if (locations.isEmpty()) {
SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString);
SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString);
}
else {
SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations);
tickers.remove(chunkString);
}
}
}
@ -689,10 +687,9 @@ public class BlockStorage {
String chunkString = locationToChunkString(l);
if (value != null) {
Set<Location> locations = SlimefunPlugin.getRegistry().getActiveTickers().computeIfAbsent(chunkString, c -> new HashSet<>());
Map<String, Set<Location>> tickers = SlimefunPlugin.getTickerTask().getActiveTickers();
Set<Location> locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>());
locations.add(l);
SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString);
}
}
}
@ -754,14 +751,6 @@ public class BlockStorage {
return SlimefunPlugin.getRegistry().getWorlds().containsKey(name);
}
public static Set<String> getTickingChunks() {
return SlimefunPlugin.getRegistry().getActiveChunks();
}
public static Set<Location> getTickingLocations(String chunk) {
return SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunk, new HashSet<>());
}
public BlockMenu loadInventory(Location l, BlockMenuPreset preset) {
if (preset == null) {
return null;