Spread chunk updates over several frames
- At most 1 chunk is updated (previously known as 'buildModel') every frame - 3x3x3 chunks closest to the player are updated in real-time without the aforementioned limit
This commit is contained in:
parent
5d570a810b
commit
c9087e7215
@ -19,7 +19,7 @@ public class Client {
|
|||||||
private final ServerCommsChannel comms;
|
private final ServerCommsChannel comms;
|
||||||
|
|
||||||
public Client(WorldData world, ServerCommsChannel comms) {
|
public Client(WorldData world, ServerCommsChannel comms) {
|
||||||
this.world = new WorldRender(world);
|
this.world = new WorldRender(world, this);
|
||||||
this.comms = comms;
|
this.comms = comms;
|
||||||
|
|
||||||
comms.addListener(new DefaultClientCommsListener(this));
|
comms.addListener(new DefaultClientCommsListener(this));
|
||||||
|
@ -59,7 +59,6 @@ implements GenericChunk<
|
|||||||
private final WorldRender world;
|
private final WorldRender world;
|
||||||
private final ChunkData data;
|
private final ChunkData data;
|
||||||
|
|
||||||
private boolean needsUpdate;
|
|
||||||
private Model model = null;
|
private Model model = null;
|
||||||
|
|
||||||
private final Map<TileDataStack, TileRenderStackImpl> tileRenderLists =
|
private final Map<TileDataStack, TileRenderStackImpl> tileRenderLists =
|
||||||
@ -108,16 +107,12 @@ implements GenericChunk<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void markForUpdate() {
|
public synchronized void markForUpdate() {
|
||||||
this.needsUpdate = true;
|
getWorld().markChunkForUpdate(getPosition());
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized boolean needsUpdate() {
|
|
||||||
return needsUpdate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void render(ShapeRenderHelper renderer) {
|
public synchronized void render(ShapeRenderHelper renderer) {
|
||||||
if (model == null || needsUpdate()) {
|
if (model == null) {
|
||||||
buildModel();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.pushTransform().translate(
|
renderer.pushTransform().translate(
|
||||||
@ -131,7 +126,7 @@ implements GenericChunk<
|
|||||||
renderer.popTransform();
|
renderer.popTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildModel() {
|
public synchronized void update() {
|
||||||
Collection<ChunkRenderOptimizer> optimizers =
|
Collection<ChunkRenderOptimizer> optimizers =
|
||||||
ChunkRenderOptimizers.getAllSuppliers().stream()
|
ChunkRenderOptimizers.getAllSuppliers().stream()
|
||||||
.map(ChunkRenderOptimizerSupplier::createOptimizer)
|
.map(ChunkRenderOptimizerSupplier::createOptimizer)
|
||||||
@ -159,7 +154,6 @@ implements GenericChunk<
|
|||||||
.forEach(builder::addPart);
|
.forEach(builder::addPart);
|
||||||
|
|
||||||
model = new StaticModel(builder);
|
model = new StaticModel(builder);
|
||||||
needsUpdate = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void buildBlock(
|
private void buildBlock(
|
||||||
|
@ -20,10 +20,12 @@ package ru.windcorp.progressia.client.world;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
|
import ru.windcorp.progressia.client.Client;
|
||||||
import ru.windcorp.progressia.client.graphics.backend.FaceCulling;
|
import ru.windcorp.progressia.client.graphics.backend.FaceCulling;
|
||||||
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
import ru.windcorp.progressia.client.graphics.model.ShapeRenderHelper;
|
||||||
import ru.windcorp.progressia.client.world.block.BlockRender;
|
import ru.windcorp.progressia.client.world.block.BlockRender;
|
||||||
@ -31,11 +33,14 @@ import ru.windcorp.progressia.client.world.entity.EntityRenderRegistry;
|
|||||||
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
import ru.windcorp.progressia.client.world.entity.EntityRenderable;
|
||||||
import ru.windcorp.progressia.client.world.tile.TileRender;
|
import ru.windcorp.progressia.client.world.tile.TileRender;
|
||||||
import ru.windcorp.progressia.client.world.tile.TileRenderStack;
|
import ru.windcorp.progressia.client.world.tile.TileRenderStack;
|
||||||
|
import ru.windcorp.progressia.common.util.VectorUtil;
|
||||||
import ru.windcorp.progressia.common.world.ChunkData;
|
import ru.windcorp.progressia.common.world.ChunkData;
|
||||||
import ru.windcorp.progressia.common.world.ChunkDataListeners;
|
import ru.windcorp.progressia.common.world.ChunkDataListeners;
|
||||||
import ru.windcorp.progressia.common.world.WorldData;
|
import ru.windcorp.progressia.common.world.WorldData;
|
||||||
import ru.windcorp.progressia.common.world.WorldDataListener;
|
import ru.windcorp.progressia.common.world.WorldDataListener;
|
||||||
import ru.windcorp.progressia.common.world.entity.EntityData;
|
import ru.windcorp.progressia.common.world.entity.EntityData;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.ChunkSet;
|
||||||
|
import ru.windcorp.progressia.common.world.generic.ChunkSets;
|
||||||
import ru.windcorp.progressia.common.world.generic.GenericWorld;
|
import ru.windcorp.progressia.common.world.generic.GenericWorld;
|
||||||
|
|
||||||
public class WorldRender
|
public class WorldRender
|
||||||
@ -48,33 +53,50 @@ implements GenericWorld<
|
|||||||
> {
|
> {
|
||||||
|
|
||||||
private final WorldData data;
|
private final WorldData data;
|
||||||
|
private final Client client;
|
||||||
|
|
||||||
private final Map<ChunkData, ChunkRender> chunks =
|
private final Map<ChunkData, ChunkRender> chunks =
|
||||||
Collections.synchronizedMap(new HashMap<>());
|
Collections.synchronizedMap(new HashMap<>());
|
||||||
private final Map<EntityData, EntityRenderable> entityModels =
|
private final Map<EntityData, EntityRenderable> entityModels =
|
||||||
Collections.synchronizedMap(new WeakHashMap<>());
|
Collections.synchronizedMap(new WeakHashMap<>());
|
||||||
|
|
||||||
public WorldRender(WorldData data) {
|
private final ChunkSet chunksToUpdate = ChunkSets.newSyncHashSet();
|
||||||
|
|
||||||
|
public WorldRender(WorldData data, Client client) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
data.addListener(ChunkDataListeners.createAdder(new ChunkUpdateListener(this)));
|
data.addListener(ChunkDataListeners.createAdder(new ChunkUpdateListener(this)));
|
||||||
data.addListener(new WorldDataListener() {
|
data.addListener(new WorldDataListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onChunkLoaded(WorldData world, ChunkData chunk) {
|
public void onChunkLoaded(WorldData world, ChunkData chunk) {
|
||||||
chunks.put(chunk, new ChunkRender(WorldRender.this, chunk));
|
addChunk(chunk);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeChunkUnloaded(WorldData world, ChunkData chunk) {
|
public void beforeChunkUnloaded(WorldData world, ChunkData chunk) {
|
||||||
chunks.remove(chunk);
|
removeChunk(chunk);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void addChunk(ChunkData chunk) {
|
||||||
|
chunks.put(chunk, new ChunkRender(WorldRender.this, chunk));
|
||||||
|
markChunkForUpdate(chunk.getPosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void removeChunk(ChunkData chunk) {
|
||||||
|
chunks.remove(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
public WorldData getData() {
|
public WorldData getData() {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Client getClient() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
public ChunkRender getChunk(ChunkData chunkData) {
|
public ChunkRender getChunk(ChunkData chunkData) {
|
||||||
return chunks.get(chunkData);
|
return chunks.get(chunkData);
|
||||||
}
|
}
|
||||||
@ -95,10 +117,67 @@ implements GenericWorld<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void render(ShapeRenderHelper renderer) {
|
public void render(ShapeRenderHelper renderer) {
|
||||||
|
updateChunks();
|
||||||
|
|
||||||
getChunks().forEach(chunk -> chunk.render(renderer));
|
getChunks().forEach(chunk -> chunk.render(renderer));
|
||||||
renderEntities(renderer);
|
renderEntities(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateChunks() {
|
||||||
|
synchronized (chunksToUpdate) {
|
||||||
|
if (chunksToUpdate.isEmpty()) return;
|
||||||
|
|
||||||
|
int updates = updateChunksNearLocalPlayer();
|
||||||
|
int maximumUpdates = getMaximumChunkUpdatesPerFrame();
|
||||||
|
|
||||||
|
updateRandomChunks(maximumUpdates - updates);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int updateChunksNearLocalPlayer() {
|
||||||
|
EntityData entity = getClient().getLocalPlayer().getEntity();
|
||||||
|
if (entity == null) return 0;
|
||||||
|
|
||||||
|
int[] updates = new int[] { 0 };
|
||||||
|
|
||||||
|
VectorUtil.iterateCuboidAround(entity.getChunkCoords(null), 3, chunkPos -> {
|
||||||
|
if (chunksToUpdate.contains(chunkPos)) {
|
||||||
|
getChunk(chunkPos).update();
|
||||||
|
chunksToUpdate.remove(chunkPos);
|
||||||
|
|
||||||
|
updates[0]++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return updates[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRandomChunks(int allowedUpdates) {
|
||||||
|
if (allowedUpdates <= 0) return;
|
||||||
|
|
||||||
|
for (Iterator<Vec3i> it = chunksToUpdate.iterator(); it.hasNext();) {
|
||||||
|
Vec3i chunkPos = it.next();
|
||||||
|
ChunkRender chunk = getChunk(chunkPos);
|
||||||
|
|
||||||
|
if (chunk != null) {
|
||||||
|
chunk.update();
|
||||||
|
allowedUpdates--;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.remove();
|
||||||
|
|
||||||
|
if (allowedUpdates <= 0) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getMaximumChunkUpdatesPerFrame() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPendingChunkUpdates() {
|
||||||
|
return chunksToUpdate.size();
|
||||||
|
}
|
||||||
|
|
||||||
private void renderEntities(ShapeRenderHelper renderer) {
|
private void renderEntities(ShapeRenderHelper renderer) {
|
||||||
FaceCulling.push(false);
|
FaceCulling.push(false);
|
||||||
|
|
||||||
@ -123,4 +202,10 @@ implements GenericWorld<
|
|||||||
.createRenderable(entity);
|
.createRenderable(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void markChunkForUpdate(Vec3i chunkPos) {
|
||||||
|
if (getData().getChunk(chunkPos) != null) {
|
||||||
|
chunksToUpdate.add(chunkPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ public class VectorUtil {
|
|||||||
X, Y, Z, W;
|
X, Y, Z, W;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forEachVectorInCuboid(
|
public static void iterateCuboid(
|
||||||
int x0, int y0, int z0,
|
int x0, int y0, int z0,
|
||||||
int x1, int y1, int z1,
|
int x1, int y1, int z1,
|
||||||
Consumer<? super Vec3i> action
|
Consumer<? super Vec3i> action
|
||||||
@ -38,6 +38,57 @@ public class VectorUtil {
|
|||||||
Vectors.release(cursor);
|
Vectors.release(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void iterateCuboid(
|
||||||
|
Vec3i vMin, Vec3i vMax,
|
||||||
|
Consumer<? super Vec3i> action
|
||||||
|
) {
|
||||||
|
iterateCuboid(vMin.x, vMin.y, vMin.z, vMax.x, vMax.y, vMax.z, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void iterateCuboidAround(
|
||||||
|
int cx, int cy, int cz,
|
||||||
|
int dx, int dy, int dz,
|
||||||
|
Consumer<? super Vec3i> action
|
||||||
|
) {
|
||||||
|
if (dx < 0) throw new IllegalArgumentException("dx " + dx + " is negative");
|
||||||
|
if (dy < 0) throw new IllegalArgumentException("dy " + dx + " is negative");
|
||||||
|
if (dz < 0) throw new IllegalArgumentException("dz " + dx + " is negative");
|
||||||
|
|
||||||
|
if (dx % 2 == 0) throw new IllegalArgumentException("dx " + dx + " is even, only odd accepted");
|
||||||
|
if (dy % 2 == 0) throw new IllegalArgumentException("dy " + dy + " is even, only odd accepted");
|
||||||
|
if (dz % 2 == 0) throw new IllegalArgumentException("dz " + dz + " is even, only odd accepted");
|
||||||
|
|
||||||
|
dx /= 2;
|
||||||
|
dy /= 2;
|
||||||
|
dz /= 2;
|
||||||
|
|
||||||
|
iterateCuboid(cx - dx, cy - dy, cz - dz, cx + dx + 1, cy + dy + 1, cz + dz + 1, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void iterateCuboidAround(
|
||||||
|
Vec3i center,
|
||||||
|
Vec3i diameters,
|
||||||
|
Consumer<? super Vec3i> action
|
||||||
|
) {
|
||||||
|
iterateCuboidAround(center.x, center.y, center.z, diameters.x, diameters.y, diameters.z, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void iterateCuboidAround(
|
||||||
|
int cx, int cy, int cz,
|
||||||
|
int diameter,
|
||||||
|
Consumer<? super Vec3i> action
|
||||||
|
) {
|
||||||
|
iterateCuboidAround(cx, cy, cz, diameter, diameter, diameter, action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void iterateCuboidAround(
|
||||||
|
Vec3i center,
|
||||||
|
int diameter,
|
||||||
|
Consumer<? super Vec3i> action
|
||||||
|
) {
|
||||||
|
iterateCuboidAround(center.x, center.y, center.z, diameter, action);
|
||||||
|
}
|
||||||
|
|
||||||
public static void applyMat4(Vec3 in, Mat4 mat, Vec3 out) {
|
public static void applyMat4(Vec3 in, Mat4 mat, Vec3 out) {
|
||||||
Vec4 vec4 = Vectors.grab4();
|
Vec4 vec4 = Vectors.grab4();
|
||||||
vec4.set(in, 1f);
|
vec4.set(in, 1f);
|
||||||
|
@ -183,7 +183,7 @@ implements GenericChunk<
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void forEachBlock(Consumer<Vec3i> action) {
|
public void forEachBlock(Consumer<Vec3i> action) {
|
||||||
VectorUtil.forEachVectorInCuboid(
|
VectorUtil.iterateCuboid(
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK,
|
BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK,
|
||||||
action
|
action
|
||||||
|
@ -2,9 +2,11 @@ package ru.windcorp.progressia.common.world.generic;
|
|||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import glm.vec._3.i.Vec3i;
|
import glm.vec._3.i.Vec3i;
|
||||||
import gnu.trove.impl.sync.TSynchronizedLongSet;
|
|
||||||
import gnu.trove.set.hash.TLongHashSet;
|
import gnu.trove.set.hash.TLongHashSet;
|
||||||
|
|
||||||
public class ChunkSets {
|
public class ChunkSets {
|
||||||
@ -14,13 +16,19 @@ public class ChunkSets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkSet newSyncHashSet(Object mutex) {
|
public static ChunkSet newSyncHashSet(Object mutex) {
|
||||||
return new LongBasedChunkSet(new TSynchronizedLongSet(new TLongHashSet(), mutex));
|
return new SynchronizedChunkSet(new LongBasedChunkSet(new TLongHashSet()), mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChunkSet newSyncHashSet() {
|
public static ChunkSet newSyncHashSet() {
|
||||||
return new LongBasedChunkSet(new TSynchronizedLongSet(new TLongHashSet()));
|
return newSyncHashSet(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ChunkSet empty() {
|
||||||
|
return EMPTY_SET;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ChunkSets() {}
|
||||||
|
|
||||||
private final static ChunkSet EMPTY_SET = new ChunkSet() {
|
private final static ChunkSet EMPTY_SET = new ChunkSet() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -89,10 +97,174 @@ public class ChunkSets {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static ChunkSet empty() {
|
private static class SynchronizedChunkSet implements ChunkSet {
|
||||||
return EMPTY_SET;
|
|
||||||
|
private final ChunkSet parent;
|
||||||
|
private final Object mutex;
|
||||||
|
|
||||||
|
public SynchronizedChunkSet(ChunkSet parent, Object mutex) {
|
||||||
|
Objects.requireNonNull(parent, "parent");
|
||||||
|
this.parent = parent;
|
||||||
|
|
||||||
|
this.mutex = mutex == null ? this : mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Vec3i> iterator() {
|
||||||
|
return parent.iterator(); // Must be synchronized manually by user!
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void forEach(Consumer<? super Vec3i> action) {
|
||||||
|
synchronized (mutex) { parent.forEach(action); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
synchronized (mutex) { return parent.size(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEmpty() {
|
||||||
|
synchronized (mutex) { return parent.isEmpty(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Vec3i pos) {
|
||||||
|
synchronized (mutex) { return parent.contains(pos); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(Vec3i pos) {
|
||||||
|
synchronized (mutex) { return parent.add(pos); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(Vec3i pos) {
|
||||||
|
synchronized (mutex) { return parent.remove(pos); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(int x, int y, int z) {
|
||||||
|
synchronized (mutex) { return parent.contains(x, y, z); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(int x, int y, int z) {
|
||||||
|
synchronized (mutex) { return parent.add(x, y, z); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(int x, int y, int z) {
|
||||||
|
synchronized (mutex) { return parent.remove(x, y, z); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(GenericChunk<?, ?, ?, ?> chunk) {
|
||||||
|
synchronized (mutex) { return parent.contains(chunk); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean add(GenericChunk<?, ?, ?, ?> chunk) {
|
||||||
|
synchronized (mutex) { return parent.add(chunk); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean remove(GenericChunk<?, ?, ?, ?> chunk) {
|
||||||
|
synchronized (mutex) { return parent.remove(chunk); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <C extends GenericChunk<C, ?, ?, ?>> void forEachIn(GenericWorld<?, ?, ?, C, ?> world,
|
||||||
|
Consumer<? super C> action) {
|
||||||
|
synchronized (mutex) { parent.forEachIn(world, action); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(ChunkSet other) {
|
||||||
|
synchronized (mutex) { return parent.containsAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAny(ChunkSet other) {
|
||||||
|
synchronized (mutex) { return parent.containsAny(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAll(ChunkSet other) {
|
||||||
|
synchronized (mutex) { parent.addAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAll(ChunkSet other) {
|
||||||
|
synchronized (mutex) { parent.removeAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retainAll(ChunkSet other) {
|
||||||
|
synchronized (mutex) { parent.retainAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
synchronized (mutex) { parent.clear(); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAll(Iterable<? extends Vec3i> other) {
|
||||||
|
synchronized (mutex) { return parent.containsAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAny(Iterable<? extends Vec3i> other) {
|
||||||
|
synchronized (mutex) { return parent.containsAny(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAll(Iterable<? extends Vec3i> other) {
|
||||||
|
synchronized (mutex) { parent.addAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAll(Iterable<? extends Vec3i> other) {
|
||||||
|
synchronized (mutex) { parent.removeAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retainAll(Iterable<? extends Vec3i> other) {
|
||||||
|
synchronized (mutex) { parent.retainAll(other); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeIf(Predicate<? super Vec3i> condition) {
|
||||||
|
synchronized (mutex) { parent.removeIf(condition); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retainIf(Predicate<? super Vec3i> condition) {
|
||||||
|
synchronized (mutex) { parent.retainIf(condition); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?>> chunks) {
|
||||||
|
synchronized (mutex) { return parent.containsAllChunks(chunks); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean containsAnyChunks(Iterable<? extends GenericChunk<?, ?, ?, ?>> chunks) {
|
||||||
|
synchronized (mutex) { return parent.containsAnyChunks(chunks); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?>> chunks) {
|
||||||
|
synchronized (mutex) { parent.addAllChunks(chunks); }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeAllChunks(Iterable<? extends GenericChunk<?, ?, ?, ?>> chunks) {
|
||||||
|
synchronized (mutex) { parent.removeAllChunks(chunks); }
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChunkSets() {}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@ public interface GenericChunk<
|
|||||||
}
|
}
|
||||||
|
|
||||||
default void forEachBiC(Consumer<? super Vec3i> action) {
|
default void forEachBiC(Consumer<? super Vec3i> action) {
|
||||||
VectorUtil.forEachVectorInCuboid(
|
VectorUtil.iterateCuboid(
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK,
|
BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK, BLOCKS_PER_CHUNK,
|
||||||
action
|
action
|
||||||
@ -63,7 +63,7 @@ public interface GenericChunk<
|
|||||||
}
|
}
|
||||||
|
|
||||||
default void forEachBiW(Consumer<? super Vec3i> action) {
|
default void forEachBiW(Consumer<? super Vec3i> action) {
|
||||||
VectorUtil.forEachVectorInCuboid(
|
VectorUtil.iterateCuboid(
|
||||||
Coordinates.getInWorld(getX(), 0),
|
Coordinates.getInWorld(getX(), 0),
|
||||||
Coordinates.getInWorld(getY(), 0),
|
Coordinates.getInWorld(getY(), 0),
|
||||||
Coordinates.getInWorld(getZ(), 0),
|
Coordinates.getInWorld(getZ(), 0),
|
||||||
|
@ -112,49 +112,6 @@ public class TickAndUpdateUtil {
|
|||||||
tickEntity(EntityLogicRegistry.getInstance().get(data.getId()), data, TickContextMutable.start().withServer(server).build());
|
tickEntity(EntityLogicRegistry.getInstance().get(data.getId()), data, TickContextMutable.start().withServer(server).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static BlockTickContext getBlockTickContext(
|
|
||||||
// Server server,
|
|
||||||
// Vec3i blockInWorld
|
|
||||||
// ) {
|
|
||||||
// MutableBlockTickContext result = new MutableBlockTickContext();
|
|
||||||
// result.init(server, blockInWorld);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static TileTickContext getTileTickContext(
|
|
||||||
// Server server,
|
|
||||||
// Vec3i blockInWorld,
|
|
||||||
// BlockFace face,
|
|
||||||
// int layer
|
|
||||||
// ) {
|
|
||||||
// MutableTileTickContext result = new MutableTileTickContext();
|
|
||||||
// result.init(server, blockInWorld, face, layer);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static TileTickContext getTileTickContext(
|
|
||||||
// Server server,
|
|
||||||
// TileDataStack stack,
|
|
||||||
// int index
|
|
||||||
// ) {
|
|
||||||
// MutableTileTickContext result = new MutableTileTickContext();
|
|
||||||
// result.init(server, stack, index);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static TileTickContext getTileTickContext(
|
|
||||||
// Server server,
|
|
||||||
// TileReference ref
|
|
||||||
// ) {
|
|
||||||
// MutableTileTickContext result = new MutableTileTickContext();
|
|
||||||
// result.init(server, ref);
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// public static TickContext getTickContext(Server server) {
|
|
||||||
// return getBlockTickContext(server, null);
|
|
||||||
// }
|
|
||||||
|
|
||||||
private TickAndUpdateUtil() {}
|
private TickAndUpdateUtil() {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,12 @@ public class LayerTestGUI extends GUILayer {
|
|||||||
128
|
128
|
||||||
));
|
));
|
||||||
|
|
||||||
|
panel.addChild(new DynamicLabel(
|
||||||
|
"ChunkUpdatesDisplay", new Font().withColor(0x37A3E6).deriveShadow(),
|
||||||
|
() -> "Pending updates: " + Integer.toString(ClientState.getInstance().getWorld().getPendingChunkUpdates()),
|
||||||
|
128
|
||||||
|
));
|
||||||
|
|
||||||
panel.getChildren().forEach(c -> {
|
panel.getChildren().forEach(c -> {
|
||||||
if (c instanceof Label) {
|
if (c instanceof Label) {
|
||||||
labels.add((Label) c);
|
labels.add((Label) c);
|
||||||
|
@ -29,8 +29,8 @@ public class TestPlayerControls {
|
|||||||
|
|
||||||
private TestPlayerControls() {}
|
private TestPlayerControls() {}
|
||||||
|
|
||||||
private static final double MODE_SWITCH_MAX_DELAY = 100 * Units.MILLISECONDS;
|
private static final double MODE_SWITCH_MAX_DELAY = 300 * Units.MILLISECONDS;
|
||||||
private static final double MIN_JUMP_DELAY = 200 * Units.MILLISECONDS;
|
private static final double MIN_JUMP_DELAY = 400 * Units.MILLISECONDS;
|
||||||
|
|
||||||
// Horizontal and vertical max control speed when flying
|
// Horizontal and vertical max control speed when flying
|
||||||
private static final float FLYING_SPEED = 6.0f * Units.METERS_PER_SECOND;
|
private static final float FLYING_SPEED = 6.0f * Units.METERS_PER_SECOND;
|
||||||
|
Reference in New Issue
Block a user