Merge pull request #22 from 34638a/dev

Patch to stop the java.util.ConcurrentModificationException.
This commit is contained in:
Jozufozu 2021-08-04 14:16:47 -07:00 committed by GitHub
commit f21566d1fc

View file

@ -1,9 +1,16 @@
package com.jozufozu.flywheel.backend.instancing;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import javax.annotation.Nullable;
@ -11,6 +18,7 @@ import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.backend.material.MaterialManager;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectArraySet;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3f;
@ -19,8 +27,8 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
public final MaterialManager<?> materialManager;
protected final ArrayList<T> queuedAdditions;
protected final ConcurrentHashMap.KeySetView<T, Boolean> queuedUpdates;
private final Set<T> queuedAdditions;
private final Set<T> queuedUpdates;
protected final Map<T, IInstance> instances;
protected final Object2ObjectOpenHashMap<T, ITickableInstance> tickableInstances;
@ -31,8 +39,8 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
public InstanceManager(MaterialManager<?> materialManager) {
this.materialManager = materialManager;
this.queuedUpdates = ConcurrentHashMap.newKeySet(64);
this.queuedAdditions = new ArrayList<>(64);
this.queuedUpdates = new HashSet<>(64);
this.queuedAdditions = new HashSet<>(64);
this.instances = new HashMap<>();
this.dynamicInstances = new Object2ObjectOpenHashMap<>();
@ -49,6 +57,7 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
public void tick(double cameraX, double cameraY, double cameraZ) {
tick++;
processQueuedUpdates();
// integer camera pos
int cX = (int) cameraX;
@ -72,12 +81,6 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0) instance.tick();
});
}
queuedUpdates.forEach(te -> {
queuedUpdates.remove(te);
update(te);
});
}
public void beginFrame(ActiveRenderInfo info) {
@ -118,7 +121,9 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
if (!Backend.getInstance()
.canUseInstancing()) return;
queuedAdditions.add(obj);
synchronized (queuedAdditions) {
queuedAdditions.add(obj);
}
}
public void update(T obj) {
@ -144,8 +149,9 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
public synchronized void queueUpdate(T obj) {
if (!Backend.getInstance()
.canUseInstancing()) return;
queuedUpdates.add(obj);
synchronized (queuedUpdates) {
queuedUpdates.add(obj);
}
}
public void onLightUpdate(T obj) {
@ -176,7 +182,6 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
tickableInstances.clear();
}
@SuppressWarnings("unchecked")
@Nullable
protected <I extends T> IInstance getInstance(I obj, boolean create) {
if (!Backend.getInstance()
@ -193,11 +198,30 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
}
}
protected synchronized void processQueuedAdditions() {
if (queuedAdditions.size() > 0) {
queuedAdditions.forEach(this::addInternal);
protected void processQueuedAdditions() {
ArrayList<T> queued;
synchronized (queuedAdditions) {
queued = new ArrayList<>(queuedAdditions);
queuedAdditions.clear();
}
if (queued.size() > 0) {
queued.forEach(this::addInternal);
}
}
protected void processQueuedUpdates() {
ArrayList<T> queued;
synchronized (queuedUpdates) {
queued = new ArrayList<>(queuedUpdates);
queuedUpdates.clear();
}
if (queued.size() > 0) {
queued.forEach(this::update);
}
}
protected boolean shouldFrameUpdate(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {