Rewrite CTM predicate handling again, fix more bugs

This commit is contained in:
embeddedt 2023-12-21 12:30:17 -05:00
parent 9c00f7297d
commit 7e2f3f3fb9
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
2 changed files with 61 additions and 23 deletions

View File

@ -0,0 +1,16 @@
package org.embeddedt.modernfix.forge.dynresources;
import net.minecraft.client.renderer.RenderType;
import java.util.function.Predicate;
public class ModernFixCTMPredicate implements Predicate<RenderType> {
public Predicate<RenderType> ctmOverride;
public Predicate<RenderType> defaultPredicate = type -> type == RenderType.solid();
@Override
public boolean test(RenderType renderType) {
Predicate<RenderType> override = ctmOverride;
return override != null ? override.test(renderType) : defaultPredicate.test(renderType);
}
}

View File

@ -1,6 +1,7 @@
package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources.ctm; package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources.ctm;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
import net.minecraft.client.renderer.ItemBlockRenderTypes; import net.minecraft.client.renderer.ItemBlockRenderTypes;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.resources.model.*; import net.minecraft.client.resources.model.*;
@ -16,6 +17,7 @@ import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.annotation.RequiresMod;
import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration; import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration;
import org.embeddedt.modernfix.api.helpers.ModelHelpers; import org.embeddedt.modernfix.api.helpers.ModelHelpers;
import org.embeddedt.modernfix.forge.dynresources.ModernFixCTMPredicate;
import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite; import org.spongepowered.asm.mixin.Overwrite;
@ -27,7 +29,6 @@ import team.chisel.ctm.client.model.AbstractCTMBakedModel;
import team.chisel.ctm.client.util.CTMPackReloadListener; import team.chisel.ctm.client.util.CTMPackReloadListener;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate; import java.util.function.Predicate;
@Mixin(CTMPackReloadListener.class) @Mixin(CTMPackReloadListener.class)
@ -37,7 +38,7 @@ public abstract class CTMPackReloadListenerMixin implements ModernFixClientInteg
/* caches the original render checks */ /* caches the original render checks */
@Shadow(remap = false) @Final private static Map<IRegistryDelegate<Block>, Predicate<RenderType>> blockRenderChecks; @Shadow(remap = false) @Final private static Map<IRegistryDelegate<Block>, Predicate<RenderType>> blockRenderChecks;
private static Map<IRegistryDelegate<Block>, Predicate<RenderType>> renderCheckOverrides = new ConcurrentHashMap<>(); private static volatile Map<IRegistryDelegate<Block>, ModernFixCTMPredicate> mfixBouncerPredicates = null;
private static Predicate<RenderType> DEFAULT_PREDICATE = type -> type == RenderType.solid(); private static Predicate<RenderType> DEFAULT_PREDICATE = type -> type == RenderType.solid();
@ -50,33 +51,55 @@ public abstract class CTMPackReloadListenerMixin implements ModernFixClientInteg
ModernFixClient.CLIENT_INTEGRATIONS.add(this); ModernFixClient.CLIENT_INTEGRATIONS.add(this);
} }
private static void initMap() {
if(mfixBouncerPredicates == null) {
synchronized (CTMPackReloadListener.class) {
if(mfixBouncerPredicates == null) {
Map<IRegistryDelegate<Block>, ModernFixCTMPredicate> map = new Reference2ReferenceOpenHashMap<>();
for(Block registeredBlock : ForgeRegistries.BLOCKS.getValues()) {
map.put(registeredBlock.delegate, new ModernFixCTMPredicate());
}
mfixBouncerPredicates = map;
}
}
}
}
/** /**
* @author embeddedt * @author embeddedt
* @reason handle layer changes dynamically * @reason handle layer changes dynamically
*/ */
@Overwrite(remap = false) @Overwrite(remap = false)
private void refreshLayerHacks() { private void refreshLayerHacks() {
renderCheckOverrides.clear(); // Make sure predicate map exists
if(blockRenderChecks.isEmpty()) { initMap();
for(Block block : ForgeRegistries.BLOCKS.getValues()) { mfixBouncerPredicates.values().forEach(bouncer -> bouncer.ctmOverride = null);
Predicate<RenderType> original = this.getExistingRenderCheck(block); }
if(original == null)
original = DEFAULT_PREDICATE; private static ModernFixCTMPredicate getPredicateForBlock(Block block) {
initMap();
ModernFixCTMPredicate predicate = mfixBouncerPredicates.get(block.delegate);
if(predicate == null) {
throw new NullPointerException("ModernFix CTM predicate missing for block: " + block.getRegistryName());
}
return predicate;
}
private void updateBlockPredicate(Block block, Predicate<RenderType> override) {
Predicate<RenderType> original = this.getExistingRenderCheck(block);
if(original == null) {
original = DEFAULT_PREDICATE;
}
ModernFixCTMPredicate bouncer = getPredicateForBlock(block);
if(original != bouncer) {
// Give the bouncer the original predicate for correct behavior
bouncer.defaultPredicate = original;
synchronized (ItemBlockRenderTypes.class) {
blockRenderChecks.put(block.delegate, original); blockRenderChecks.put(block.delegate, original);
updateBlockPredicate(block);
} }
} }
} bouncer.ctmOverride = override;
ItemBlockRenderTypes.setRenderLayer(block, bouncer);
private void updateBlockPredicate(Block block) {
ItemBlockRenderTypes.setRenderLayer(block, type -> this.useOverrideIfPresent(block.delegate, type));
}
private boolean useOverrideIfPresent(IRegistryDelegate<Block> delegate, RenderType type) {
Predicate<RenderType> override = renderCheckOverrides.get(delegate);
if(override == null)
override = blockRenderChecks.get(delegate);
return override.test(type);
} }
@Override @Override
@ -87,7 +110,7 @@ public abstract class CTMPackReloadListenerMixin implements ModernFixClientInteg
return originalModel; return originalModel;
/* we construct a new ResourceLocation because an MRL is coming in */ /* we construct a new ResourceLocation because an MRL is coming in */
Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(location.getNamespace(), location.getPath())); Block block = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(location.getNamespace(), location.getPath()));
if(block == null || block == Blocks.AIR || renderCheckOverrides.containsKey(block.delegate)) if(block == null || block == Blocks.AIR || getPredicateForBlock(block).ctmOverride != null)
return originalModel; return originalModel;
/* find all states that match this MRL */ /* find all states that match this MRL */
ImmutableList<BlockState> allStates; ImmutableList<BlockState> allStates;
@ -100,8 +123,7 @@ public abstract class CTMPackReloadListenerMixin implements ModernFixClientInteg
for(BlockState state : allStates) { for(BlockState state : allStates) {
Predicate<RenderType> newPredicate = this.getLayerCheck(state, originalModel); Predicate<RenderType> newPredicate = this.getLayerCheck(state, originalModel);
if(newPredicate != null) { if(newPredicate != null) {
renderCheckOverrides.put(block.delegate, newPredicate); updateBlockPredicate(block, newPredicate);
updateBlockPredicate(block);
return originalModel; return originalModel;
} }
} }