Skip to content

Commit 1d67197

Browse files
committed
Merge 1.16 into 1.18
2 parents 8320c31 + c678ebb commit 1d67197

File tree

4 files changed

+79
-6
lines changed

4 files changed

+79
-6
lines changed

common/src/main/java/org/embeddedt/modernfix/util/ClassInfoManager.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,22 @@
33
import org.embeddedt.modernfix.ModernFix;
44
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
55
import org.objectweb.asm.tree.ClassNode;
6+
import org.spongepowered.asm.logging.ILogger;
7+
import org.spongepowered.asm.logging.LoggerAdapterDefault;
68
import org.spongepowered.asm.mixin.MixinEnvironment;
79
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
810
import org.spongepowered.asm.mixin.transformer.ClassInfo;
11+
import org.spongepowered.asm.service.MixinServiceAbstract;
912

1013
import java.lang.reflect.Field;
14+
import java.util.ArrayList;
1115
import java.util.Collection;
16+
import java.util.List;
1217
import java.util.Map;
1318

1419
public class ClassInfoManager {
1520
private static boolean hasRun = false;
21+
private static final List<Runnable> loggersToRestore = new ArrayList<>();
1622
public static void clear() {
1723
if (!ModernFixMixinPlugin.instance.isOptionEnabled("perf.clear_mixin_classinfo.ClassInfoManager") || hasRun)
1824
return;
@@ -25,11 +31,33 @@ private static Field accessible(Field f) {
2531
return f;
2632
}
2733

34+
private static void changeLoggerAndRestoreLater(Map<String, ILogger> map, ILogger newLogger) {
35+
ILogger oldLogger = map.put("mixin.audit", newLogger);
36+
loggersToRestore.add(() -> map.put("mixin.audit", oldLogger));
37+
}
38+
39+
private static void disableLoggers() throws ReflectiveOperationException {
40+
// Disable default audit logger
41+
Field loggersField = accessible(MixinServiceAbstract.class.getDeclaredField("loggers"));
42+
changeLoggerAndRestoreLater((Map<String, ILogger>)loggersField.get(null), new LoggerAdapterDefault("mixin.audit"));
43+
Class<?> fabricLogger = null;
44+
try {
45+
fabricLogger = Class.forName("net.fabricmc.loader.impl.knot.MixinLogger");
46+
} catch(Throwable e) {
47+
// Probably not Fabric
48+
return;
49+
}
50+
// Disable Fabric audit logger
51+
loggersField = accessible(fabricLogger.getDeclaredField("LOGGER_MAP"));
52+
changeLoggerAndRestoreLater((Map<String, ILogger>)loggersField.get(null), new LoggerAdapterDefault("mixin.audit"));
53+
}
54+
2855
private static void doClear() {
2956
Map<String, ClassInfo> classInfoCache;
3057
Field mixinField, stateField, classNodeField, methodsField, fieldsField;
3158
Class<?> stateClz;
3259
try {
60+
disableLoggers();
3361
Field field = accessible(ClassInfo.class.getDeclaredField("cache"));
3462
classInfoCache = (Map<String, ClassInfo>) field.get(null);
3563
mixinField = accessible(ClassInfo.class.getDeclaredField("mixin"));
@@ -70,6 +98,9 @@ private static void doClear() {
7098
} catch (RuntimeException e) {
7199
e.printStackTrace();
72100
}
101+
// Put back the old logger
102+
loggersToRestore.forEach(Runnable::run);
103+
loggersToRestore.clear();
73104
ModernFix.LOGGER.warn("Cleared mixin data structures");
74105
}
75106
}

forge/src/main/java/org/embeddedt/modernfix/forge/dynresources/ModelBakeEventHelper.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,13 +153,26 @@ public boolean containsKey(@Nullable Object key) {
153153

154154
@Override
155155
public void replaceAll(BiFunction<? super ResourceLocation, ? super BakedModel, ? extends BakedModel> function) {
156-
ModernFix.LOGGER.warn("Mod '{}' is calling replaceAll on the model registry. This requires temporarily loading every model for that mod, which is slow.", modId);
156+
ModernFix.LOGGER.warn("Mod '{}' is calling replaceAll on the model registry. Some hacks will be used to keep this fast, but they may not be 100% compatible.", modId);
157157
List<ResourceLocation> locations = new ArrayList<>(keySet());
158158
for(ResourceLocation location : locations) {
159-
BakedModel existing = get(location);
160-
BakedModel replacement = function.apply(location, existing);
161-
if(replacement != existing) {
162-
put(location, replacement);
159+
/*
160+
* Fetching every model is insanely slow. So we call the function with a null object first, since it
161+
* probably isn't expecting that. If we get an exception thrown, or it returns nonnull, then we know
162+
* it actually cares about the given model.
163+
*/
164+
boolean needsReplacement;
165+
try {
166+
needsReplacement = function.apply(location, null) != null;
167+
} catch(Throwable e) {
168+
needsReplacement = true;
169+
}
170+
if(needsReplacement) {
171+
BakedModel existing = get(location);
172+
BakedModel replacement = function.apply(location, existing);
173+
if(replacement != existing) {
174+
put(location, replacement);
175+
}
163176
}
164177
}
165178
}

forge/src/main/java/org/embeddedt/modernfix/forge/mixin/bugfix/model_data_manager_cme/ModelDataManagerMixin.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
import net.minecraft.world.level.Level;
77
import net.minecraftforge.client.model.ModelDataManager;
88
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
9+
import org.spongepowered.asm.mixin.Final;
910
import org.spongepowered.asm.mixin.Mixin;
1011
import org.spongepowered.asm.mixin.Shadow;
1112
import org.spongepowered.asm.mixin.injection.At;
1213
import org.spongepowered.asm.mixin.injection.ModifyArg;
1314
import org.spongepowered.asm.mixin.injection.Redirect;
1415

1516
import java.util.Collections;
17+
import java.util.Map;
1618
import java.util.Set;
1719
import java.util.concurrent.ConcurrentHashMap;
1820
import 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.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.embeddedt.modernfix.forge.mixin.perf.forge_cap_retrieval;
2+
3+
import net.minecraft.core.Direction;
4+
import net.minecraft.world.entity.LivingEntity;
5+
import net.minecraftforge.common.capabilities.Capability;
6+
import net.minecraftforge.items.CapabilityItemHandler;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.injection.At;
9+
import org.spongepowered.asm.mixin.injection.Redirect;
10+
11+
import javax.annotation.Nullable;
12+
13+
@Mixin(LivingEntity.class)
14+
public class LivingEntityMixin {
15+
/**
16+
* @author embeddedt (issue noted by XFactHD)
17+
* @reason check capability equality before checking that entity is alive, the latter requires a lot more
18+
* indirection
19+
*/
20+
@Redirect(method = "getCapability", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;isAlive()Z"))
21+
private <T> boolean checkAliveAfterCap(LivingEntity entity, Capability<T> capability, @Nullable Direction facing) {
22+
return capability == CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && entity.isAlive();
23+
}
24+
}

0 commit comments

Comments
 (0)