Hopefully fixed #8 by enforcing only one change per tile per tick
- TickerCoordinator.pendingChanges is now a HashSet - TickerCoordinator now makes some best-effort checks to make sure the world does not change during evaluation phase - Extracted Cached{Block,Tile}Change - these classes implement hashCode() and equals() based on the location of the block/tile they affect, thus ensuring that only one per block/tile remain in the aforementioned set - Similarly extracted PacketAffect{Block,Tile,Entity} - Renamed a bunch of packets
This commit is contained in:
parent
cc031529a1
commit
daba418361
@ -7,7 +7,7 @@ import ru.windcorp.progressia.common.comms.CommsListener;
|
||||
import ru.windcorp.progressia.common.comms.packets.Packet;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
import ru.windcorp.progressia.common.world.PacketSetLocalPlayer;
|
||||
import ru.windcorp.progressia.common.world.PacketWorldChange;
|
||||
import ru.windcorp.progressia.common.world.PacketAffectWorld;
|
||||
|
||||
// TODO refactor with no mercy
|
||||
public class DefaultClientCommsListener implements CommsListener {
|
||||
@ -20,8 +20,8 @@ public class DefaultClientCommsListener implements CommsListener {
|
||||
|
||||
@Override
|
||||
public void onPacketReceived(Packet packet) {
|
||||
if (packet instanceof PacketWorldChange) {
|
||||
((PacketWorldChange) packet).apply(
|
||||
if (packet instanceof PacketAffectWorld) {
|
||||
((PacketAffectWorld) packet).apply(
|
||||
getClient().getWorld().getData()
|
||||
);
|
||||
} else if (packet instanceof PacketSetLocalPlayer) {
|
||||
|
@ -2,9 +2,9 @@ package ru.windcorp.progressia.common.world;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
|
||||
public abstract class PacketChunkChange extends PacketWorldChange {
|
||||
public abstract class PacketAffectChunk extends PacketAffectWorld {
|
||||
|
||||
public PacketChunkChange(String id) {
|
||||
public PacketAffectChunk(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ package ru.windcorp.progressia.common.world;
|
||||
|
||||
import ru.windcorp.progressia.common.comms.packets.Packet;
|
||||
|
||||
public abstract class PacketWorldChange extends Packet {
|
||||
public abstract class PacketAffectWorld extends Packet {
|
||||
|
||||
public PacketWorldChange(String id) {
|
||||
public PacketAffectWorld(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import java.io.IOException;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
|
||||
public class PacketRevokeChunk extends PacketChunkChange {
|
||||
public class PacketRevokeChunk extends PacketAffectChunk {
|
||||
|
||||
private final Vec3i position = new Vec3i();
|
||||
|
||||
|
@ -10,7 +10,7 @@ import ru.windcorp.progressia.common.state.IOContext;
|
||||
import ru.windcorp.progressia.common.util.DataBuffer;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
|
||||
public class PacketSendChunk extends PacketChunkChange {
|
||||
public class PacketSendChunk extends PacketAffectChunk {
|
||||
|
||||
private final DataBuffer data = new DataBuffer();
|
||||
private final Vec3i position = new Vec3i();
|
||||
|
@ -0,0 +1,45 @@
|
||||
package ru.windcorp.progressia.common.world.block;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketAffectChunk;
|
||||
|
||||
public abstract class PacketAffectBlock extends PacketAffectChunk {
|
||||
|
||||
private final Vec3i blockInWorld = new Vec3i();
|
||||
|
||||
public PacketAffectBlock(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Vec3i getBlockInWorld() {
|
||||
return blockInWorld;
|
||||
}
|
||||
|
||||
public void set(Vec3i blockInWorld) {
|
||||
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeInt(this.blockInWorld.x);
|
||||
output.writeInt(this.blockInWorld.y);
|
||||
output.writeInt(this.blockInWorld.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAffectedChunk(Vec3i output) {
|
||||
Coordinates.convertInWorldToChunk(this.blockInWorld, output);
|
||||
}
|
||||
|
||||
}
|
@ -5,15 +5,12 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketChunkChange;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
|
||||
public class PacketSetBlock extends PacketChunkChange {
|
||||
public class PacketSetBlock extends PacketAffectBlock {
|
||||
|
||||
private String id;
|
||||
private final Vec3i blockInWorld = new Vec3i();
|
||||
private String blockId;
|
||||
|
||||
public PacketSetBlock() {
|
||||
this("Core:SetBlock");
|
||||
@ -23,34 +20,31 @@ public class PacketSetBlock extends PacketChunkChange {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public String getBlockId() {
|
||||
return blockId;
|
||||
}
|
||||
|
||||
public void set(BlockData block, Vec3i blockInWorld) {
|
||||
this.id = block.getId();
|
||||
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
|
||||
super.set(blockInWorld);
|
||||
this.blockId = block.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.id = input.readUTF();
|
||||
this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt());
|
||||
super.read(input);
|
||||
this.blockId = input.readUTF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeUTF(this.id);
|
||||
output.writeInt(this.blockInWorld.x);
|
||||
output.writeInt(this.blockInWorld.y);
|
||||
output.writeInt(this.blockInWorld.z);
|
||||
super.write(output);
|
||||
output.writeUTF(this.blockId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(WorldData world) {
|
||||
BlockData block = BlockDataRegistry.getInstance().get(id);
|
||||
world.setBlock(blockInWorld, block, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAffectedChunk(Vec3i output) {
|
||||
Coordinates.convertInWorldToChunk(this.blockInWorld, output);
|
||||
BlockData block = BlockDataRegistry.getInstance().get(getBlockId());
|
||||
world.setBlock(getBlockInWorld(), block, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,42 @@
|
||||
package ru.windcorp.progressia.common.world.entity;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketAffectWorld;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
|
||||
public class PacketAffectEntity extends PacketAffectWorld {
|
||||
|
||||
private long entityId;
|
||||
|
||||
public PacketAffectEntity(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public long getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void set(long entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.entityId = input.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeLong(this.entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(WorldData world) {
|
||||
world.removeEntity(this.entityId);
|
||||
}
|
||||
|
||||
}
|
@ -8,44 +8,27 @@ import ru.windcorp.progressia.common.state.IOContext;
|
||||
import ru.windcorp.progressia.common.util.DataBuffer;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketWorldChange;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
|
||||
public class PacketEntityChange extends PacketWorldChange {
|
||||
public class PacketChangeEntity extends PacketAffectEntity {
|
||||
|
||||
private long entityId;
|
||||
private final DataBuffer buffer = new DataBuffer();
|
||||
|
||||
public PacketEntityChange() {
|
||||
public PacketChangeEntity() {
|
||||
super("Core:EntityChange");
|
||||
}
|
||||
|
||||
protected PacketEntityChange(String id) {
|
||||
protected PacketChangeEntity(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public long getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void setEntityId(long entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public DataBuffer getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public DataInput getReader() {
|
||||
return buffer.getReader();
|
||||
}
|
||||
|
||||
public DataOutput getWriter() {
|
||||
return buffer.getWriter();
|
||||
}
|
||||
|
||||
public void set(EntityData entity) {
|
||||
this.entityId = entity.getEntityId();
|
||||
super.set(entity.getEntityId());
|
||||
|
||||
try {
|
||||
entity.write(this.buffer.getWriter(), IOContext.COMMS);
|
||||
} catch (IOException e) {
|
||||
@ -55,13 +38,13 @@ public class PacketEntityChange extends PacketWorldChange {
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.entityId = input.readLong();
|
||||
super.read(input);
|
||||
this.buffer.fill(input, input.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeLong(this.entityId);
|
||||
super.write(output);
|
||||
output.writeInt(this.buffer.getSize());
|
||||
this.buffer.flush(output);
|
||||
}
|
||||
@ -75,7 +58,7 @@ public class PacketEntityChange extends PacketWorldChange {
|
||||
}
|
||||
|
||||
try {
|
||||
entity.read(getReader(), IOContext.COMMS);
|
||||
entity.read(getBuffer().getReader(), IOContext.COMMS);
|
||||
} catch (IOException e) {
|
||||
throw CrashReports.report(e, "Entity could not be read");
|
||||
}
|
@ -4,12 +4,10 @@ import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import ru.windcorp.progressia.common.world.PacketWorldChange;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
|
||||
public class PacketRevokeEntity extends PacketWorldChange {
|
||||
|
||||
private long entityId;
|
||||
public class PacketRevokeEntity extends PacketAffectEntity {
|
||||
|
||||
public PacketRevokeEntity() {
|
||||
this("Core:RevokeEntity");
|
||||
@ -19,23 +17,24 @@ public class PacketRevokeEntity extends PacketWorldChange {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(long entityId) {
|
||||
this.entityId = entityId;
|
||||
super.set(entityId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException {
|
||||
this.entityId = input.readLong();
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
super.read(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeLong(this.entityId);
|
||||
super.write(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(WorldData world) {
|
||||
world.removeEntity(this.entityId);
|
||||
world.removeEntity(getEntityId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,13 +8,11 @@ import ru.windcorp.progressia.common.state.IOContext;
|
||||
import ru.windcorp.progressia.common.util.DataBuffer;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketWorldChange;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
|
||||
public class PacketSendEntity extends PacketWorldChange {
|
||||
public class PacketSendEntity extends PacketAffectEntity {
|
||||
|
||||
private String id;
|
||||
private long entityId;
|
||||
private String entityTypeId;
|
||||
private final DataBuffer buffer = new DataBuffer();
|
||||
|
||||
public PacketSendEntity() {
|
||||
@ -25,9 +23,23 @@ public class PacketSendEntity extends PacketWorldChange {
|
||||
super(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text ID of the entity added by this packet.
|
||||
* @return text ID
|
||||
* @see #getEntityId()
|
||||
*/
|
||||
public String getEntityTypeId() {
|
||||
return entityTypeId;
|
||||
}
|
||||
|
||||
public DataBuffer getBuffer() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public void set(EntityData entity) {
|
||||
this.id = entity.getId();
|
||||
this.entityId = entity.getEntityId();
|
||||
super.set(entity.getEntityId());
|
||||
|
||||
this.entityTypeId = entity.getId();
|
||||
|
||||
try {
|
||||
entity.write(this.buffer.getWriter(), IOContext.COMMS);
|
||||
@ -38,26 +50,28 @@ public class PacketSendEntity extends PacketWorldChange {
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.id = input.readUTF();
|
||||
this.entityId = input.readLong();
|
||||
super.read(input);
|
||||
|
||||
this.entityTypeId = input.readUTF();
|
||||
this.buffer.fill(input, input.readInt());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeUTF(this.id);
|
||||
output.writeLong(this.entityId);
|
||||
super.write(output);
|
||||
|
||||
output.writeUTF(this.entityTypeId);
|
||||
output.writeInt(this.buffer.getSize());
|
||||
this.buffer.flush(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(WorldData world) {
|
||||
EntityData entity = EntityDataRegistry.getInstance().create(this.id);
|
||||
EntityData entity = EntityDataRegistry.getInstance().create(getEntityTypeId());
|
||||
|
||||
entity.setEntityId(this.entityId);
|
||||
entity.setEntityId(getEntityId());
|
||||
try {
|
||||
entity.read(this.buffer.getReader(), IOContext.COMMS);
|
||||
entity.read(getBuffer().getReader(), IOContext.COMMS);
|
||||
} catch (IOException e) {
|
||||
throw CrashReports.report(e, "Could not read an entity from an internal buffer");
|
||||
}
|
||||
|
@ -5,17 +5,13 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketChunkChange;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
|
||||
public class PacketAddTile extends PacketChunkChange {
|
||||
public class PacketAddTile extends PacketAffectTile {
|
||||
|
||||
private String id;
|
||||
private final Vec3i blockInWorld = new Vec3i();
|
||||
private BlockFace face;
|
||||
private String tileId;
|
||||
|
||||
public PacketAddTile() {
|
||||
this("Core:AddTile");
|
||||
@ -25,37 +21,31 @@ public class PacketAddTile extends PacketChunkChange {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public String getTileId() {
|
||||
return tileId;
|
||||
}
|
||||
|
||||
public void set(TileData tile, Vec3i blockInWorld, BlockFace face) {
|
||||
this.id = tile.getId();
|
||||
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
|
||||
this.face = face;
|
||||
super.set(blockInWorld, face, -1);
|
||||
this.tileId = tile.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.id = input.readUTF();
|
||||
this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt());
|
||||
this.face = BlockFace.getFaces().get(input.readByte());
|
||||
super.read(input);
|
||||
this.tileId = input.readUTF();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeUTF(this.id);
|
||||
output.writeInt(this.blockInWorld.x);
|
||||
output.writeInt(this.blockInWorld.y);
|
||||
output.writeInt(this.blockInWorld.z);
|
||||
output.writeByte(this.face.getId());
|
||||
super.write(output);
|
||||
output.writeUTF(this.tileId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(WorldData world) {
|
||||
TileData tile = TileDataRegistry.getInstance().get(id);
|
||||
world.getTiles(blockInWorld, face).add(tile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAffectedChunk(Vec3i output) {
|
||||
Coordinates.convertInWorldToChunk(this.blockInWorld, output);
|
||||
TileData tile = TileDataRegistry.getInstance().get(getTileId());
|
||||
world.getTiles(getBlockInWorld(), getFace()).add(tile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
package ru.windcorp.progressia.common.world.tile;
|
||||
|
||||
import java.io.DataInput;
|
||||
import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketAffectChunk;
|
||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
|
||||
public abstract class PacketAffectTile extends PacketAffectChunk {
|
||||
|
||||
private final Vec3i blockInWorld = new Vec3i();
|
||||
private BlockFace face;
|
||||
private int tag;
|
||||
|
||||
public PacketAffectTile(String id) {
|
||||
super(id);
|
||||
}
|
||||
|
||||
public Vec3i getBlockInWorld() {
|
||||
return blockInWorld;
|
||||
}
|
||||
|
||||
public BlockFace getFace() {
|
||||
return face;
|
||||
}
|
||||
|
||||
public int getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void set(Vec3i blockInWorld, BlockFace face, int tag) {
|
||||
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
|
||||
this.face = face;
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt());
|
||||
this.face = BlockFace.getFaces().get(input.readByte());
|
||||
this.tag = input.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeInt(this.blockInWorld.x);
|
||||
output.writeInt(this.blockInWorld.y);
|
||||
output.writeInt(this.blockInWorld.z);
|
||||
output.writeByte(this.face.getId());
|
||||
output.writeInt(this.tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAffectedChunk(Vec3i output) {
|
||||
Coordinates.convertInWorldToChunk(this.blockInWorld, output);
|
||||
}
|
||||
|
||||
}
|
@ -5,17 +5,12 @@ import java.io.DataOutput;
|
||||
import java.io.IOException;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.Coordinates;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
import ru.windcorp.progressia.common.world.DecodingException;
|
||||
import ru.windcorp.progressia.common.world.PacketChunkChange;
|
||||
import ru.windcorp.progressia.common.world.WorldData;
|
||||
import ru.windcorp.progressia.common.world.block.BlockFace;
|
||||
|
||||
public class PacketRemoveTile extends PacketChunkChange {
|
||||
|
||||
private final Vec3i blockInWorld = new Vec3i();
|
||||
private BlockFace face;
|
||||
private int tag;
|
||||
public class PacketRemoveTile extends PacketAffectTile {
|
||||
|
||||
public PacketRemoveTile() {
|
||||
this("Core:RemoveTile");
|
||||
@ -25,37 +20,37 @@ public class PacketRemoveTile extends PacketChunkChange {
|
||||
super(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(Vec3i blockInWorld, BlockFace face, int tag) {
|
||||
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
|
||||
this.face = face;
|
||||
this.tag = tag;
|
||||
super.set(blockInWorld, face, tag);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(DataInput input) throws IOException, DecodingException {
|
||||
this.blockInWorld.set(input.readInt(), input.readInt(), input.readInt());
|
||||
this.face = BlockFace.getFaces().get(input.readByte());
|
||||
this.tag = input.readInt();
|
||||
super.read(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(DataOutput output) throws IOException {
|
||||
output.writeInt(this.blockInWorld.x);
|
||||
output.writeInt(this.blockInWorld.y);
|
||||
output.writeInt(this.blockInWorld.z);
|
||||
output.writeByte(this.face.getId());
|
||||
output.writeInt(this.tag);
|
||||
super.write(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(WorldData world) {
|
||||
TileDataStack stack = world.getTiles(blockInWorld, face);
|
||||
stack.remove(stack.getIndexByTag(tag));
|
||||
TileDataStack stack = world.getTiles(getBlockInWorld(), getFace());
|
||||
|
||||
int index = stack.getIndexByTag(getTag());
|
||||
|
||||
if (index < 0) {
|
||||
throw CrashReports.report(null,
|
||||
"Could not find tile with tag %d at (%d; %d; %d; %s)",
|
||||
getTag(),
|
||||
getBlockInWorld().x, getBlockInWorld().y, getBlockInWorld().z,
|
||||
getFace()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getAffectedChunk(Vec3i output) {
|
||||
Coordinates.convertInWorldToChunk(this.blockInWorld, output);
|
||||
stack.remove(index);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class TickAndUpdateUtil {
|
||||
try {
|
||||
block.tick(context);
|
||||
} catch (Exception e) {
|
||||
throw CrashReports.report(e, "Could not tick block {}", block);
|
||||
throw CrashReports.report(e, "Could not tick block %s", block);
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,7 @@ public class TickAndUpdateUtil {
|
||||
try {
|
||||
tile.tick(context);
|
||||
} catch (Exception e) {
|
||||
throw CrashReports.report(e, "Could not tick tile {}", tile);
|
||||
throw CrashReports.report(e, "Could not tick tile %s", tile);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import ru.windcorp.progressia.common.world.tile.PacketAddTile;
|
||||
|
||||
class AddTile extends CachedChunkChange<PacketAddTile> {
|
||||
class AddTile extends CachedTileChange<PacketAddTile> {
|
||||
|
||||
public AddTile(Consumer<? super CachedChange> disposer) {
|
||||
super(disposer, new PacketAddTile());
|
||||
|
@ -0,0 +1,45 @@
|
||||
package ru.windcorp.progressia.server.world.tasks;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import glm.Glm;
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.block.PacketAffectBlock;
|
||||
|
||||
public class CachedBlockChange<P extends PacketAffectBlock> extends CachedChunkChange<P> {
|
||||
|
||||
public CachedBlockChange(Consumer<? super CachedChange> disposer, P packet) {
|
||||
super(disposer, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
PacketAffectBlock packet = getPacket();
|
||||
Vec3i biw = packet.getBlockInWorld();
|
||||
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + biw.x;
|
||||
result = prime * result + biw.y;
|
||||
result = prime * result + biw.z;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
|
||||
PacketAffectBlock my = getPacket();
|
||||
PacketAffectBlock other = ((CachedBlockChange<?>) obj).getPacket();
|
||||
|
||||
return Glm.equals(my.getBlockInWorld(), other.getBlockInWorld());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
Vec3i biw = getPacket().getBlockInWorld();
|
||||
|
||||
return getClass().getSimpleName() + " (" + biw.x + "; " + biw.y + "; " + biw.z + ")";
|
||||
}
|
||||
|
||||
}
|
@ -3,9 +3,9 @@ package ru.windcorp.progressia.server.world.tasks;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.PacketChunkChange;
|
||||
import ru.windcorp.progressia.common.world.PacketAffectChunk;
|
||||
|
||||
public abstract class CachedChunkChange<P extends PacketChunkChange> extends CachedWorldChange<P> {
|
||||
public abstract class CachedChunkChange<P extends PacketAffectChunk> extends CachedWorldChange<P> {
|
||||
|
||||
public CachedChunkChange(Consumer<? super CachedChange> disposer, P packet) {
|
||||
super(disposer, packet);
|
||||
|
@ -0,0 +1,54 @@
|
||||
package ru.windcorp.progressia.server.world.tasks;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import glm.Glm;
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.tile.PacketAffectTile;
|
||||
|
||||
public class CachedTileChange<P extends PacketAffectTile> extends CachedChunkChange<P> {
|
||||
|
||||
public CachedTileChange(Consumer<? super CachedChange> disposer, P packet) {
|
||||
super(disposer, packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
PacketAffectTile packet = getPacket();
|
||||
Vec3i biw = packet.getBlockInWorld();
|
||||
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + biw.x;
|
||||
result = prime * result + biw.y;
|
||||
result = prime * result + biw.z;
|
||||
result = prime * result + Objects.hashCode(packet.getFace());
|
||||
result = prime * result + packet.getTag();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof CachedTileChange<?>)) return false;
|
||||
|
||||
PacketAffectTile my = getPacket();
|
||||
PacketAffectTile other = ((CachedTileChange<?>) obj).getPacket();
|
||||
|
||||
// Tag of -1 signals that we should ignore it
|
||||
if (my.getTag() == -1 || other.getTag() == -1) return false;
|
||||
|
||||
return Glm.equals(my.getBlockInWorld(), other.getBlockInWorld())
|
||||
&& (my.getFace() == other.getFace())
|
||||
&& (my.getTag() == other.getTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
PacketAffectTile packet = getPacket();
|
||||
Vec3i biw = packet.getBlockInWorld();
|
||||
|
||||
return getClass().getSimpleName() + " (" + biw.x + "; " + biw.y + "; " + biw.z + "; " + packet.getFace() + "; tag: " + packet.getTag() + ")";
|
||||
}
|
||||
|
||||
}
|
@ -4,10 +4,10 @@ import java.util.function.Consumer;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.util.Vectors;
|
||||
import ru.windcorp.progressia.common.world.PacketWorldChange;
|
||||
import ru.windcorp.progressia.common.world.PacketAffectWorld;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
|
||||
public abstract class CachedWorldChange<P extends PacketWorldChange> extends CachedChange {
|
||||
public abstract class CachedWorldChange<P extends PacketAffectWorld> extends CachedChange {
|
||||
|
||||
private final P packet;
|
||||
|
||||
|
@ -4,7 +4,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import glm.vec._3.i.Vec3i;
|
||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||
import ru.windcorp.progressia.common.world.entity.PacketEntityChange;
|
||||
import ru.windcorp.progressia.common.world.entity.PacketChangeEntity;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
|
||||
class ChangeEntity extends CachedChange {
|
||||
@ -12,7 +12,7 @@ class ChangeEntity extends CachedChange {
|
||||
private EntityData entity;
|
||||
private StateChange<?> change;
|
||||
|
||||
private final PacketEntityChange packet = new PacketEntityChange();
|
||||
private final PacketChangeEntity packet = new PacketChangeEntity();
|
||||
|
||||
public ChangeEntity(Consumer<? super CachedChange> disposer) {
|
||||
super(disposer);
|
||||
@ -56,4 +56,15 @@ class ChangeEntity extends CachedChange {
|
||||
this.change = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return System.identityHashCode(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof ChangeEntity)) return false;
|
||||
return ((ChangeEntity) obj).entity == entity;
|
||||
}
|
||||
|
||||
}
|
@ -4,7 +4,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import ru.windcorp.progressia.common.world.tile.PacketRemoveTile;
|
||||
|
||||
class RemoveTile extends CachedChunkChange<PacketRemoveTile> {
|
||||
class RemoveTile extends CachedTileChange<PacketRemoveTile> {
|
||||
|
||||
public RemoveTile(Consumer<? super CachedChange> disposer) {
|
||||
super(disposer, new PacketRemoveTile());
|
||||
|
@ -4,7 +4,7 @@ import java.util.function.Consumer;
|
||||
|
||||
import ru.windcorp.progressia.common.world.block.PacketSetBlock;
|
||||
|
||||
class SetBlock extends CachedChunkChange<PacketSetBlock> {
|
||||
class SetBlock extends CachedBlockChange<PacketSetBlock> {
|
||||
|
||||
public SetBlock(Consumer<? super CachedChange> disposer) {
|
||||
super(disposer, new PacketSetBlock());
|
||||
|
@ -24,4 +24,16 @@ public abstract class Change extends TickerTask {
|
||||
affect(server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
// Use instance hash code by default
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Use instance-based equals() by default
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package ru.windcorp.progressia.server.world.ticking;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
@ -14,6 +16,9 @@ import com.google.common.collect.ImmutableList;
|
||||
|
||||
import ru.windcorp.progressia.common.Units;
|
||||
import ru.windcorp.progressia.common.util.crash.CrashReports;
|
||||
import ru.windcorp.progressia.common.world.ChunkData;
|
||||
import ru.windcorp.progressia.common.world.ChunkDataListener;
|
||||
import ru.windcorp.progressia.common.world.ChunkDataListeners;
|
||||
import ru.windcorp.progressia.server.Server;
|
||||
|
||||
/**
|
||||
@ -28,7 +33,7 @@ public class TickerCoordinator {
|
||||
private final Server server;
|
||||
|
||||
// Synchronized manually
|
||||
private final Collection<Change> pendingChanges = new ArrayList<>(INITIAL_QUEUE_SIZE);
|
||||
private final Collection<Change> pendingChanges = new HashSet<>(INITIAL_QUEUE_SIZE);
|
||||
// Synchronized manually
|
||||
private final Collection<Evaluation> pendingEvaluations = new ArrayList<>(INITIAL_QUEUE_SIZE);
|
||||
|
||||
@ -49,6 +54,8 @@ public class TickerCoordinator {
|
||||
|
||||
private final AtomicInteger workingTickers = new AtomicInteger();
|
||||
|
||||
private final AtomicBoolean canChange = new AtomicBoolean(true);
|
||||
|
||||
private boolean isTickStartSet = false;
|
||||
private long tickStart = -1;
|
||||
private double tickLength = 1.0 / 20; // Do something about it
|
||||
@ -66,6 +73,15 @@ public class TickerCoordinator {
|
||||
|
||||
this.tickers = ImmutableList.copyOf(tickerCollection);
|
||||
this.threads = Collections2.transform(this.tickers, Ticker::getThread); // Immutable because it is a view
|
||||
|
||||
server.getWorld().getData().addListener(ChunkDataListeners.createAdder(new ChunkDataListener() {
|
||||
@Override
|
||||
public void onChunkChanged(ChunkData chunk) {
|
||||
if (!canChange.get()) {
|
||||
throw CrashReports.report(null, "A change has been detected during evaluation phase");
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -157,7 +173,9 @@ public class TickerCoordinator {
|
||||
}
|
||||
|
||||
private synchronized void runOnePass() throws InterruptedException {
|
||||
canChange.set(false);
|
||||
runPassStage(pendingEvaluations, "EVALUATION");
|
||||
canChange.set(true);
|
||||
runPassStage(pendingChanges, "CHANGE");
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user