From 60d01fab11dc2c520f5bdc0efe8201e1969912d5 Mon Sep 17 00:00:00 2001 From: themode Date: Thu, 12 Nov 2020 00:56:36 +0100 Subject: [PATCH] Fix main loop sleep --- .../net/minestom/server/MinecraftServer.java | 4 +-- .../net/minestom/server/UpdateManager.java | 7 ++-- .../instance/palette/PaletteStorage.java | 35 ++++++++++++------- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/src/main/java/net/minestom/server/MinecraftServer.java b/src/main/java/net/minestom/server/MinecraftServer.java index 2fe64734a..e83cc9559 100644 --- a/src/main/java/net/minestom/server/MinecraftServer.java +++ b/src/main/java/net/minestom/server/MinecraftServer.java @@ -239,8 +239,7 @@ public final class MinecraftServer { * @param brandName the server brand name * @throws NullPointerException if {@code brandName} is null */ - @NotNull - public static void setBrandName(String brandName) { + public static void setBrandName(@NotNull String brandName) { Check.notNull(brandName, "The brand name cannot be null"); MinecraftServer.brandName = brandName; @@ -281,7 +280,6 @@ public final class MinecraftServer { * * @param difficulty the new server difficulty */ - @NotNull public static void setDifficulty(@NotNull Difficulty difficulty) { Check.notNull(difficulty, "The server difficulty cannot be null."); MinecraftServer.difficulty = difficulty; diff --git a/src/main/java/net/minestom/server/UpdateManager.java b/src/main/java/net/minestom/server/UpdateManager.java index 037c0d2ff..08e7e1237 100644 --- a/src/main/java/net/minestom/server/UpdateManager.java +++ b/src/main/java/net/minestom/server/UpdateManager.java @@ -67,11 +67,14 @@ public final class UpdateManager { // Server tick (chunks/entities) serverTick(tickStart); + // the time that the tick took in nanoseconds + final long tickTime = System.nanoTime() - currentTime; + // Tick end callbacks - doTickCallback(tickEndCallbacks, (System.nanoTime() - currentTime) / 1000000); + doTickCallback(tickEndCallbacks, tickTime / 1000000); // Sleep until next tick - final long sleepTime = Math.max(1, (tickDistance - (System.nanoTime() - currentTime)) / 1000000); + final long sleepTime = Math.max(1, (tickDistance - tickTime) / 1000000); try { Thread.sleep(sleepTime); diff --git a/src/main/java/net/minestom/server/instance/palette/PaletteStorage.java b/src/main/java/net/minestom/server/instance/palette/PaletteStorage.java index 4e46c5905..c2ae1b649 100644 --- a/src/main/java/net/minestom/server/instance/palette/PaletteStorage.java +++ b/src/main/java/net/minestom/server/instance/palette/PaletteStorage.java @@ -5,6 +5,8 @@ import it.unimi.dsi.fastutil.shorts.Short2ShortOpenHashMap; import net.minestom.server.instance.Chunk; import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.chunk.ChunkUtils; +import net.minestom.server.utils.validate.Check; +import org.jetbrains.annotations.NotNull; import static net.minestom.server.instance.Chunk.CHUNK_SECTION_COUNT; import static net.minestom.server.instance.Chunk.CHUNK_SECTION_SIZE; @@ -22,7 +24,7 @@ public class PaletteStorage { private final static int BLOCK_COUNT = CHUNK_SECTION_SIZE * CHUNK_SECTION_SIZE * CHUNK_SECTION_SIZE; private int bitsPerEntry; - private int bitsIncrement; + private final int bitsIncrement; private int valuesPerLong; private boolean hasPalette; @@ -41,10 +43,11 @@ public class PaletteStorage { } public PaletteStorage(int bitsPerEntry, int bitsIncrement) { + Check.argCondition(bitsPerEntry > MAXIMUM_BITS_PER_ENTRY, "The maximum bits per entry is 15"); // Change the bitsPerEntry to be valid if (bitsPerEntry < 4) { bitsPerEntry = 4; - } else if (MathUtils.isBetween(bitsPerEntry, 9, 14) || bitsPerEntry > MAXIMUM_BITS_PER_ENTRY) { + } else if (MathUtils.isBetween(bitsPerEntry, 9, 14)) { bitsPerEntry = MAXIMUM_BITS_PER_ENTRY; } @@ -171,7 +174,14 @@ public class PaletteStorage { return 1 << bitsPerEntry; } - private static void setBlockAt(PaletteStorage paletteStorage, int x, int y, int z, short blockId) { + // Magic values generated with "Integer.MAX_VALUE >> (31 - bitsPerIndex)" for bitsPerIndex between 4 and 15 + private static final int[] MAGIC_MASKS = + {0, 0, 0, 0, + 15, 31, 63, 127, 255, + 511, 1023, 2047, 4095, + 8191, 16383, 32767}; + + private static void setBlockAt(@NotNull PaletteStorage paletteStorage, int x, int y, int z, short blockId) { x = toChunkCoordinate(x); z = toChunkCoordinate(z); @@ -190,28 +200,29 @@ public class PaletteStorage { if (paletteStorage.sectionBlocks[section].length == 0) { if (blockId == 0) { + // Section is empty and method is trying to place an air block, stop unnecessary computation return; } + // Initialize the section paletteStorage.sectionBlocks[section] = new long[getSize(valuesPerLong)]; } - long[] sectionBlock = paletteStorage.sectionBlocks[section]; + final long[] sectionBlock = paletteStorage.sectionBlocks[section]; long block = sectionBlock[index]; { - final long clear = Integer.MAX_VALUE >> (31 - bitsPerEntry); + final long clear = MAGIC_MASKS[bitsPerEntry]; block |= clear << bitIndex; block ^= clear << bitIndex; block |= (long) blockId << bitIndex; sectionBlock[index] = block; - } } - private static short getBlockAt(PaletteStorage paletteStorage, int x, int y, int z) { + private static short getBlockAt(@NotNull PaletteStorage paletteStorage, int x, int y, int z) { x = toChunkCoordinate(x); z = toChunkCoordinate(z); @@ -228,18 +239,16 @@ public class PaletteStorage { final long[] blocks = paletteStorage.sectionBlocks[section]; if (blocks.length == 0) { + // Section is not loaded, can only be air return 0; } - long mask = Integer.MAX_VALUE >> (31 - bitsPerEntry); - long value = blocks[index] >> bitIndex & mask; + final long value = blocks[index] >> bitIndex & MAGIC_MASKS[bitsPerEntry]; - // Change to palette value - final short blockId = paletteStorage.hasPalette ? + // Change to palette value and return + return paletteStorage.hasPalette ? paletteStorage.paletteBlockMap.get((short) value) : (short) value; - - return blockId; } private static int getSize(int valuesPerLong) {