Added BlockBatch

This commit is contained in:
TheMode 2019-08-12 13:27:24 +02:00
parent 2e626f785e
commit 349de8773f
9 changed files with 98 additions and 43 deletions

View File

@ -11,7 +11,7 @@ public class EntityManager {
private static InstanceManager instanceManager = Main.getInstanceManager();
private ExecutorService creaturesPool = Executors.newFixedThreadPool(4);
private ExecutorService creaturesPool = Executors.newFixedThreadPool(2);
private ExecutorService playersPool = Executors.newFixedThreadPool(2);
public void update() {

View File

@ -1,6 +1,8 @@
package fr.themode.minestom.entity.demo;
import fr.themode.minestom.Main;
import fr.themode.minestom.entity.EntityCreature;
import fr.themode.minestom.entity.Player;
public class ChickenCreature extends EntityCreature {
@ -12,10 +14,10 @@ public class ChickenCreature extends EntityCreature {
public void update() {
double speed = 0.075;
/*Player player = Main.getConnectionManager().getPlayer("TheMode911");
Player player = Main.getConnectionManager().getPlayer("TheMode911");
if (player != null) {
teleport(player.getX(), 5, player.getZ());
}*/
//teleport(player.getX(), 5, player.getZ());
}
move(0, 0, speed);
}

View File

@ -0,0 +1,67 @@
package fr.themode.minestom.instance;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class BlockBatch {
private static volatile ExecutorService batchesPool = Executors.newFixedThreadPool(2);
private Instance instance;
private Map<Chunk, List<BlockData>> data = new HashMap<>();
public BlockBatch(Instance instance) {
this.instance = instance;
}
public synchronized void setBlock(int x, int y, int z, Block block) {
final int chunkX = Math.floorDiv(x, 16);
final int chunkZ = Math.floorDiv(z, 16);
Chunk chunk = this.instance.getChunk(chunkX, chunkZ);
if (chunk == null)
chunk = this.instance.createChunk(Biome.VOID, chunkX, chunkZ);
List<BlockData> blockData = this.data.getOrDefault(chunk, new ArrayList<>());
BlockData data = new BlockData();
data.x = x % 16;
data.y = y;
data.z = z % 16;
data.block = block;
blockData.add(data);
this.data.put(chunk, blockData);
}
public void flush() {
for (Map.Entry<Chunk, List<BlockData>> entry : data.entrySet()) {
Chunk chunk = entry.getKey();
List<BlockData> dataList = entry.getValue();
synchronized (chunk) {
batchesPool.submit(() -> {
for (BlockData data : dataList) {
data.apply(chunk);
}
instance.sendChunkUpdate(chunk);
});
}
}
}
private class BlockData {
private int x, y, z;
private Block block;
public void apply(Chunk chunk) {
chunk.setBlock(x % 16, y, z % 16, block);
}
}
}

View File

@ -3,7 +3,6 @@ package fr.themode.minestom.instance;
import fr.themode.minestom.entity.Entity;
import fr.themode.minestom.entity.EntityCreature;
import fr.themode.minestom.entity.Player;
import fr.themode.minestom.net.packet.server.play.ChunkDataPacket;
import java.util.Collections;
import java.util.HashMap;
@ -17,7 +16,6 @@ public class Chunk {
private int chunkX, chunkZ;
private Biome biome;
private HashMap<Short, Block> blocks = new HashMap<>();
private ChunkDataPacket fullChunkPacket;
public Chunk(Biome biome, int chunkX, int chunkZ) {
this.biome = biome;
@ -90,15 +88,4 @@ public class Chunk {
public Set<Player> getPlayers() {
return Collections.unmodifiableSet(players);
}
private void refreshFullChunkPacket() {
ChunkDataPacket chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.fullChunk = true;
chunkDataPacket.chunk = this;
// TODO fill buffer
}
public ChunkDataPacket getFullChunkPacket() {
return fullChunkPacket;
}
}

View File

@ -35,10 +35,14 @@ public class Instance {
}
synchronized (chunk) {
chunk.setBlock(x % 16, y, z % 16, block);
sendChunkUpdate(chunk); // TODO partial chunk data
sendChunkUpdate(chunk);
}
}
public BlockBatch createBlockBatch() {
return new BlockBatch(this);
}
public Chunk getChunk(int chunkX, int chunkZ) {
for (Chunk chunk : getChunks()) {
if (chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ)
@ -102,7 +106,7 @@ public class Instance {
return uniqueId;
}
private Chunk createChunk(Biome biome, int chunkX, int chunkZ) {
protected Chunk createChunk(Biome biome, int chunkX, int chunkZ) {
Chunk chunk = new Chunk(biome, chunkX, chunkZ);
this.creatures.addCollection(chunk.creatures);
this.players.addCollection(chunk.players);
@ -110,6 +114,13 @@ public class Instance {
return chunk;
}
protected void sendChunkUpdate(Chunk chunk) {
ChunkDataPacket chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.fullChunk = true; // TODO partial chunk data
chunkDataPacket.chunk = chunk;
getPlayers().forEach(player -> player.getPlayerConnection().sendPacket(chunkDataPacket));
}
private void sendChunks(Player player) {
ChunkDataPacket chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.fullChunk = true;
@ -118,11 +129,4 @@ public class Instance {
player.getPlayerConnection().sendPacket(chunkDataPacket);
}
}
private void sendChunkUpdate(Chunk chunk) {
ChunkDataPacket chunkDataPacket = new ChunkDataPacket();
chunkDataPacket.fullChunk = true;
chunkDataPacket.chunk = chunk;
getPlayers().forEach(player -> player.getPlayerConnection().sendPacket(chunkDataPacket));
}
}

View File

@ -40,7 +40,7 @@ public class PacketProcessor {
public void process(Connection connection, Packet packet) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
int id = packet.get(PACKET_ID_IDENTIFIER);
System.out.println("RECEIVED ID: " + id);
// System.out.println("RECEIVED ID: " + id);
Buffer buffer = packet.getPayload();
connectionPlayerConnectionMap.get(connection);
PlayerConnection playerConnection = connectionPlayerConnectionMap.computeIfAbsent(connection, c -> new PlayerConnection(c));

View File

@ -103,8 +103,8 @@ public class LoginStartPacket implements ClientPreplayPacket {
playerInfoPacket.playerInfos.add(addPlayer);
connection.sendPacket(playerInfoPacket);
for (int x = -5; x < 5; x++)
for (int z = -5; z < 5; z++) {
for (int x = 0; x < 4; x++)
for (int z = 0; z < 4; z++) {
// TODO test entity
ChickenCreature chickenCreature = new ChickenCreature();
chickenCreature.refreshPosition(0 + (double) x * 1, 5, 0 + (double) z * 1);

View File

@ -3,6 +3,7 @@ package fr.themode.minestom.net.packet.client.play;
import fr.adamaq01.ozao.net.Buffer;
import fr.themode.minestom.entity.Player;
import fr.themode.minestom.instance.Block;
import fr.themode.minestom.instance.BlockBatch;
import fr.themode.minestom.instance.Instance;
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
import fr.themode.minestom.utils.Position;
@ -21,7 +22,13 @@ public class ClientPlayerBlockPlacementPacket implements ClientPlayPacket {
Instance instance = player.getInstance();
if (instance == null)
return;
instance.setBlock(position.getX(), position.getY(), position.getZ(), new Block(2));
BlockBatch blockBatch = instance.createBlockBatch();
for (int x = -64; x < 64; x++)
for (int z = -64; z < 64; z++) {
blockBatch.setBlock(x, position.getY() + 1, z, new Block(1));
}
blockBatch.flush();
}
@Override

View File

@ -7,7 +7,7 @@ public class GroupedCollections<E> implements Iterable<E> {
private Collection<Collection<E>> collections;
public GroupedCollections(Collection collection) {
public GroupedCollections(Collection<Collection<E>> collection) {
this.collections = collection;
}
@ -28,18 +28,6 @@ public class GroupedCollections<E> implements Iterable<E> {
return collections.stream().flatMap(Collection::stream).iterator();
}
/*public Object[] toArray() {
return collections.stream().flatMap(Collection::stream).collect(Collectors.toList()).toArray();
}
public <T> T[] toArray(T[] ts) {
return collections.stream().flatMap(Collection::stream).collect(Collectors.toList()).toArray(ts);
}
public boolean containsAll(Collection<?> collection) {
return collections.stream().flatMap(Collection::stream).collect(Collectors.toList()).containsAll(collection);
}*/
public void addCollection(Collection<E> list) {
this.collections.add(list);
}