Attempt to fix ConcurrentModificationException #2
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
See my comment on issue #1.
To summarise, PalladiumCore enables mod developers to deal with client-side setup in a cross-platform way. One thing that mods often do during client-side setup is call
ItemProperties::register
. This method is not thread-safe, which isn't a problem on Fabric since it doesn't run client-side setup in parallel for multiple mods, but it is a problem on Forge, which does. Looking at another mod that ran into this issue, my understanding is that we can avoid this concurrency error by usingFMLClientSetupEvent::enqueueWork
.This PR attempts to fix the concurrency issue on PalladiumCore's side by blindly enqueuing client setup for all mods that register/listen for the
CLIENT_SETUP
event. A possible consequence of this is that loading mods on Forge takes longer.To avoid that performance hit, we would need to be able to distinguish between listeners that don't need to be enqueued vs those that do, for example by providing two separate client events to register for. But this distinction only makes sense on Forge, so it could be awkward to expose this difference to mod developers.
I had considered providing the
FMLClientSetupEvent
instance as an argument to listeners and letting them callenqueueWork
themselves, but that would expose a Forge-specific class. To get around that, you would have to create a compatibility class that is composed ofFMLClientSetupEvent
on Forge or whatever the equivalent is on Fabric, and then provides anenqueueWork
method that delegates toFMLClientSetupEvent::enqueueWork
on Forge and immediately runs the runnable on Fabric. But that sounds very clunky, and still doesn't solve the problem of hiding a Forge-only concern.