More comments for the data API

This commit is contained in:
themode 2020-10-26 01:30:32 +01:00
parent 6a6e359529
commit e621069cc5
9 changed files with 63 additions and 32 deletions

View File

@ -60,7 +60,7 @@ public abstract class JsonMessage {
private JsonObject jsonObject; private JsonObject jsonObject;
public RawJsonMessage(JsonObject jsonObject) { public RawJsonMessage(@NotNull JsonObject jsonObject) {
this.jsonObject = jsonObject; this.jsonObject = jsonObject;
} }

View File

@ -5,7 +5,7 @@ import org.jetbrains.annotations.Nullable;
/** /**
* Represents an element which can have a {@link Data} attached to it. * Represents an element which can have a {@link Data} attached to it.
* <p> * <p>
* The data will always be optional. * The data will always be optional and can therefore be null.
*/ */
public interface DataContainer { public interface DataContainer {
@ -22,6 +22,9 @@ public interface DataContainer {
/** /**
* Sets the {@link Data} of this container. * Sets the {@link Data} of this container.
* <p>
* Default implementations are {@link DataImpl} and {@link SerializableDataImpl} depending
* on your use-case.
* *
* @param data the {@link Data} of this container, null to remove it * @param data the {@link Data} of this container, null to remove it
*/ */

View File

@ -14,6 +14,15 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
/**
* Manager used to register types which can be serialized and deserialized back.
* <p>
* Registering happens with {@link #registerType(Class, DataType)},
* you can then retrieve the {@link DataType} with {@link #getDataType(Class)}.
* <p>
* A lot of types are already registered by default so you do not have to add all of them manually,
* you can verify if {@link #getDataType(Class)} returns null for the desired type, if it is then you will need to register it.
*/
public final class DataManager { public final class DataManager {
private final Map<Class, DataType> dataTypeMap = new HashMap<>(); private final Map<Class, DataType> dataTypeMap = new HashMap<>();

View File

@ -16,6 +16,8 @@ public abstract class DataType<T> {
/** /**
* Encodes the data type. * Encodes the data type.
* <p>
* Be sure that the encoded value can be decoded back using {@link #decode(BinaryReader)}.
* *
* @param writer the data writer * @param writer the data writer
* @param value the value to encode * @param value the value to encode

View File

@ -59,7 +59,7 @@ public interface SerializableData extends Data {
/** /**
* Reads the index map and the data of a serialized {@link SerializableData}. * Reads the index map and the data of a serialized {@link SerializableData}.
* * <p>
* Got from {@link #getIndexedSerializedData()}. * Got from {@link #getIndexedSerializedData()}.
* *
* @param reader the binary reader * @param reader the binary reader
@ -74,7 +74,7 @@ public interface SerializableData extends Data {
* <p> * <p>
* Sized by a var-int. * Sized by a var-int.
* *
* @param typeToIndexMap the data index map * @param typeToIndexMap the filled data index map
*/ */
static void writeDataIndexHeader(@NotNull BinaryWriter indexWriter, @NotNull Object2ShortMap<String> typeToIndexMap) { static void writeDataIndexHeader(@NotNull BinaryWriter indexWriter, @NotNull Object2ShortMap<String> typeToIndexMap) {
// Write the size of the following index list (class name-> class index) // Write the size of the following index list (class name-> class index)

View File

@ -97,12 +97,12 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
private final PFInstanceSpace instanceSpace = new PFInstanceSpace(this); private final PFInstanceSpace instanceSpace = new PFInstanceSpace(this);
/** /**
* Creates a new instance * Creates a new instance.
* *
* @param uniqueId the {@link UUID} of the instance * @param uniqueId the {@link UUID} of the instance
* @param dimensionType the {@link DimensionType} of the instance * @param dimensionType the {@link DimensionType} of the instance
*/ */
public Instance(UUID uniqueId, DimensionType dimensionType) { public Instance(@NotNull UUID uniqueId, @NotNull DimensionType dimensionType) {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
this.dimensionType = dimensionType; this.dimensionType = dimensionType;
@ -110,12 +110,12 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
} }
/** /**
* Schedules a task to be run during the next instance tick * Schedules a task to be run during the next instance tick.
* It ensures that the task will be executed in the same thread as the instance and its chunks/entities (depending of the {@link ThreadProvider}) * It ensures that the task will be executed in the same thread as the instance and its chunks/entities (depending of the {@link ThreadProvider}).
* *
* @param callback the task to execute during the next instance tick * @param callback the task to execute during the next instance tick
*/ */
public void scheduleNextTick(Consumer<Instance> callback) { public void scheduleNextTick(@NotNull Consumer<Instance> callback) {
this.nextTick.add(callback); this.nextTick.add(callback);
} }
@ -127,7 +127,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param blockPosition the block position * @param blockPosition the block position
* @param blockStateId the new block state * @param blockStateId the new block state
*/ */
public abstract void refreshBlockStateId(BlockPosition blockPosition, short blockStateId); public abstract void refreshBlockStateId(@NotNull BlockPosition blockPosition, short blockStateId);
/** /**
* Does call {@link net.minestom.server.event.player.PlayerBlockBreakEvent} * Does call {@link net.minestom.server.event.player.PlayerBlockBreakEvent}
@ -137,7 +137,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param blockPosition the {@link BlockPosition} of the broken block * @param blockPosition the {@link BlockPosition} of the broken block
* @return true if the block has been broken, false if it has been cancelled * @return true if the block has been broken, false if it has been cancelled
*/ */
public abstract boolean breakBlock(Player player, BlockPosition blockPosition); public abstract boolean breakBlock(@NotNull Player player, @NotNull BlockPosition blockPosition);
/** /**
* Forces the generation of a {@link Chunk}, even if no file and {@link ChunkGenerator} are defined. * Forces the generation of a {@link Chunk}, even if no file and {@link ChunkGenerator} are defined.
@ -189,7 +189,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param chunk the {@link Chunk} to save * @param chunk the {@link Chunk} to save
* @param callback optional callback called when the {@link Chunk} is done saving * @param callback optional callback called when the {@link Chunk} is done saving
*/ */
public abstract void saveChunkToStorage(Chunk chunk, @Nullable Runnable callback); public abstract void saveChunkToStorage(@NotNull Chunk chunk, @Nullable Runnable callback);
/** /**
* Saves multiple chunks to permanent storage. * Saves multiple chunks to permanent storage.
@ -212,13 +212,14 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @return a ChunkBatch linked to {@code chunk} * @return a ChunkBatch linked to {@code chunk}
* @throws NullPointerException if {@code chunk} is null * @throws NullPointerException if {@code chunk} is null
*/ */
public abstract ChunkBatch createChunkBatch(Chunk chunk); public abstract ChunkBatch createChunkBatch(@NotNull Chunk chunk);
/** /**
* Gets the instance {@link ChunkGenerator}. * Gets the instance {@link ChunkGenerator}.
* *
* @return the {@link ChunkGenerator} of the instance * @return the {@link ChunkGenerator} of the instance
*/ */
@Nullable
public abstract ChunkGenerator getChunkGenerator(); public abstract ChunkGenerator getChunkGenerator();
/** /**
@ -226,13 +227,14 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @param chunkGenerator the new {@link ChunkGenerator} of the instance * @param chunkGenerator the new {@link ChunkGenerator} of the instance
*/ */
public abstract void setChunkGenerator(ChunkGenerator chunkGenerator); public abstract void setChunkGenerator(@Nullable ChunkGenerator chunkGenerator);
/** /**
* Gets all the instance's chunks. * Gets all the instance's chunks.
* *
* @return an unmodifiable containing all the loaded chunks of the instance * @return an unmodifiable containing all the loaded chunks of the instance
*/ */
@NotNull
public abstract Collection<Chunk> getChunks(); public abstract Collection<Chunk> getChunks();
/** /**
@ -240,6 +242,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return the {@link StorageLocation} of the instance * @return the {@link StorageLocation} of the instance
*/ */
@Nullable
public abstract StorageLocation getStorageLocation(); public abstract StorageLocation getStorageLocation();
/** /**
@ -247,7 +250,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @param storageLocation the new {@link StorageLocation} of the instance * @param storageLocation the new {@link StorageLocation} of the instance
*/ */
public abstract void setStorageLocation(StorageLocation storageLocation); public abstract void setStorageLocation(@Nullable StorageLocation storageLocation);
/** /**
* Used when a {@link Chunk} is not currently loaded in memory and need to be retrieved from somewhere else. * Used when a {@link Chunk} is not currently loaded in memory and need to be retrieved from somewhere else.
@ -301,7 +304,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param position the position in the world * @param position the position in the world
* @return true iif position is inside the void * @return true iif position is inside the void
*/ */
public abstract boolean isInVoid(Position position); public abstract boolean isInVoid(@NotNull Position position);
/** /**
* Gets if the instance has been registered in {@link InstanceManager}. * Gets if the instance has been registered in {@link InstanceManager}.
@ -396,6 +399,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return the client update rate for time related packet * @return the client update rate for time related packet
*/ */
@Nullable
public UpdateOption getTimeUpdate() { public UpdateOption getTimeUpdate() {
return timeUpdate; return timeUpdate;
} }
@ -408,7 +412,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @param timeUpdate the new update rate concerning time * @param timeUpdate the new update rate concerning time
*/ */
public void setTimeUpdate(UpdateOption timeUpdate) { public void setTimeUpdate(@Nullable UpdateOption timeUpdate) {
this.timeUpdate = timeUpdate; this.timeUpdate = timeUpdate;
} }
@ -417,6 +421,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return the {@link TimeUpdatePacket} with this instance data * @return the {@link TimeUpdatePacket} with this instance data
*/ */
@NotNull
private TimeUpdatePacket getTimePacket() { private TimeUpdatePacket getTimePacket() {
TimeUpdatePacket timeUpdatePacket = new TimeUpdatePacket(); TimeUpdatePacket timeUpdatePacket = new TimeUpdatePacket();
timeUpdatePacket.worldAge = worldAge; timeUpdatePacket.worldAge = worldAge;
@ -429,6 +434,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return the {@link WorldBorder} linked to the instance * @return the {@link WorldBorder} linked to the instance
*/ */
@NotNull
public WorldBorder getWorldBorder() { public WorldBorder getWorldBorder() {
return worldBorder; return worldBorder;
} }
@ -438,6 +444,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return an unmodifiable {@link Set} containing all the entities in the instance * @return an unmodifiable {@link Set} containing all the entities in the instance
*/ */
@NotNull
public Set<Entity> getEntities() { public Set<Entity> getEntities() {
return Collections.unmodifiableSet(entities); return Collections.unmodifiableSet(entities);
} }
@ -447,6 +454,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return an unmodifiable {@link Set} containing all the players in the instance * @return an unmodifiable {@link Set} containing all the players in the instance
*/ */
@NotNull
public Set<Player> getPlayers() { public Set<Player> getPlayers() {
return Collections.unmodifiableSet(players); return Collections.unmodifiableSet(players);
} }
@ -456,6 +464,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return an unmodifiable {@link Set} containing all the creatures in the instance * @return an unmodifiable {@link Set} containing all the creatures in the instance
*/ */
@NotNull
public Set<EntityCreature> getCreatures() { public Set<EntityCreature> getCreatures() {
return Collections.unmodifiableSet(creatures); return Collections.unmodifiableSet(creatures);
} }
@ -465,6 +474,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return an unmodifiable {@link Set} containing all the object entities in the instance * @return an unmodifiable {@link Set} containing all the object entities in the instance
*/ */
@NotNull
public Set<ObjectEntity> getObjectEntities() { public Set<ObjectEntity> getObjectEntities() {
return Collections.unmodifiableSet(objectEntities); return Collections.unmodifiableSet(objectEntities);
} }
@ -474,6 +484,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* *
* @return an unmodifiable {@link Set} containing all the experience orbs in the instance * @return an unmodifiable {@link Set} containing all the experience orbs in the instance
*/ */
@NotNull
public Set<ExperienceOrb> getExperienceOrbs() { public Set<ExperienceOrb> getExperienceOrbs() {
return Collections.unmodifiableSet(experienceOrbs); return Collections.unmodifiableSet(experienceOrbs);
} }
@ -485,6 +496,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @return an unmodifiable {@link Set} containing all the entities in a chunk, * @return an unmodifiable {@link Set} containing all the entities in a chunk,
* if {@code chunk} is unloaded, return an empty {@link HashSet} * if {@code chunk} is unloaded, return an empty {@link HashSet}
*/ */
@NotNull
public Set<Entity> getChunkEntities(Chunk chunk) { public Set<Entity> getChunkEntities(Chunk chunk) {
if (!ChunkUtils.isLoaded(chunk)) if (!ChunkUtils.isLoaded(chunk))
return new HashSet<>(); return new HashSet<>();
@ -518,7 +530,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param z the Z position * @param z the Z position
* @param block the new visual block * @param block the new visual block
*/ */
public void refreshBlockId(int x, int y, int z, Block block) { public void refreshBlockId(int x, int y, int z, @NotNull Block block) {
refreshBlockStateId(x, y, z, block.getBlockId()); refreshBlockStateId(x, y, z, block.getBlockId());
} }
@ -530,7 +542,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param blockPosition the block position * @param blockPosition the block position
* @param block the new visual block * @param block the new visual block
*/ */
public void refreshBlockId(BlockPosition blockPosition, Block block) { public void refreshBlockId(@NotNull BlockPosition blockPosition, @NotNull Block block) {
refreshBlockStateId(blockPosition, block.getBlockId()); refreshBlockStateId(blockPosition, block.getBlockId());
} }
@ -552,7 +564,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param position the chunk position * @param position the chunk position
* @param callback the optional callback to run when the chunk is loaded * @param callback the optional callback to run when the chunk is loaded
*/ */
public void loadChunk(Position position, @Nullable ChunkCallback callback) { public void loadChunk(@NotNull Position position, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate((int) position.getX()); final int chunkX = ChunkUtils.getChunkCoordinate((int) position.getX());
final int chunkZ = ChunkUtils.getChunkCoordinate((int) position.getZ()); final int chunkZ = ChunkUtils.getChunkCoordinate((int) position.getZ());
loadChunk(chunkX, chunkZ, callback); loadChunk(chunkX, chunkZ, callback);
@ -565,7 +577,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param position the chunk position * @param position the chunk position
* @param callback the optional callback executed when the chunk is loaded (or with a null chunk if not) * @param callback the optional callback executed when the chunk is loaded (or with a null chunk if not)
*/ */
public void loadOptionalChunk(Position position, @Nullable ChunkCallback callback) { public void loadOptionalChunk(@NotNull Position position, @Nullable ChunkCallback callback) {
final int chunkX = ChunkUtils.getChunkCoordinate((int) position.getX()); final int chunkX = ChunkUtils.getChunkCoordinate((int) position.getX());
final int chunkZ = ChunkUtils.getChunkCoordinate((int) position.getZ()); final int chunkZ = ChunkUtils.getChunkCoordinate((int) position.getZ());
loadOptionalChunk(chunkX, chunkZ, callback); loadOptionalChunk(chunkX, chunkZ, callback);
@ -675,6 +687,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param z the Z position * @param z the Z position
* @return the block data at the position, null if not any * @return the block data at the position, null if not any
*/ */
@Nullable
public Data getBlockData(int x, int y, int z) { public Data getBlockData(int x, int y, int z) {
final Chunk chunk = getChunkAt(x, z); final Chunk chunk = getChunkAt(x, z);
Check.notNull(chunk, "The chunk at " + x + ":" + z + " is not loaded"); Check.notNull(chunk, "The chunk at " + x + ":" + z + " is not loaded");
@ -688,6 +701,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
* @param blockPosition the block position * @param blockPosition the block position
* @return the block data at the position, null if not any * @return the block data at the position, null if not any
*/ */
@Nullable
public Data getBlockData(@NotNull BlockPosition blockPosition) { public Data getBlockData(@NotNull BlockPosition blockPosition) {
return getBlockData(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ()); return getBlockData(blockPosition.getX(), blockPosition.getY(), blockPosition.getZ());
} }

View File

@ -236,8 +236,9 @@ public class InstanceContainer extends Instance {
} }
@Override @Override
public void refreshBlockStateId(BlockPosition blockPosition, short blockStateId) { public void refreshBlockStateId(@NotNull BlockPosition blockPosition, short blockStateId) {
final Chunk chunk = getChunkAt(blockPosition.getX(), blockPosition.getZ()); final Chunk chunk = getChunkAt(blockPosition.getX(), blockPosition.getZ());
Check.notNull(chunk, "You cannot refresh a block in a null chunk!");
synchronized (chunk) { synchronized (chunk) {
chunk.refreshBlockStateId(blockPosition.getX(), blockPosition.getY(), chunk.refreshBlockStateId(blockPosition.getX(), blockPosition.getY(),
blockPosition.getZ(), blockStateId); blockPosition.getZ(), blockStateId);
@ -342,10 +343,11 @@ public class InstanceContainer extends Instance {
} }
@Override @Override
public boolean breakBlock(Player player, BlockPosition blockPosition) { public boolean breakBlock(@NotNull Player player, @NotNull BlockPosition blockPosition) {
player.resetTargetBlock(); player.resetTargetBlock();
final Chunk chunk = getChunkAt(blockPosition); final Chunk chunk = getChunkAt(blockPosition);
Check.notNull(chunk, "You cannot break blocks in a null chunk!");
// Cancel if the chunk is read-only // Cancel if the chunk is read-only
if (chunk.isReadOnly()) { if (chunk.isReadOnly()) {
@ -474,7 +476,7 @@ public class InstanceContainer extends Instance {
} }
@Override @Override
public void saveChunkToStorage(Chunk chunk, Runnable callback) { public void saveChunkToStorage(@NotNull Chunk chunk, Runnable callback) {
this.chunkLoader.saveChunk(chunk, callback); this.chunkLoader.saveChunk(chunk, callback);
} }
@ -489,7 +491,7 @@ public class InstanceContainer extends Instance {
} }
@Override @Override
public ChunkBatch createChunkBatch(Chunk chunk) { public ChunkBatch createChunkBatch(@NotNull Chunk chunk) {
Check.notNull(chunk, "The chunk of a ChunkBatch cannot be null"); Check.notNull(chunk, "The chunk of a ChunkBatch cannot be null");
return new ChunkBatch(this, chunk); return new ChunkBatch(this, chunk);
} }
@ -551,7 +553,7 @@ public class InstanceContainer extends Instance {
} }
@Override @Override
public boolean isInVoid(Position position) { public boolean isInVoid(@NotNull Position position) {
// TODO: customizable // TODO: customizable
return position.getY() < -64; return position.getY() < -64;
} }
@ -629,6 +631,7 @@ public class InstanceContainer extends Instance {
* *
* @return the chunks of this instance * @return the chunks of this instance
*/ */
@NotNull
public Collection<Chunk> getChunks() { public Collection<Chunk> getChunks() {
return Collections.unmodifiableCollection(chunks.values()); return Collections.unmodifiableCollection(chunks.values());
} }

View File

@ -29,12 +29,12 @@ public class SharedInstance extends Instance {
} }
@Override @Override
public void refreshBlockStateId(BlockPosition blockPosition, short blockStateId) { public void refreshBlockStateId(@NotNull BlockPosition blockPosition, short blockStateId) {
this.instanceContainer.refreshBlockStateId(blockPosition, blockStateId); this.instanceContainer.refreshBlockStateId(blockPosition, blockStateId);
} }
@Override @Override
public boolean breakBlock(Player player, BlockPosition blockPosition) { public boolean breakBlock(@NotNull Player player, @NotNull BlockPosition blockPosition) {
return instanceContainer.breakBlock(player, blockPosition); return instanceContainer.breakBlock(player, blockPosition);
} }
@ -59,7 +59,7 @@ public class SharedInstance extends Instance {
} }
@Override @Override
public void saveChunkToStorage(Chunk chunk, @Nullable Runnable callback) { public void saveChunkToStorage(@NotNull Chunk chunk, @Nullable Runnable callback) {
this.instanceContainer.saveChunkToStorage(chunk, callback); this.instanceContainer.saveChunkToStorage(chunk, callback);
} }
@ -74,7 +74,7 @@ public class SharedInstance extends Instance {
} }
@Override @Override
public ChunkBatch createChunkBatch(Chunk chunk) { public ChunkBatch createChunkBatch(@NotNull Chunk chunk) {
return instanceContainer.createChunkBatch(chunk); return instanceContainer.createChunkBatch(chunk);
} }
@ -88,6 +88,7 @@ public class SharedInstance extends Instance {
return instanceContainer.getChunkGenerator(); return instanceContainer.getChunkGenerator();
} }
@NotNull
@Override @Override
public Collection<Chunk> getChunks() { public Collection<Chunk> getChunks() {
return instanceContainer.getChunks(); return instanceContainer.getChunks();
@ -124,7 +125,7 @@ public class SharedInstance extends Instance {
} }
@Override @Override
public boolean isInVoid(Position position) { public boolean isInVoid(@NotNull Position position) {
return instanceContainer.isInVoid(position); return instanceContainer.isInVoid(position);
} }

View File

@ -18,7 +18,6 @@ public class RespawnPacket implements ServerPacket {
@Override @Override
public void write(@NotNull BinaryWriter writer) { public void write(@NotNull BinaryWriter writer) {
//TODO add api
writer.writeNBT("", dimensionType.toNBT()); writer.writeNBT("", dimensionType.toNBT());
// Warning: must be different for each dimension type! Otherwise the client seems to cache the world name // Warning: must be different for each dimension type! Otherwise the client seems to cache the world name