66import net .minecraft .world .level .Level ;
77import net .minecraftforge .client .model .ModelDataManager ;
88import org .embeddedt .modernfix .annotation .ClientOnlyMixin ;
9+ import org .spongepowered .asm .mixin .Final ;
910import org .spongepowered .asm .mixin .Mixin ;
1011import org .spongepowered .asm .mixin .Shadow ;
1112import org .spongepowered .asm .mixin .injection .At ;
1213import org .spongepowered .asm .mixin .injection .ModifyArg ;
1314import org .spongepowered .asm .mixin .injection .Redirect ;
1415
1516import java .util .Collections ;
17+ import java .util .Map ;
1618import java .util .Set ;
1719import java .util .concurrent .ConcurrentHashMap ;
1820import java .util .function .Function ;
@@ -27,6 +29,8 @@ public abstract class ModelDataManagerMixin {
2729 throw new AssertionError ();
2830 }
2931
32+ @ Shadow @ Final private static Map <ChunkPos , Set <BlockPos >> needModelDataRefresh ;
33+
3034 /**
3135 * Make the set of positions to refresh a real concurrent hash set rather than relying on synchronizedSet,
3236 * because the returned iterator won't be thread-safe otherwise. See https://github.com/AppliedEnergistics/Applied-Energistics-2/issues/7511
@@ -40,7 +44,8 @@ private static Function<ChunkPos, Set<BlockPos>> changeTypeOfSetUsed(Function<Ch
4044 private static void onlyRefreshOnMainThread (Level toUpdate , ChunkPos pos ) {
4145 // Only refresh model data on the main thread. This prevents calling getBlockEntity from worker threads
4246 // which could cause weird CMEs or other behavior.
43- if (Minecraft .getInstance ().isSameThread ()) {
47+ // Avoid the loop if no model data needs to be refreshed, to prevent unnecessary allocation.
48+ if (Minecraft .getInstance ().isSameThread () && !needModelDataRefresh .isEmpty ()) {
4449 // Refresh the given chunk, and all its neighbors. This is less efficient than the default code
4550 // but we have no choice since we need to not do refreshing on workers, and blocks might
4651 // try to access model data in neighboring chunks.
0 commit comments