Add synchronization to CharBlocks (#963)

similar to ChunkHolder, it represents an internal chunk for which operations should not be accepted by multiple threads at once.

Co-authored-by: NotMyFault <mc.cache@web.de>
This commit is contained in:
dordsor21 2021-03-15 18:33:21 +00:00 committed by GitHub
parent 20424b081c
commit d224d6ea32
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -62,7 +62,7 @@ public abstract class CharBlocks implements IBlocks {
} }
@Override @Override
public boolean trim(boolean aggressive) { public synchronized boolean trim(boolean aggressive) {
boolean result = true; boolean result = true;
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
if (!sections[i].isFull() && blocks[i] != null) { if (!sections[i].isFull() && blocks[i] != null) {
@ -75,7 +75,7 @@ public abstract class CharBlocks implements IBlocks {
} }
@Override @Override
public boolean trim(boolean aggressive, int layer) { public synchronized boolean trim(boolean aggressive, int layer) {
boolean result = true; boolean result = true;
if (!sections[layer].isFull() && blocks[layer] != null) { if (!sections[layer].isFull() && blocks[layer] != null) {
blocks[layer] = null; blocks[layer] = null;
@ -86,18 +86,18 @@ public abstract class CharBlocks implements IBlocks {
} }
@Override @Override
public IChunkSet reset() { public synchronized IChunkSet reset() {
for (int i = 0; i < 16; i++) { for (int i = 0; i < 16; i++) {
sections[i] = EMPTY; sections[i] = EMPTY;
} }
return null; return null;
} }
public void reset(@Range(from = 0, to = 15) int layer) { public synchronized void reset(@Range(from = 0, to = 15) int layer) {
sections[layer] = EMPTY; sections[layer] = EMPTY;
} }
public char[] update(int layer, char[] data) { public synchronized char[] update(int layer, char[] data) {
if (data == null) { if (data == null) {
return new char[4096]; return new char[4096];
} }
@ -107,22 +107,23 @@ public abstract class CharBlocks implements IBlocks {
return data; return data;
} }
// Not synchronized as any subsequent methods called from this class will be, or the section shouldn't appear as loaded anyway.
@Override @Override
public boolean hasSection(@Range(from = 0, to = 15) int layer) { public boolean hasSection(@Range(from = 0, to = 15) int layer) {
return sections[layer].isFull(); return sections[layer].isFull();
} }
@Override @Override
public char[] load(@Range(from = 0, to = 15) int layer) { public synchronized char[] load(@Range(from = 0, to = 15) int layer) {
return sections[layer].get(this, layer); return sections[layer].get(this, layer);
} }
@Override @Override
public BlockState getBlock(int x, int y, int z) { public synchronized BlockState getBlock(int x, int y, int z) {
return BlockTypesCache.states[get(x, y, z)]; return BlockTypesCache.states[get(x, y, z)];
} }
public char get(int x, @Range(from = 0, to = 255) int y, int z) { public synchronized char get(int x, @Range(from = 0, to = 255) int y, int z) {
final int layer = y >> 4; final int layer = y >> 4;
final int index = (y & 15) << 8 | z << 4 | x; final int index = (y & 15) << 8 | z << 4 | x;
if (layer >= sections.length || layer < 0) { if (layer >= sections.length || layer < 0) {
@ -131,6 +132,7 @@ public abstract class CharBlocks implements IBlocks {
return sections[layer].get(this, layer, index); return sections[layer].get(this, layer, index);
} }
// Not synchronized as it refers to a synchronized method and includes nothing that requires synchronization
public void set(int x, @Range(from = 0, to = 255) int y, int z, char value) { public void set(int x, @Range(from = 0, to = 255) int y, int z, char value) {
final int layer = y >> 4; final int layer = y >> 4;
final int index = (y & 15) << 8 | z << 4 | x; final int index = (y & 15) << 8 | z << 4 | x;
@ -147,11 +149,11 @@ public abstract class CharBlocks implements IBlocks {
Section Section
*/ */
public final char get(@Range(from = 0, to = 15)int layer, int index) { public synchronized final char get(@Range(from = 0, to = 15) int layer, int index) {
return sections[layer].get(this, layer, index); return sections[layer].get(this, layer, index);
} }
public final void set(@Range(from = 0, to = 15) int layer, int index, char value) throws ArrayIndexOutOfBoundsException { public synchronized final void set(@Range(from = 0, to = 15) int layer, int index, char value) throws ArrayIndexOutOfBoundsException {
sections[layer].set(this, layer, index, value); sections[layer].set(this, layer, index, value);
} }