Remove BlockState class

The BlockState class is simply a wrapper for an integer. Dealing with many BlockState classes in our Geyser project uses up a lot of RAM when we can simplify that down to more efficient integers.
This commit is contained in:
DoctorMacc 2020-06-18 18:44:07 -04:00
parent f142eab3a2
commit 16cbbf8de5
14 changed files with 37 additions and 73 deletions

View file

@ -1,6 +1,5 @@
package com.github.steveice10.mc.protocol.data.game.chunk;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;
import lombok.AccessLevel;
@ -18,12 +17,12 @@ import java.util.List;
@Setter(AccessLevel.NONE)
@AllArgsConstructor
public class Chunk {
private static final BlockState AIR = new BlockState(0);
private static final int AIR = 0;
private int blockCount;
private int bitsPerEntry;
private @NonNull List<BlockState> states;
private @NonNull List<Integer> states;
private @NonNull FlexibleStorage storage;
public Chunk() {
@ -34,10 +33,10 @@ public class Chunk {
int blockCount = in.readShort();
int bitsPerEntry = in.readUnsignedByte();
List<BlockState> states = new ArrayList<>();
List<Integer> states = new ArrayList<>();
int stateCount = bitsPerEntry > 8 ? 0 : in.readVarInt();
for(int i = 0; i < stateCount; i++) {
states.add(BlockState.read(in));
states.add(in.readVarInt());
}
FlexibleStorage storage = new FlexibleStorage(bitsPerEntry, in.readLongs(in.readVarInt()));
@ -50,8 +49,8 @@ public class Chunk {
if(chunk.getBitsPerEntry() <= 8) {
out.writeVarInt(chunk.getStates().size());
for (BlockState state : chunk.getStates()) {
BlockState.write(out, state);
for (int state : chunk.getStates()) {
out.writeVarInt(state);
}
}
@ -64,21 +63,21 @@ public class Chunk {
return y << 8 | z << 4 | x;
}
public BlockState get(int x, int y, int z) {
public int get(int x, int y, int z) {
int id = this.storage.get(index(x, y, z));
return this.bitsPerEntry <= 8 ? (id >= 0 && id < this.states.size() ? this.states.get(id) : AIR) : new BlockState(id);
return this.bitsPerEntry <= 8 ? (id >= 0 && id < this.states.size() ? this.states.get(id) : AIR) : id;
}
public void set(int x, int y, int z, @NonNull BlockState state) {
int id = this.bitsPerEntry <= 8 ? this.states.indexOf(state) : state.getId();
public void set(int x, int y, int z, @NonNull int state) {
int id = this.bitsPerEntry <= 8 ? this.states.indexOf(state) : state;
if(id == -1) {
this.states.add(state);
if(this.states.size() > 1 << this.bitsPerEntry) {
this.bitsPerEntry++;
List<BlockState> oldStates = this.states;
List<Integer> oldStates = this.states;
if(this.bitsPerEntry > 8) {
oldStates = new ArrayList<BlockState>(this.states);
oldStates = new ArrayList<Integer>(this.states);
this.states.clear();
this.bitsPerEntry = 13;
}
@ -86,18 +85,18 @@ public class Chunk {
FlexibleStorage oldStorage = this.storage;
this.storage = new FlexibleStorage(this.bitsPerEntry, this.storage.getSize());
for(int index = 0; index < this.storage.getSize(); index++) {
this.storage.set(index, this.bitsPerEntry <= 8 ? oldStorage.get(index) : oldStates.get(index).getId());
this.storage.set(index, this.bitsPerEntry <= 8 ? oldStorage.get(index) : oldStates.get(index));
}
}
id = this.bitsPerEntry <= 8 ? this.states.indexOf(state) : state.getId();
id = this.bitsPerEntry <= 8 ? this.states.indexOf(state) : state;
}
int ind = index(x, y, z);
int curr = this.storage.get(ind);
if(state.getId() != AIR.getId() && curr == AIR.getId()) {
if(state != AIR && curr == AIR) {
this.blockCount++;
} else if(state.getId() == AIR.getId() && curr != AIR.getId()) {
} else if(state == AIR && curr != AIR) {
this.blockCount--;
}

View file

@ -3,7 +3,6 @@ package com.github.steveice10.mc.protocol.data.game.entity.metadata;
import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.NBT;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockFace;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.mc.protocol.data.game.world.particle.Particle;
import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleData;
import com.github.steveice10.mc.protocol.data.game.world.particle.ParticleType;
@ -41,6 +40,7 @@ public class EntityMetadata {
value = in.readByte();
break;
case INT:
case BLOCK_STATE:
value = in.readVarInt();
break;
case FLOAT:
@ -87,9 +87,6 @@ public class EntityMetadata {
value = in.readUUID();
}
break;
case BLOCK_STATE:
value = BlockState.read(in);
break;
case NBT_TAG:
value = NBT.read(in);
@ -175,7 +172,7 @@ public class EntityMetadata {
break;
case BLOCK_STATE:
BlockState.write(out, (BlockState) meta.getValue());
out.writeVarInt((int) meta.getValue());
break;
case NBT_TAG:
NBT.write(out, (CompoundTag) meta.getValue());

View file

@ -9,5 +9,5 @@ import lombok.NonNull;
@AllArgsConstructor
public class BlockChangeRecord {
private final @NonNull Position position;
private final @NonNull BlockState block;
private final @NonNull int block;
}

View file

@ -1,22 +0,0 @@
package com.github.steveice10.mc.protocol.data.game.world.block;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.IOException;
@Data
@AllArgsConstructor
public class BlockState {
private final int id;
public static BlockState read(NetInput in) throws IOException {
return new BlockState(in.readVarInt());
}
public static void write(NetOutput out, BlockState blockState) throws IOException {
out.writeVarInt(blockState.getId());
}
}

View file

@ -1,6 +1,5 @@
package com.github.steveice10.mc.protocol.data.game.world.effect;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;
@ -8,5 +7,5 @@ import lombok.NonNull;
@Data
@AllArgsConstructor
public class BreakBlockEffectData implements WorldEffectData {
private final @NonNull BlockState blockState;
private final @NonNull int blockState;
}

View file

@ -1,6 +1,5 @@
package com.github.steveice10.mc.protocol.data.game.world.particle;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;
@ -8,5 +7,5 @@ import lombok.NonNull;
@Data
@AllArgsConstructor
public class BlockParticleData implements ParticleData {
private final @NonNull BlockState blockState;
private final @NonNull int blockState;
}

View file

@ -1,6 +1,5 @@
package com.github.steveice10.mc.protocol.data.game.world.particle;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NonNull;
@ -8,5 +7,5 @@ import lombok.NonNull;
@Data
@AllArgsConstructor
public class FallingDustParticleData implements ParticleData {
private final @NonNull BlockState blockState;
private final @NonNull int blockState;
}

View file

@ -1,7 +1,6 @@
package com.github.steveice10.mc.protocol.data.game.world.particle;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;
@ -11,7 +10,7 @@ public interface ParticleData {
public static ParticleData read(NetInput in, ParticleType type) throws IOException {
switch (type) {
case BLOCK:
return new BlockParticleData(BlockState.read(in));
return new BlockParticleData(in.readVarInt());
case DUST:
float red = in.readFloat();
float green = in.readFloat();
@ -19,7 +18,7 @@ public interface ParticleData {
float scale = in.readFloat();
return new DustParticleData(red, green, blue, scale);
case FALLING_DUST:
return new FallingDustParticleData(BlockState.read(in));
return new FallingDustParticleData(in.readVarInt());
case ITEM:
return new ItemParticleData(ItemStack.read(in));
default:
@ -30,7 +29,7 @@ public interface ParticleData {
public static void write(NetOutput out, ParticleType type, ParticleData data) throws IOException {
switch (type) {
case BLOCK:
BlockState.write(out, ((BlockParticleData) data).getBlockState());
out.writeVarInt(((BlockParticleData) data).getBlockState());
break;
case DUST:
out.writeFloat(((DustParticleData) data).getRed());
@ -39,7 +38,7 @@ public interface ParticleData {
out.writeFloat(((DustParticleData) data).getScale());
break;
case FALLING_DUST:
BlockState.write(out, ((FallingDustParticleData) data).getBlockState());
out.writeVarInt(((FallingDustParticleData) data).getBlockState());
break;
case ITEM:
ItemStack.write(out, ((ItemParticleData) data).getItemStack());

View file

@ -3,7 +3,6 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.entity.player;
import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.entity.player.PlayerAction;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet;
@ -24,12 +23,12 @@ public class ServerPlayerActionAckPacket implements Packet {
private @NonNull PlayerAction action;
private boolean successful;
private @NonNull Position position;
private @NonNull BlockState newState;
private @NonNull int newState;
@Override
public void read(NetInput in) throws IOException {
this.position = Position.read(in);
this.newState = BlockState.read(in);
this.newState = in.readVarInt();
this.action = MagicValues.key(PlayerAction.class, in.readVarInt());
this.successful = in.readBoolean();
}
@ -37,7 +36,7 @@ public class ServerPlayerActionAckPacket implements Packet {
@Override
public void write(NetOutput out) throws IOException {
Position.write(out, this.position);
BlockState.write(out, this.newState);
out.writeVarInt(this.newState);
out.writeVarInt(MagicValues.value(Integer.class, this.action));
out.writeBoolean(this.successful);
}

View file

@ -2,7 +2,6 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.world;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet;
@ -24,13 +23,13 @@ public class ServerBlockChangePacket implements Packet {
@Override
public void read(NetInput in) throws IOException {
this.record = new BlockChangeRecord(Position.read(in), BlockState.read(in));
this.record = new BlockChangeRecord(Position.read(in), in.readVarInt());
}
@Override
public void write(NetOutput out) throws IOException {
Position.write(out, this.record.getPosition());
BlockState.write(out, this.record.getBlock());
out.writeVarInt(this.record.getBlock());
}
@Override

View file

@ -2,7 +2,6 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.world;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.packetlib.io.NetInput;
import com.github.steveice10.packetlib.io.NetOutput;
import com.github.steveice10.packetlib.packet.Packet;
@ -35,7 +34,7 @@ public class ServerMultiBlockChangePacket implements Packet {
this.records = new BlockChangeRecord[in.readVarInt()];
for(int index = 0; index < this.records.length; index++) {
short pos = in.readShort();
BlockState block = BlockState.read(in);
int block = in.readVarInt();
int x = (chunkX << 4) + (pos >> 12 & 15);
int y = pos & 255;
int z = (chunkZ << 4) + (pos >> 8 & 15);
@ -52,7 +51,7 @@ public class ServerMultiBlockChangePacket implements Packet {
out.writeVarInt(this.records.length);
for(BlockChangeRecord record : this.records) {
out.writeShort((record.getPosition().getX() - (chunkX << 4)) << 12 | (record.getPosition().getZ() - (chunkZ << 4)) << 8 | record.getPosition().getY());
BlockState.write(out, record.getBlock());
out.writeVarInt(record.getBlock());
}
}

View file

@ -2,7 +2,6 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.world;
import com.github.steveice10.mc.protocol.data.MagicValues;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.mc.protocol.data.game.world.effect.BonemealGrowEffectData;
import com.github.steveice10.mc.protocol.data.game.world.effect.BreakBlockEffectData;
import com.github.steveice10.mc.protocol.data.game.world.effect.BreakPotionEffectData;
@ -49,7 +48,7 @@ public class ServerPlayEffectPacket implements Packet {
} else if(this.effect == ParticleEffect.SMOKE) {
this.data = MagicValues.key(SmokeEffectData.class, value % 9);
} else if(this.effect == ParticleEffect.BREAK_BLOCK) {
this.data = new BreakBlockEffectData(new BlockState(value));
this.data = new BreakBlockEffectData(value);
} else if(this.effect == ParticleEffect.BREAK_SPLASH_POTION) {
this.data = new BreakPotionEffectData(value);
} else if(this.effect == ParticleEffect.BONEMEAL_GROW) {
@ -71,7 +70,7 @@ public class ServerPlayEffectPacket implements Packet {
} else if(this.data instanceof SmokeEffectData) {
value = MagicValues.value(Integer.class, (SmokeEffectData) this.data);
} else if(this.data instanceof BreakBlockEffectData) {
value = ((BreakBlockEffectData) this.data).getBlockState().getId();
value = ((BreakBlockEffectData) this.data).getBlockState();
} else if(this.data instanceof BreakPotionEffectData) {
value = ((BreakPotionEffectData) this.data).getPotionId();
} else if(this.data instanceof BonemealGrowEffectData) {

View file

@ -2,7 +2,6 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.world;
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Position;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockChangeRecord;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.mc.protocol.packet.PacketTest;
import org.junit.Before;
@ -11,7 +10,7 @@ public class ServerBlockChangePacketTest extends PacketTest {
public void setup() {
this.setPackets(
new ServerBlockChangePacket(new BlockChangeRecord(
new Position(1, 61, -1), new BlockState(3)
new Position(1, 61, -1), 3
))
);
}

View file

@ -2,7 +2,6 @@ package com.github.steveice10.mc.protocol.packet.ingame.server.world;
import com.github.steveice10.mc.protocol.data.game.chunk.Chunk;
import com.github.steveice10.mc.protocol.data.game.chunk.Column;
import com.github.steveice10.mc.protocol.data.game.world.block.BlockState;
import com.github.steveice10.mc.protocol.packet.PacketTest;
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
import org.junit.Before;
@ -11,7 +10,7 @@ public class ServerChunkDataPacketTest extends PacketTest {
@Before
public void setup() {
Chunk chunk = new Chunk();
chunk.set(0, 0, 0, new BlockState(10));
chunk.set(0, 0, 0, 10);
this.setPackets(
new ServerChunkDataPacket(