Chunk memory optimization

This commit is contained in:
TheMode 2019-08-19 00:48:49 +02:00
parent 0d40be1552
commit 4263a3965b
8 changed files with 53 additions and 28 deletions

View File

@ -39,7 +39,7 @@ public class Main {
blockManager = new BlockManager(); blockManager = new BlockManager();
entityManager = new EntityManager(); entityManager = new EntityManager();
blockManager.registerBlock("stone", StoneBlock::new); blockManager.registerBlock(StoneBlock::new);
server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() { server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() {
@Override @Override

View File

@ -6,14 +6,23 @@ import java.util.function.Supplier;
public class BlockManager { public class BlockManager {
private Map<String, CustomBlock> blocks = new HashMap<>(); private Map<Integer, CustomBlock> blocksInternalId = new HashMap<>();
private Map<String, CustomBlock> blocksId = new HashMap<>();
public void registerBlock(String id, Supplier<CustomBlock> blocks) { public void registerBlock(Supplier<CustomBlock> blocks) {
this.blocks.put(id, blocks.get()); CustomBlock customBlock = blocks.get();
String identifier = customBlock.getIdentifier();
int id = customBlock.getId();
this.blocksInternalId.put(id, customBlock);
this.blocksId.put(identifier, customBlock);
} }
public CustomBlock getBlock(String id) { public CustomBlock getBlock(String identifier) {
return this.blocks.get(id); return blocksId.get(identifier);
}
public CustomBlock getBlock(int id) {
return blocksInternalId.get(id);
} }
} }

View File

@ -18,7 +18,7 @@ public class Chunk {
private int chunkX, chunkZ; private int chunkX, chunkZ;
private Biome biome; private Biome biome;
private short[] blocksId = new short[CHUNK_SIZE]; private short[] blocksId = new short[CHUNK_SIZE];
private String[] customBlocks = new String[CHUNK_SIZE]; private int[] customBlocks = new int[CHUNK_SIZE];
public Chunk(Biome biome, int chunkX, int chunkZ) { public Chunk(Biome biome, int chunkX, int chunkZ) {
this.biome = biome; this.biome = biome;
@ -30,23 +30,27 @@ public class Chunk {
int index = getIndex(x, y, z); int index = getIndex(x, y, z);
this.blocksId[index] = blockId; this.blocksId[index] = blockId;
if (blockId == 0) { if (blockId == 0) {
this.customBlocks[index] = null; this.customBlocks[index] = 0;
} }
} }
protected void setBlock(byte x, byte y, byte z, String blockId) { protected void setBlock(byte x, byte y, byte z, String blockId) {
int index = getIndex(x, y, z);
CustomBlock customBlock = Main.getBlockManager().getBlock(blockId); CustomBlock customBlock = Main.getBlockManager().getBlock(blockId);
if (customBlock == null)
throw new IllegalArgumentException("The block " + blockId + " does not exist or isn't registered");
int index = getIndex(x, y, z);
this.blocksId[index] = customBlock.getType(); this.blocksId[index] = customBlock.getType();
this.customBlocks[index] = blockId; this.customBlocks[index] = customBlock.getId();
} }
public short getBlockId(byte x, byte y, byte z) { public short getBlockId(byte x, byte y, byte z) {
return this.blocksId[getIndex(x, y, z)]; return this.blocksId[getIndex(x, y, z)];
} }
public String getCustomBlockId(byte x, byte y, byte z) { public CustomBlock getCustomBlock(byte x, byte y, byte z) {
return this.customBlocks[getIndex(x, y, z)]; int id = this.customBlocks[getIndex(x, y, z)];
return id != 0 ? Main.getBlockManager().getBlock(id) : null;
} }
public void addEntity(Entity entity) { public void addEntity(Entity entity) {

View File

@ -2,20 +2,28 @@ package fr.themode.minestom.instance;
import fr.themode.minestom.entity.Player; import fr.themode.minestom.entity.Player;
import java.util.concurrent.atomic.AtomicInteger;
public abstract class CustomBlock { public abstract class CustomBlock {
private short type; private static final AtomicInteger idCounter = new AtomicInteger();
public CustomBlock(short type) { private int id;
this.type = type;
public CustomBlock() {
this.id = idCounter.incrementAndGet();
} }
public abstract short getType();
public abstract String getIdentifier();
/* /*
Time in ms Time in ms
*/ */
public abstract int getBreakDelay(Player player); public abstract int getBreakDelay(Player player);
public short getType() { public int getId() {
return type; return id;
} }
} }

View File

@ -19,7 +19,7 @@ public class Instance {
private GroupedCollections<EntityCreature> creatures = new GroupedCollections<>(new CopyOnWriteArrayList()); private GroupedCollections<EntityCreature> creatures = new GroupedCollections<>(new CopyOnWriteArrayList());
private GroupedCollections<Player> players = new GroupedCollections<>(new CopyOnWriteArrayList()); private GroupedCollections<Player> players = new GroupedCollections<>(new CopyOnWriteArrayList());
private Set<Chunk> chunksSet = new CopyOnWriteArraySet<>(); private Set<Chunk> chunksSet = new CopyOnWriteArraySet<>(); // TODO change for a map with position as key and chunk as value
public Instance(UUID uniqueId) { public Instance(UUID uniqueId) {
this.uniqueId = uniqueId; this.uniqueId = uniqueId;
@ -46,9 +46,9 @@ public class Instance {
return chunk.getBlockId((byte) (x % 16), (byte) y, (byte) (z % 16)); return chunk.getBlockId((byte) (x % 16), (byte) y, (byte) (z % 16));
} }
public String getCustomBlockId(int x, int y, int z) { public CustomBlock getCustomBlock(int x, int y, int z) {
Chunk chunk = getChunkAt(x, z); Chunk chunk = getChunkAt(x, z);
return chunk.getCustomBlockId((byte) (x % 16), (byte) y, (byte) (z % 16)); return chunk.getCustomBlock((byte) (x % 16), (byte) y, (byte) (z % 16));
} }
public BlockBatch createBlockBatch() { public BlockBatch createBlockBatch() {

View File

@ -5,12 +5,18 @@ import fr.themode.minestom.instance.CustomBlock;
public class StoneBlock extends CustomBlock { public class StoneBlock extends CustomBlock {
public StoneBlock() { @Override
super((short) 1); public short getType() {
return 1;
}
@Override
public String getIdentifier() {
return "stone_block";
} }
@Override @Override
public int getBreakDelay(Player player) { public int getBreakDelay(Player player) {
return 750; return 750;
} }
} }

View File

@ -25,7 +25,7 @@ public class ClientPlayerBlockPlacementPacket implements ClientPlayPacket {
int offsetY = blockFace == ClientPlayerDiggingPacket.BlockFace.BOTTOM ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.TOP ? 1 : 0; int offsetY = blockFace == ClientPlayerDiggingPacket.BlockFace.BOTTOM ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.TOP ? 1 : 0;
int offsetZ = blockFace == ClientPlayerDiggingPacket.BlockFace.NORTH ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.SOUTH ? 1 : 0; int offsetZ = blockFace == ClientPlayerDiggingPacket.BlockFace.NORTH ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.SOUTH ? 1 : 0;
instance.setBlock(position.getX() + offsetX, position.getY() + offsetY, position.getZ() + offsetZ, "stone"); instance.setBlock(position.getX() + offsetX, position.getY() + offsetY, position.getZ() + offsetZ, "stone_block");
player.getInventory().refreshSlot(player.getHeldSlot()); player.getInventory().refreshSlot(player.getHeldSlot());
// TODO consume block in hand for survival players // TODO consume block in hand for survival players
/*Random random = new Random(); /*Random random = new Random();

View File

@ -1,7 +1,6 @@
package fr.themode.minestom.net.packet.client.play; package fr.themode.minestom.net.packet.client.play;
import fr.adamaq01.ozao.net.Buffer; import fr.adamaq01.ozao.net.Buffer;
import fr.themode.minestom.Main;
import fr.themode.minestom.entity.GameMode; import fr.themode.minestom.entity.GameMode;
import fr.themode.minestom.entity.Player; import fr.themode.minestom.entity.Player;
import fr.themode.minestom.instance.CustomBlock; import fr.themode.minestom.instance.CustomBlock;
@ -30,9 +29,8 @@ public class ClientPlayerDiggingPacket implements ClientPlayPacket {
} else if (player.getGameMode() == GameMode.SURVIVAL) { } else if (player.getGameMode() == GameMode.SURVIVAL) {
Instance instance = player.getInstance(); Instance instance = player.getInstance();
if (instance != null) { if (instance != null) {
String customBlockId = instance.getCustomBlockId(position.getX(), position.getY(), position.getZ()); CustomBlock customBlock = instance.getCustomBlock(position.getX(), position.getY(), position.getZ());
if (customBlockId != null) { if (customBlock != null) {
CustomBlock customBlock = Main.getBlockManager().getBlock(customBlockId);
player.refreshTargetBlock(customBlock, position); player.refreshTargetBlock(customBlock, position);
addEffect(player); addEffect(player);
} else { } else {