stamps and notes
This commit is contained in:
@@ -4,18 +4,21 @@ import it.unimi.dsi.fastutil.longs.Long2ByteOpenHashMap;
|
||||
import me.cortex.voxy.common.world.WorldEngine;
|
||||
import me.cortex.voxy.common.world.WorldSection;
|
||||
|
||||
import java.util.concurrent.locks.StampedLock;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
import static me.cortex.voxy.common.world.WorldEngine.UPDATE_TYPE_BLOCK_BIT;
|
||||
|
||||
public class SectionUpdateRouter implements ISectionWatcher {
|
||||
private static final int SLICES = 1<<8;
|
||||
private static final int SLICES = 1<<4;
|
||||
public interface IChildUpdate {void accept(WorldSection section);}
|
||||
|
||||
private final Long2ByteOpenHashMap[] slices = new Long2ByteOpenHashMap[SLICES];
|
||||
private final StampedLock[] locks = new StampedLock[SLICES];
|
||||
{
|
||||
for (int i = 0; i < this.slices.length; i++) {
|
||||
this.slices[i] = new Long2ByteOpenHashMap();
|
||||
this.locks[i] = new StampedLock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,17 +38,34 @@ public class SectionUpdateRouter implements ISectionWatcher {
|
||||
}
|
||||
|
||||
public boolean watch(long position, int types) {
|
||||
var set = this.slices[getSliceIndex(position)];
|
||||
int idx = getSliceIndex(position);
|
||||
var set = this.slices[idx];
|
||||
var lock = this.locks[idx];
|
||||
byte delta = 0;
|
||||
synchronized (set) {
|
||||
byte current = 0;
|
||||
if (set.containsKey(position)) {
|
||||
current = set.get(position);
|
||||
}
|
||||
{
|
||||
long stamp = lock.readLock();
|
||||
byte current = set.getOrDefault(position, (byte) 0);
|
||||
delta = (byte) (current&types);
|
||||
current |= (byte) types;
|
||||
delta ^= (byte) (current&types);
|
||||
if (delta != 0) {//Was change
|
||||
long ws = lock.tryConvertToWriteLock(stamp);
|
||||
if (ws == 0) {
|
||||
lock.unlockRead(stamp);
|
||||
stamp = lock.writeLock();
|
||||
//We need to recompute as we failed to acquire an immediate write lock
|
||||
current = set.getOrDefault(position, (byte) 0);
|
||||
delta = (byte) (current&types);
|
||||
current |= (byte) types;
|
||||
delta ^= (byte) (current&types);
|
||||
if (delta != 0)
|
||||
set.put(position, current);
|
||||
} else {
|
||||
stamp = ws;
|
||||
set.put(position, current);
|
||||
}
|
||||
}
|
||||
lock.unlock(stamp);
|
||||
}
|
||||
if ((delta&UPDATE_TYPE_BLOCK_BIT)!=0) {
|
||||
//If we added it, immediately invoke for an update
|
||||
@@ -58,38 +78,67 @@ public class SectionUpdateRouter implements ISectionWatcher {
|
||||
return this.unwatch(WorldEngine.getWorldSectionId(lvl, x, y, z), types);
|
||||
}
|
||||
|
||||
public boolean unwatch(long position, int types) {
|
||||
var set = this.slices[getSliceIndex(position)];
|
||||
synchronized (set) {
|
||||
if (!set.containsKey(position)) {
|
||||
throw new IllegalStateException("Section pos not in map!! " + WorldEngine.pprintPos(position));
|
||||
public boolean unwatch(long position, int types) {//Types is types to unwatch
|
||||
int idx = getSliceIndex(position);
|
||||
var set = this.slices[idx];
|
||||
var lock = this.locks[idx];
|
||||
|
||||
long stamp = lock.readLock();
|
||||
|
||||
byte current = set.getOrDefault(position, (byte)0);
|
||||
if (current == 0) {
|
||||
throw new IllegalStateException("Section pos not in map " + WorldEngine.pprintPos(position));
|
||||
}
|
||||
byte current = set.get(position);
|
||||
byte delta = (byte) (current&types);
|
||||
boolean removed = false;
|
||||
if ((current&types) != 0) {//Was change
|
||||
long ws = lock.tryConvertToWriteLock(stamp);
|
||||
if (ws == 0) {//failed to get write lock, need to unlock, get write, then redo
|
||||
lock.unlockRead(stamp);
|
||||
stamp = lock.writeLock();
|
||||
|
||||
current = set.getOrDefault(position, (byte)0);
|
||||
if (current == 0) {
|
||||
throw new IllegalStateException("Section pos not in map " + WorldEngine.pprintPos(position));
|
||||
}
|
||||
} else {
|
||||
stamp = ws;
|
||||
}
|
||||
|
||||
if ((current&types) != 0) {
|
||||
current &= (byte) ~types;
|
||||
if (current == 0) {
|
||||
set.remove(position);
|
||||
return true;
|
||||
}
|
||||
removed = true;
|
||||
} else {
|
||||
set.put(position, current);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
lock.unlock(stamp);
|
||||
return removed;
|
||||
}
|
||||
|
||||
public int get(long position) {
|
||||
var set = this.slices[getSliceIndex(position)];
|
||||
synchronized (set) {
|
||||
return set.getOrDefault(position, (byte) 0);
|
||||
}
|
||||
int idx = getSliceIndex(position);
|
||||
var set = this.slices[idx];
|
||||
var lock = this.locks[idx];
|
||||
long stamp = lock.readLock();
|
||||
int ret = set.getOrDefault(position, (byte) 0);
|
||||
lock.unlockRead(stamp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void forwardEvent(WorldSection section, int type) {
|
||||
final long position = section.key;
|
||||
var set = this.slices[getSliceIndex(position)];
|
||||
byte types = 0;
|
||||
synchronized (set) {
|
||||
types = set.getOrDefault(position, (byte)0);
|
||||
}
|
||||
|
||||
int idx = getSliceIndex(position);
|
||||
var set = this.slices[idx];
|
||||
var lock = this.locks[idx];
|
||||
|
||||
long stamp = lock.readLock();
|
||||
byte types = set.getOrDefault(position, (byte) 0);
|
||||
lock.unlockRead(stamp);
|
||||
|
||||
if (types!=0) {
|
||||
if ((type&WorldEngine.UPDATE_TYPE_CHILD_EXISTENCE_BIT)!=0) {
|
||||
this.childUpdateCallback.accept(section);
|
||||
|
||||
@@ -331,6 +331,7 @@ public class RenderDataFactory45 {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: add neighbor face culling
|
||||
private void generateYZOpaqueInnerGeometry(int axis) {
|
||||
for (int layer = 0; layer < 31; layer++) {
|
||||
this.blockMesher.auxiliaryPosition = layer;
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.lwjgl.system.MemoryUtil;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.function.LongConsumer;
|
||||
|
||||
//TODO: replace synchronize with StampedLock
|
||||
public class MemoryStorageBackend extends StorageBackend {
|
||||
private final Long2ObjectMap<MemoryBuffer>[] maps;
|
||||
private final Int2ObjectMap<ByteBuffer> idMappings = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@@ -18,7 +18,7 @@ public class ActiveSectionTracker {
|
||||
//Loaded section world cache, TODO: get rid of VolatileHolder and use something more sane
|
||||
|
||||
private final Long2ObjectOpenHashMap<VolatileHolder<WorldSection>>[] loadedSectionCache;
|
||||
private final ReentrantLock[] locks;
|
||||
private final ReentrantLock[] locks;//TODO: replace with StampedLocks
|
||||
private final SectionLoader loader;
|
||||
|
||||
private final int lruSize;
|
||||
|
||||
Reference in New Issue
Block a user