Merge Forge mixins that didn't automerge

This commit is contained in:
embeddedt 2024-03-02 13:14:41 -05:00
parent 8d2d3d8e15
commit 96db279d58
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
6 changed files with 20 additions and 171 deletions

View File

@ -1,56 +0,0 @@
package org.embeddedt.modernfix.forge.mixin.bugfix.model_data_manager_cme;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.ChunkPos;
import net.minecraftforge.client.model.data.ModelDataManager;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
/**
* Fix several concurrency issues in the default ModelDataManager.
*/
@Mixin(ModelDataManager.class)
@ClientOnlyMixin
public abstract class ModelDataManagerMixin {
@Shadow protected abstract void refreshAt(ChunkPos chunk);
@Shadow @Final private Map<ChunkPos, Set<BlockPos>> needModelDataRefresh;
/**
* Make the set of positions to refresh a real concurrent hash set rather than relying on synchronizedSet,
* because the returned iterator won't be thread-safe otherwise. See https://github.com/AppliedEnergistics/Applied-Energistics-2/issues/7511
*/
@ModifyArg(method = "requestRefresh", at = @At(value = "INVOKE", target = "Ljava/util/Map;computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;", ordinal = 0), index = 1, remap = false)
private Function<ChunkPos, Set<BlockPos>> changeTypeOfSetUsed(Function<ChunkPos, Set<BlockPos>> mappingFunction) {
return pos -> Collections.newSetFromMap(new ConcurrentHashMap<>());
}
@Redirect(method = "getAt(Lnet/minecraft/world/level/ChunkPos;)Ljava/util/Map;", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/client/model/data/ModelDataManager;refreshAt(Lnet/minecraft/world/level/ChunkPos;)V"), remap = false)
private void onlyRefreshOnMainThread(ModelDataManager instance, ChunkPos pos) {
// Only refresh model data on the main thread. This prevents calling getBlockEntity from worker threads
// which could cause weird CMEs or other behavior.
// Avoid the loop if no model data needs to be refreshed, to prevent unnecessary allocation.
if(Minecraft.getInstance().isSameThread() && !needModelDataRefresh.isEmpty()) {
// Refresh the given chunk, and all its neighbors. This is less efficient than the default code
// but we have no choice since we need to not do refreshing on workers, and blocks might
// try to access model data in neighboring chunks.
for(int x = -1; x <= 1; x++) {
for(int z = -1; z <= 1; z++) {
refreshAt(new ChunkPos(pos.x + x, pos.z + z));
}
}
}
}
}

View File

@ -1,24 +0,0 @@
package org.embeddedt.modernfix.forge.mixin.perf.forge_cap_retrieval;
import net.minecraft.core.Direction;
import net.minecraft.world.entity.LivingEntity;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.ForgeCapabilities;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
import javax.annotation.Nullable;
@Mixin(LivingEntity.class)
public class LivingEntityMixin {
/**
* @author embeddedt (issue noted by XFactHD)
* @reason check capability equality before checking that entity is alive, the latter requires a lot more
* indirection
*/
@Redirect(method = "getCapability", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;isAlive()Z"))
private <T> boolean checkAliveAfterCap(LivingEntity entity, Capability<T> capability, @Nullable Direction facing) {
return capability == ForgeCapabilities.ITEM_HANDLER && entity.isAlive();
}
}

View File

@ -1,69 +0,0 @@
package org.embeddedt.modernfix.forge.mixin.perf.forge_registry_alloc;
import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import net.minecraft.core.Holder;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraftforge.registries.ForgeRegistry;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow;
import java.util.Locale;
import java.util.Map;
@Mixin(value = ForgeRegistry.class, remap = false)
public abstract class ForgeRegistryMixin<V> {
// Replace the backing maps with fastutil maps for a bit more speed, since value->holder lookups in particular
// are a bottleneck in many areas (e.g. render type lookup)
@Shadow @Final private Map<ResourceLocation, Holder.Reference<V>> delegatesByName = new Object2ObjectOpenHashMap<>();
@Shadow @Final private Map<V, Holder.Reference<V>> delegatesByValue = new Object2ObjectOpenHashMap<>(Hash.DEFAULT_INITIAL_SIZE, 0.5F);
/**
* @author embeddedt
* @reason stop allocating so many unneeded objects. stop.
*/
@Overwrite
public Holder.Reference<V> getDelegateOrThrow(ResourceLocation location) {
Holder.Reference<V> holder = delegatesByName.get(location);
if (holder == null) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH, "No delegate exists for location %s", location));
}
return holder;
}
/**
* @author embeddedt
* @reason see above
*/
@Overwrite
public Holder.Reference<V> getDelegateOrThrow(ResourceKey<V> rkey) {
Holder.Reference<V> holder = delegatesByName.get(rkey.location());
if (holder == null) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH, "No delegate exists for key %s", rkey));
}
return holder;
}
/**
* @author embeddedt
* @reason see above
*/
@Overwrite
public Holder.Reference<V> getDelegateOrThrow(V value) {
Holder.Reference<V> holder = delegatesByValue.get(value);
if (holder == null) {
throw new IllegalArgumentException(String.format(Locale.ENGLISH, "No delegate exists for value %s", value));
}
return holder;
}
}

