Introduce the Tickable interface

This commit is contained in:
themode 2021-03-11 20:54:30 +01:00
parent 68ef3e31af
commit 3ecace5bd6
9 changed files with 53 additions and 27 deletions

View File

@ -0,0 +1,7 @@
package net.minestom.server;
public interface Tickable {
void tick(long time);
}

View File

@ -2,6 +2,7 @@ package net.minestom.server.entity;
import com.google.common.collect.Queues; import com.google.common.collect.Queues;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.Tickable;
import net.minestom.server.Viewable; import net.minestom.server.Viewable;
import net.minestom.server.chat.JsonMessage; import net.minestom.server.chat.JsonMessage;
import net.minestom.server.collision.BoundingBox; import net.minestom.server.collision.BoundingBox;
@ -52,7 +53,7 @@ import java.util.function.Consumer;
* <p> * <p>
* To create your own entity you probably want to extends {@link ObjectEntity} or {@link EntityCreature} instead. * 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<Integer, Entity> entityById = new ConcurrentHashMap<>(); private static final Map<Integer, Entity> entityById = new ConcurrentHashMap<>();
private static final Map<UUID, Entity> entityByUuid = new ConcurrentHashMap<>(); private static final Map<UUID, Entity> entityByUuid = new ConcurrentHashMap<>();
@ -426,6 +427,7 @@ public class Entity implements Viewable, EventHandler, DataContainer, Permission
* *
* @param time the update time in milliseconds * @param time the update time in milliseconds
*/ */
@Override
public void tick(long time) { public void tick(long time) {
if (instance == null) if (instance == null)
return; return;

View File

@ -1,6 +1,7 @@
package net.minestom.server.instance; package net.minestom.server.instance;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.Tickable;
import net.minestom.server.Viewable; import net.minestom.server.Viewable;
import net.minestom.server.data.Data; import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer; 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 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. * 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 BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
protected static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager(); protected static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager();
@ -66,6 +67,7 @@ public abstract class Chunk implements Viewable, DataContainer {
private final UUID identifier; private final UUID identifier;
protected Instance instance;
@NotNull @NotNull
protected final Biome[] biomes; protected final Biome[] biomes;
protected final int chunkX, chunkZ; protected final int chunkX, chunkZ;
@ -84,8 +86,9 @@ public abstract class Chunk implements Viewable, DataContainer {
// Data // Data
protected Data 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.identifier = UUID.randomUUID();
this.instance = instance;
this.chunkX = chunkX; this.chunkX = chunkX;
this.chunkZ = chunkZ; this.chunkZ = chunkZ;
this.shouldGenerate = shouldGenerate; this.shouldGenerate = shouldGenerate;
@ -125,10 +128,10 @@ public abstract class Chunk implements Viewable, DataContainer {
* <p> * <p>
* WARNING: this method doesn't necessary have to be thread-safe, proceed with caution. * WARNING: this method doesn't necessary have to be thread-safe, proceed with caution.
* *
* @param time the time of the update in milliseconds * @param time the time of the update in milliseconds
* @param instance the {@link Instance} linked to this chunk
*/ */
public abstract void tick(long time, @NotNull Instance instance); @Override
public abstract void tick(long time);
/** /**
* Gets the block state id at a position. * Gets the block state id at a position.
@ -244,12 +247,13 @@ public abstract class Chunk implements Viewable, DataContainer {
* <p> * <p>
* The chunk position (X/Z) can be modified using the given arguments. * The chunk position (X/Z) can be modified using the given arguments.
* *
* @param chunkX the chunk X of the copy * @param instance the chunk owner
* @param chunkZ the chunk Z of the copy * @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 * @return a copy of this chunk with a potentially new instance and position
*/ */
@NotNull @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. * 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; return identifier;
} }
/**
* Gets the instance where this chunk is stored
*
* @return the linked instance
*/
@NotNull
public Instance getInstance() {
return instance;
}
public Biome[] getBiomes() { public Biome[] getBiomes() {
return biomes; return biomes;
} }

View File

@ -9,7 +9,6 @@ import net.minestom.server.data.Data;
import net.minestom.server.data.SerializableData; import net.minestom.server.data.SerializableData;
import net.minestom.server.data.SerializableDataImpl; import net.minestom.server.data.SerializableDataImpl;
import net.minestom.server.entity.pathfinding.PFBlockDescription; 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.block.CustomBlock;
import net.minestom.server.instance.palette.PaletteStorage; import net.minestom.server.instance.palette.PaletteStorage;
import net.minestom.server.network.packet.server.play.ChunkDataPacket; import net.minestom.server.network.packet.server.play.ChunkDataPacket;
@ -60,15 +59,15 @@ public class DynamicChunk extends Chunk {
private long lastChangeTime; 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) { @NotNull PaletteStorage blockPalette, @NotNull PaletteStorage customBlockPalette) {
super(biomes, chunkX, chunkZ, true); super(instance, biomes, chunkX, chunkZ, true);
this.blockPalette = blockPalette; this.blockPalette = blockPalette;
this.customBlockPalette = customBlockPalette; this.customBlockPalette = customBlockPalette;
} }
public DynamicChunk(@Nullable Biome[] biomes, int chunkX, int chunkZ) { public DynamicChunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ) {
this(biomes, chunkX, chunkZ, this(instance, biomes, chunkX, chunkZ,
new PaletteStorage(15, 2), new PaletteStorage(15, 2),
new PaletteStorage(15, 2)); new PaletteStorage(15, 2));
} }
@ -129,7 +128,7 @@ public class DynamicChunk extends Chunk {
} }
@Override @Override
public void tick(long time, @NotNull Instance instance) { public void tick(long time) {
if (updatableBlocks.isEmpty()) if (updatableBlocks.isEmpty())
return; return;
@ -397,8 +396,8 @@ public class DynamicChunk extends Chunk {
@NotNull @NotNull
@Override @Override
public Chunk copy(int chunkX, int chunkZ) { public Chunk copy(@NotNull Instance instance, int chunkX, int chunkZ) {
DynamicChunk dynamicChunk = new DynamicChunk(biomes.clone(), chunkX, chunkZ); DynamicChunk dynamicChunk = new DynamicChunk(instance, biomes.clone(), chunkX, chunkZ);
dynamicChunk.blockPalette = blockPalette.clone(); dynamicChunk.blockPalette = blockPalette.clone();
dynamicChunk.customBlockPalette = customBlockPalette.clone(); dynamicChunk.customBlockPalette = customBlockPalette.clone();
dynamicChunk.blocksData.putAll(blocksData); dynamicChunk.blocksData.putAll(blocksData);

View File

@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectMaps; import it.unimi.dsi.fastutil.longs.Long2ObjectMaps;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minestom.server.MinecraftServer; import net.minestom.server.MinecraftServer;
import net.minestom.server.Tickable;
import net.minestom.server.UpdateManager; import net.minestom.server.UpdateManager;
import net.minestom.server.data.Data; import net.minestom.server.data.Data;
import net.minestom.server.data.DataContainer; 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 * 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)}. * {@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 BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
protected static final UpdateManager UPDATE_MANAGER = MinecraftServer.getUpdateManager(); 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 * @param time the tick time in milliseconds
*/ */
@Override
public void tick(long time) { public void tick(long time) {
// Scheduled tasks // Scheduled tasks
if (!nextTick.isEmpty()) { if (!nextTick.isEmpty()) {

View File

@ -542,7 +542,7 @@ public class InstanceContainer extends Instance {
chunkGenerator.fillBiomes(biomes, chunkX, chunkZ); 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."); Check.notNull(chunk, "Chunks supplied by a ChunkSupplier cannot be null.");
cacheChunk(chunk); 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. * Copies all the chunks of this instance and create a new instance container with all of them.
* <p> * <p>
* 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. * {@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' * @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 chunkX = chunk.getChunkX();
final int chunkZ = chunk.getChunkZ(); final int chunkZ = chunk.getChunkZ();
final Chunk copiedChunk = chunk.copy(chunkX, chunkZ); final Chunk copiedChunk = chunk.copy(copiedInstance, chunkX, chunkZ);
copiedInstance.cacheChunk(copiedChunk); copiedInstance.cacheChunk(copiedChunk);
UPDATE_MANAGER.signalChunkLoad(copiedInstance, chunkX, chunkZ); UPDATE_MANAGER.signalChunkLoad(copiedInstance, chunkX, chunkZ);

View File

@ -77,7 +77,7 @@ public class MinestomBasicChunkLoader implements IChunkLoader {
// Found, load from result bytes // Found, load from result bytes
BinaryReader reader = new BinaryReader(bytes); BinaryReader reader = new BinaryReader(bytes);
// Create the chunk object using the instance's ChunkSupplier to support multiple implementations // 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) // Execute the callback once all blocks are placed (allow for multithreaded implementations)
chunk.readChunk(reader, callback); chunk.readChunk(reader, callback);
return true; return true;

View File

@ -151,7 +151,7 @@ public abstract class ThreadProvider {
* @param time the current time in ms * @param time the current time in ms
*/ */
protected void updateChunk(@NotNull Instance instance, @NotNull Chunk chunk, long time) { protected void updateChunk(@NotNull Instance instance, @NotNull Chunk chunk, long time) {
chunk.tick(time, instance); chunk.tick(time);
} }
// ENTITY UPDATE // ENTITY UPDATE

View File

@ -1,6 +1,7 @@
package net.minestom.server.utils.chunk; package net.minestom.server.utils.chunk;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance;
import net.minestom.server.world.biomes.Biome; import net.minestom.server.world.biomes.Biome;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -14,11 +15,12 @@ public interface ChunkSupplier {
/** /**
* Creates a {@link Chunk} object. * Creates a {@link Chunk} object.
* *
* @param biomes the biomes of the chunk, can be null * @param instance the linked instance
* @param chunkX the chunk X * @param biomes the biomes of the chunk, can be null
* @param chunkZ the chunk Z * @param chunkX the chunk X
* @param chunkZ the chunk Z
* @return a newly {@link Chunk} object, cannot be null * @return a newly {@link Chunk} object, cannot be null
*/ */
@NotNull @NotNull
Chunk createChunk(@Nullable Biome[] biomes, int chunkX, int chunkZ); Chunk createChunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ);
} }