Ladysnake / Effective

A Minecraft Quilt client-side mod adding ambient and environmental interaction effects to enhance immersion.
Other
200 stars 65 forks source link

Caught Errors in `enhanced 'for'` Loop #82

Closed lonefelidae16 closed 1 year ago

lonefelidae16 commented 2 years ago

Hi👋 I got some errors at WaterfallCloudGenerators.tickParticles(WaterfallCloudGenerators.java:67).

java.lang.ArrayIndexOutOfBoundsException: crash-2022-04-27_17.51.03-client.txt

java.lang.NullPointerException: crash-2022-04-27_21.40.56-client.txt

I feel that the crash rate is particularly high when moving chunks around. So I tried these test codes:

public class Main {
    public static final Object2IntMap<BlockPos> particlesToSpawn = new Object2IntOpenHashMap<>();

    public static void main(String[] args) throws InterruptedException {
        particlesToSpawn.put(new BlockPos(0, 0, 8), 3);
        particlesToSpawn.put(new BlockPos(0, 0, 1), 0);
        particlesToSpawn.put(new BlockPos(0, 0, 4), 0);
        particlesToSpawn.put(new BlockPos(0, 0, 0), 2);

        Thread updater1 = new Thread(Main::updateParticles);
        Thread updater2 = new Thread(Main::updateParticles);
        updater1.start();
        updater2.start();
        updater1.join();
        updater2.join();
    }

    public static void updateParticles() {
        for (BlockPos pos : particlesToSpawn.keySet()) {
            if (pos != null) {
                if (particlesToSpawn.put(pos, particlesToSpawn.getInt(pos) - 1) <= 0) {
                    particlesToSpawn.removeInt(pos);
                }
                System.out.printf("%s, particlesToSpawn.size() == %d%n", pos, particlesToSpawn.size());
            }
        }
    }
}

... and I got java.lang.NullPointerException.

Perhaps this crash seems to be caused by deletion in the enhanced 'for' loop.

https://github.com/Ladysnake/Effective/blob/9bd3c7d6f78cdf431082e6be43c8039dc9023658/src/main/java/ladysnake/effective/client/world/WaterfallCloudGenerators.java#L70

By enclosing this with synchronized and replacing ObjectSet<Object2IntMap.Entry<K>>#removeIf(Predicate), I have not had any problems so far.

Thanks for awesome mod!