View File

@ -1,10 +1,10 @@
package org.embeddedt.modernfix.forge.mixin.bugfix.entity_pose_stack;
package org.embeddedt.modernfix.neoforge.mixin.bugfix.entity_pose_stack;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.entity.LivingEntityRenderer;
import net.minecraftforge.client.event.RenderLivingEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.IEventBus;
import net.neoforged.neoforge.client.event.RenderLivingEvent;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.IEventBus;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -13,18 +13,17 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(LivingEntityRenderer.class)
@ClientOnlyMixin
public class LivingEntityRendererMixin {
@Redirect(method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z", ordinal = 0))
private boolean fireCheckingPoseStack(IEventBus instance, Event event) {
@Redirect(method = "render(Lnet/minecraft/world/entity/LivingEntity;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", at = @At(value = "INVOKE", target = "Lnet/neoforged/bus/api/IEventBus;post(Lnet/neoforged/bus/api/Event;)Lnet/neoforged/bus/api/Event;", ordinal = 0))
private Event fireCheckingPoseStack(IEventBus instance, Event event) {
PoseStack stack = ((RenderLivingEvent)event).getPoseStack();
int size = ((PoseStackAccessor)stack).getPoseStack().size();
if (instance.post(event)) {
instance.post(event);
if (((RenderLivingEvent.Pre)event).isCanceled()) {
// Pop the stack if someone pushed it in the event
while (((PoseStackAccessor)stack).getPoseStack().size() > size) {
stack.popPose();
}
return true;
} else {
return false;
}
return event;
}
}

View File

@ -1,10 +1,10 @@
package org.embeddedt.modernfix.forge.mixin.bugfix.entity_pose_stack;
package org.embeddedt.modernfix.neoforge.mixin.bugfix.entity_pose_stack;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.entity.player.PlayerRenderer;
import net.minecraftforge.client.event.RenderPlayerEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.IEventBus;
import net.neoforged.bus.api.Event;
import net.neoforged.bus.api.IEventBus;
import net.neoforged.neoforge.client.event.RenderLivingEvent;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@ -13,18 +13,17 @@ import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(PlayerRenderer.class)
@ClientOnlyMixin
public class PlayerRendererMixin {
@Redirect(method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/eventbus/api/IEventBus;post(Lnet/minecraftforge/eventbus/api/Event;)Z", ordinal = 0))
private boolean fireCheckingPoseStack(IEventBus instance, Event event) {
PoseStack stack = ((RenderPlayerEvent)event).getPoseStack();
@Redirect(method = "render(Lnet/minecraft/client/player/AbstractClientPlayer;FFLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;I)V", at = @At(value = "INVOKE", target = "Lnet/neoforged/bus/api/IEventBus;post(Lnet/neoforged/bus/api/Event;)Lnet/neoforged/bus/api/Event;", ordinal = 0))
private Event fireCheckingPoseStack(IEventBus instance, Event event) {
PoseStack stack = ((RenderLivingEvent)event).getPoseStack();
int size = ((PoseStackAccessor)stack).getPoseStack().size();
if (instance.post(event)) {
instance.post(event);
if (((RenderLivingEvent.Pre)event).isCanceled()) {
// Pop the stack if someone pushed it in the event
while (((PoseStackAccessor)stack).getPoseStack().size() > size) {
stack.popPose();
}
return true;
} else {
return false;
}
return event;
}
}

View File

@ -1,4 +1,4 @@
package org.embeddedt.modernfix.forge.mixin.bugfix.entity_pose_stack;
package org.embeddedt.modernfix.neoforge.mixin.bugfix.entity_pose_stack;
import com.mojang.blaze3d.vertex.PoseStack;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;