From 3ecace5bd62061ecf2371da7fca4f12ac3686827 Mon Sep 17 00:00:00 2001 From: themode Date: Thu, 11 Mar 2021 20:54:30 +0100 Subject: [PATCH] Introduce the Tickable interface --- .../java/net/minestom/server/Tickable.java | 7 +++++ .../net/minestom/server/entity/Entity.java | 4 ++- .../net/minestom/server/instance/Chunk.java | 30 ++++++++++++++----- .../server/instance/DynamicChunk.java | 15 +++++----- .../minestom/server/instance/Instance.java | 4 ++- .../server/instance/InstanceContainer.java | 6 ++-- .../instance/MinestomBasicChunkLoader.java | 2 +- .../server/thread/ThreadProvider.java | 2 +- .../server/utils/chunk/ChunkSupplier.java | 10 ++++--- 9 files changed, 53 insertions(+), 27 deletions(-) create mode 100644 src/main/java/net/minestom/server/Tickable.java diff --git a/src/main/java/net/minestom/server/Tickable.java b/src/main/java/net/minestom/server/Tickable.java new file mode 100644 index 000000000..a84b25c60 --- /dev/null +++ b/src/main/java/net/minestom/server/Tickable.java @@ -0,0 +1,7 @@ +package net.minestom.server; + +public interface Tickable { + + void tick(long time); + +} diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index aecc0b32f..0d47beb2b 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -2,6 +2,7 @@ package net.minestom.server.entity; import com.google.common.collect.Queues; import net.minestom.server.MinecraftServer; +import net.minestom.server.Tickable; import net.minestom.server.Viewable; import net.minestom.server.chat.JsonMessage; import net.minestom.server.collision.BoundingBox; @@ -52,7 +53,7 @@ import java.util.function.Consumer; *

* To create your own entity you probably want to extends {@link ObjectEntity} or {@link EntityCreature} instead. */ -public class Entity implements Viewable, EventHandler, DataContainer, PermissionHandler { +public class Entity implements Viewable, Tickable, EventHandler, DataContainer, PermissionHandler { private static final Map entityById = new ConcurrentHashMap<>(); private static final Map entityByUuid = new ConcurrentHashMap<>(); @@ -426,6 +427,7 @@ public class Entity implements Viewable, EventHandler, DataContainer, Permission * * @param time the update time in milliseconds */ + @Override public void tick(long time) { if (instance == null) return; diff --git a/src/main/java/net/minestom/server/instance/Chunk.java b/src/main/java/net/minestom/server/instance/Chunk.java index 736091c18..c660397e5 100644 --- a/src/main/java/net/minestom/server/instance/Chunk.java +++ b/src/main/java/net/minestom/server/instance/Chunk.java @@ -1,6 +1,7 @@ package net.minestom.server.instance; import net.minestom.server.MinecraftServer; +import net.minestom.server.Tickable; import net.minestom.server.Viewable; import net.minestom.server.data.Data; import net.minestom.server.data.DataContainer; @@ -50,7 +51,7 @@ import java.util.concurrent.CopyOnWriteArraySet; * You generally want to avoid storing references of this object as this could lead to a huge memory leak, * you should store the chunk coordinates instead. */ -public abstract class Chunk implements Viewable, DataContainer { +public abstract class Chunk implements Viewable, Tickable, DataContainer { protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); protected static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager(); @@ -66,6 +67,7 @@ public abstract class Chunk implements Viewable, DataContainer { private final UUID identifier; + protected Instance instance; @NotNull protected final Biome[] biomes; protected final int chunkX, chunkZ; @@ -84,8 +86,9 @@ public abstract class Chunk implements Viewable, DataContainer { // Data protected Data data; - public Chunk(@Nullable Biome[] biomes, int chunkX, int chunkZ, boolean shouldGenerate) { + public Chunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ, boolean shouldGenerate) { this.identifier = UUID.randomUUID(); + this.instance = instance; this.chunkX = chunkX; this.chunkZ = chunkZ; this.shouldGenerate = shouldGenerate; @@ -125,10 +128,10 @@ public abstract class Chunk implements Viewable, DataContainer { *

* WARNING: this method doesn't necessary have to be thread-safe, proceed with caution. * - * @param time the time of the update in milliseconds - * @param instance the {@link Instance} linked to this chunk + * @param time the time of the update in milliseconds */ - public abstract void tick(long time, @NotNull Instance instance); + @Override + public abstract void tick(long time); /** * Gets the block state id at a position. @@ -244,12 +247,13 @@ public abstract class Chunk implements Viewable, DataContainer { *

* The chunk position (X/Z) can be modified using the given arguments. * - * @param chunkX the chunk X of the copy - * @param chunkZ the chunk Z of the copy + * @param instance the chunk owner + * @param chunkX the chunk X of the copy + * @param chunkZ the chunk Z of the copy * @return a copy of this chunk with a potentially new instance and position */ @NotNull - public abstract Chunk copy(int chunkX, int chunkZ); + public abstract Chunk copy(@NotNull Instance instance, int chunkX, int chunkZ); /** * Resets the chunk, this means clearing all the data making it empty. @@ -298,6 +302,16 @@ public abstract class Chunk implements Viewable, DataContainer { return identifier; } + /** + * Gets the instance where this chunk is stored + * + * @return the linked instance + */ + @NotNull + public Instance getInstance() { + return instance; + } + public Biome[] getBiomes() { return biomes; } diff --git a/src/main/java/net/minestom/server/instance/DynamicChunk.java b/src/main/java/net/minestom/server/instance/DynamicChunk.java index a64fefdb1..20f595f1a 100644 --- a/src/main/java/net/minestom/server/instance/DynamicChunk.java +++ b/src/main/java/net/minestom/server/instance/DynamicChunk.java @@ -9,7 +9,6 @@ import net.minestom.server.data.Data; import net.minestom.server.data.SerializableData; import net.minestom.server.data.SerializableDataImpl; import net.minestom.server.entity.pathfinding.PFBlockDescription; -import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.CustomBlock; import net.minestom.server.instance.palette.PaletteStorage; import net.minestom.server.network.packet.server.play.ChunkDataPacket; @@ -60,15 +59,15 @@ public class DynamicChunk extends Chunk { private long lastChangeTime; - public DynamicChunk(@Nullable Biome[] biomes, int chunkX, int chunkZ, + public DynamicChunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ, @NotNull PaletteStorage blockPalette, @NotNull PaletteStorage customBlockPalette) { - super(biomes, chunkX, chunkZ, true); + super(instance, biomes, chunkX, chunkZ, true); this.blockPalette = blockPalette; this.customBlockPalette = customBlockPalette; } - public DynamicChunk(@Nullable Biome[] biomes, int chunkX, int chunkZ) { - this(biomes, chunkX, chunkZ, + public DynamicChunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ) { + this(instance, biomes, chunkX, chunkZ, new PaletteStorage(15, 2), new PaletteStorage(15, 2)); } @@ -129,7 +128,7 @@ public class DynamicChunk extends Chunk { } @Override - public void tick(long time, @NotNull Instance instance) { + public void tick(long time) { if (updatableBlocks.isEmpty()) return; @@ -397,8 +396,8 @@ public class DynamicChunk extends Chunk { @NotNull @Override - public Chunk copy(int chunkX, int chunkZ) { - DynamicChunk dynamicChunk = new DynamicChunk(biomes.clone(), chunkX, chunkZ); + public Chunk copy(@NotNull Instance instance, int chunkX, int chunkZ) { + DynamicChunk dynamicChunk = new DynamicChunk(instance, biomes.clone(), chunkX, chunkZ); dynamicChunk.blockPalette = blockPalette.clone(); dynamicChunk.customBlockPalette = customBlockPalette.clone(); dynamicChunk.blocksData.putAll(blocksData); diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index aaa2435ec..7938ec0b9 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import net.minestom.server.MinecraftServer; +import net.minestom.server.Tickable; import net.minestom.server.UpdateManager; import net.minestom.server.data.Data; import net.minestom.server.data.DataContainer; @@ -56,7 +57,7 @@ import java.util.function.Consumer; * you need to be sure to signal the {@link UpdateManager} of the changes using * {@link UpdateManager#signalChunkLoad(Instance, int, int)} and {@link UpdateManager#signalChunkUnload(Instance, int, int)}. */ -public abstract class Instance implements BlockModifier, EventHandler, DataContainer { +public abstract class Instance implements BlockModifier, Tickable, EventHandler, DataContainer { protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); protected static final UpdateManager UPDATE_MANAGER = MinecraftServer.getUpdateManager(); @@ -1034,6 +1035,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta * * @param time the tick time in milliseconds */ + @Override public void tick(long time) { // Scheduled tasks if (!nextTick.isEmpty()) { diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index f2363a388..06e119f26 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -542,7 +542,7 @@ public class InstanceContainer extends Instance { chunkGenerator.fillBiomes(biomes, chunkX, chunkZ); } - final Chunk chunk = chunkSupplier.createChunk(biomes, chunkX, chunkZ); + final Chunk chunk = chunkSupplier.createChunk(this, biomes, chunkX, chunkZ); Check.notNull(chunk, "Chunks supplied by a ChunkSupplier cannot be null."); cacheChunk(chunk); @@ -636,7 +636,7 @@ public class InstanceContainer extends Instance { /** * Copies all the chunks of this instance and create a new instance container with all of them. *

- * Chunks are copied with {@link Chunk#copy(int, int)}, + * Chunks are copied with {@link Chunk#copy(Instance, int, int)}, * {@link UUID} is randomized, {@link DimensionType} is passed over and the {@link StorageLocation} is null. * * @return an {@link InstanceContainer} with the exact same chunks as 'this' @@ -651,7 +651,7 @@ public class InstanceContainer extends Instance { final int chunkX = chunk.getChunkX(); final int chunkZ = chunk.getChunkZ(); - final Chunk copiedChunk = chunk.copy(chunkX, chunkZ); + final Chunk copiedChunk = chunk.copy(copiedInstance, chunkX, chunkZ); copiedInstance.cacheChunk(copiedChunk); UPDATE_MANAGER.signalChunkLoad(copiedInstance, chunkX, chunkZ); diff --git a/src/main/java/net/minestom/server/instance/MinestomBasicChunkLoader.java b/src/main/java/net/minestom/server/instance/MinestomBasicChunkLoader.java index 2469eb14b..b7beec13d 100644 --- a/src/main/java/net/minestom/server/instance/MinestomBasicChunkLoader.java +++ b/src/main/java/net/minestom/server/instance/MinestomBasicChunkLoader.java @@ -77,7 +77,7 @@ public class MinestomBasicChunkLoader implements IChunkLoader { // Found, load from result bytes BinaryReader reader = new BinaryReader(bytes); // Create the chunk object using the instance's ChunkSupplier to support multiple implementations - Chunk chunk = instanceContainer.getChunkSupplier().createChunk(null, chunkX, chunkZ); + Chunk chunk = instanceContainer.getChunkSupplier().createChunk(instance, null, chunkX, chunkZ); // Execute the callback once all blocks are placed (allow for multithreaded implementations) chunk.readChunk(reader, callback); return true; diff --git a/src/main/java/net/minestom/server/thread/ThreadProvider.java b/src/main/java/net/minestom/server/thread/ThreadProvider.java index 7ed136228..0d8b0d881 100644 --- a/src/main/java/net/minestom/server/thread/ThreadProvider.java +++ b/src/main/java/net/minestom/server/thread/ThreadProvider.java @@ -151,7 +151,7 @@ public abstract class ThreadProvider { * @param time the current time in ms */ protected void updateChunk(@NotNull Instance instance, @NotNull Chunk chunk, long time) { - chunk.tick(time, instance); + chunk.tick(time); } // ENTITY UPDATE diff --git a/src/main/java/net/minestom/server/utils/chunk/ChunkSupplier.java b/src/main/java/net/minestom/server/utils/chunk/ChunkSupplier.java index 1c33308be..546bc9afc 100644 --- a/src/main/java/net/minestom/server/utils/chunk/ChunkSupplier.java +++ b/src/main/java/net/minestom/server/utils/chunk/ChunkSupplier.java @@ -1,6 +1,7 @@ package net.minestom.server.utils.chunk; import net.minestom.server.instance.Chunk; +import net.minestom.server.instance.Instance; import net.minestom.server.world.biomes.Biome; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -14,11 +15,12 @@ public interface ChunkSupplier { /** * Creates a {@link Chunk} object. * - * @param biomes the biomes of the chunk, can be null - * @param chunkX the chunk X - * @param chunkZ the chunk Z + * @param instance the linked instance + * @param biomes the biomes of the chunk, can be null + * @param chunkX the chunk X + * @param chunkZ the chunk Z * @return a newly {@link Chunk} object, cannot be null */ @NotNull - Chunk createChunk(@Nullable Biome[] biomes, int chunkX, int chunkZ); + Chunk createChunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ); }