Merge 1.19.4 into 1.20
This commit is contained in:
commit
858325e40d
|
|
@ -0,0 +1,56 @@
|
||||||
|
package org.embeddedt.modernfix.blockstate;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntArrayMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
|
||||||
|
import net.minecraft.world.level.block.state.StateDefinition;
|
||||||
|
import net.minecraft.world.level.block.state.StateHolder;
|
||||||
|
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
public class FerriteCorePostProcess {
|
||||||
|
private static final boolean willPostProcess;
|
||||||
|
|
||||||
|
private static final MethodHandle theTable, toKeyIndex;
|
||||||
|
|
||||||
|
static {
|
||||||
|
boolean success = true;
|
||||||
|
MethodHandle table = null, keyIndex = null;
|
||||||
|
try {
|
||||||
|
Class<?> fastMap = Class.forName("malte0811.ferritecore.fastmap.FastMap");
|
||||||
|
Field field = fastMap.getDeclaredField("toKeyIndex");
|
||||||
|
field.setAccessible(true);
|
||||||
|
keyIndex = MethodHandles.publicLookup().unreflectSetter(field);
|
||||||
|
field = StateHolder.class.getDeclaredField("ferritecore_globalTable");
|
||||||
|
field.setAccessible(true);
|
||||||
|
table = MethodHandles.publicLookup().unreflectGetter(field);
|
||||||
|
} catch(ReflectiveOperationException | RuntimeException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
willPostProcess = success;
|
||||||
|
theTable = table;
|
||||||
|
toKeyIndex = keyIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Object2IntMap<?> EMPTY_MAP = Object2IntMaps.unmodifiable(new Object2IntArrayMap<>());
|
||||||
|
|
||||||
|
public static <O, S extends StateHolder<O, S>> void postProcess(StateDefinition<O, S> state) {
|
||||||
|
if(!willPostProcess)
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
if(state.getProperties().size() == 0) {
|
||||||
|
for(S holder : state.getPossibleStates()) {
|
||||||
|
// deduplicate Object2IntMap objects from FerriteCore
|
||||||
|
// will probably be fixed upstream at some point, but likely not for older versions
|
||||||
|
Object table = theTable.invoke(holder);
|
||||||
|
toKeyIndex.invoke(table, EMPTY_MAP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectList;
|
||||||
|
import net.minecraft.core.MappedRegistry;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||||
|
|
||||||
|
@Mixin(MappedRegistry.class)
|
||||||
|
public class MappedRegistryMixin {
|
||||||
|
/**
|
||||||
|
* Avoid copying the ID list to a slightly larger one every time an entry is added to the registry.
|
||||||
|
* The original behavior causes O(n) time complexity for registration.
|
||||||
|
*/
|
||||||
|
@Redirect(
|
||||||
|
method = "registerMapping(ILnet/minecraft/resources/ResourceKey;Ljava/lang/Object;Lcom/mojang/serialization/Lifecycle;Z)Lnet/minecraft/core/Holder;",
|
||||||
|
at = @At(value = "INVOKE", target = "Lit/unimi/dsi/fastutil/objects/ObjectList;size(I)V")
|
||||||
|
)
|
||||||
|
private void setSizeSmart(ObjectList<?> list, int size) {
|
||||||
|
if(list instanceof ObjectArrayList && size > list.size()) {
|
||||||
|
int requestedSize = size;
|
||||||
|
/* choose next power of two, or this value if it is a power of two */
|
||||||
|
int p2Size = Integer.highestOneBit(size);
|
||||||
|
if(p2Size != size)
|
||||||
|
size = p2Size << 1;
|
||||||
|
// grow backing array to power-of-two size, this will return instantly in most cases
|
||||||
|
((ObjectArrayList<?>)list).ensureCapacity(size);
|
||||||
|
// write null entries to fill size, to match the behavior of list.size(int)
|
||||||
|
while(list.size() < requestedSize)
|
||||||
|
list.add(null);
|
||||||
|
} else {
|
||||||
|
list.size(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.embeddedt.modernfix.forge.mixin.perf.fast_registry_validation;
|
package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
|
@ -12,7 +12,7 @@ import java.util.Map;
|
||||||
|
|
||||||
@Mixin(ResourceKey.class)
|
@Mixin(ResourceKey.class)
|
||||||
public class ResourceKeyMixin<T> {
|
public class ResourceKeyMixin<T> {
|
||||||
private static Map<ResourceLocation, Map<ResourceLocation, ResourceKey<?>>> INTERNING_MAP = new Object2ObjectOpenHashMap<>();
|
private static final Map<ResourceLocation, Map<ResourceLocation, ResourceKey<?>>> INTERNING_MAP = new Object2ObjectOpenHashMap<>();
|
||||||
@Inject(method = "create(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/resources/ResourceKey;", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "create(Lnet/minecraft/resources/ResourceLocation;Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/resources/ResourceKey;", at = @At("HEAD"), cancellable = true)
|
||||||
private static <T> void createEfficient(ResourceLocation parent, ResourceLocation location, CallbackInfoReturnable<ResourceKey<T>> cir) {
|
private static <T> void createEfficient(ResourceLocation parent, ResourceLocation location, CallbackInfoReturnable<ResourceKey<T>> cir) {
|
||||||
synchronized (ResourceKey.class) {
|
synchronized (ResourceKey.class) {
|
||||||
|
|
@ -6,11 +6,15 @@ import net.minecraft.world.level.block.state.StateHolder;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
import net.minecraft.world.level.block.state.properties.Property;
|
||||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
import org.embeddedt.modernfix.annotation.RequiresMod;
|
||||||
import org.embeddedt.modernfix.blockstate.FakeStateMap;
|
import org.embeddedt.modernfix.blockstate.FakeStateMap;
|
||||||
|
import org.embeddedt.modernfix.blockstate.FerriteCorePostProcess;
|
||||||
|
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||||
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.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -27,4 +31,11 @@ public class StateDefinitionMixin<O, S extends StateHolder<O, S>> {
|
||||||
}
|
}
|
||||||
return new FakeStateMap<>(numStates);
|
return new FakeStateMap<>(numStates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "<init>", at = @At("TAIL"))
|
||||||
|
private void postProcess(CallbackInfo ci) {
|
||||||
|
// keep in dev only until upstream FC releases
|
||||||
|
if(ModernFixPlatformHooks.INSTANCE.isDevEnv())
|
||||||
|
FerriteCorePostProcess.postProcess((StateDefinition<O, S>)(Object)this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package org.embeddedt.modernfix.forge.load;
|
||||||
|
|
||||||
|
import net.minecraftforge.fml.ModList;
|
||||||
|
import net.minecraftforge.forgespi.language.IModFileInfo;
|
||||||
|
import net.minecraftforge.forgespi.locating.IModFile;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
|
||||||
|
public class ModResourcePackPathFixer {
|
||||||
|
private static final IdentityHashMap<Path, IModFile> modFileByPath = new IdentityHashMap<>();
|
||||||
|
|
||||||
|
public static synchronized IModFile getModFileByRootPath(Path path) {
|
||||||
|
if(modFileByPath.size() == 0) {
|
||||||
|
for(IModFileInfo info : ModList.get().getModFiles()) {
|
||||||
|
modFileByPath.put(info.getFile().getFilePath(), info.getFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return modFileByPath.get(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,10 @@ package org.embeddedt.modernfix.forge.mixin.perf.resourcepacks;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.packs.PackResources;
|
import net.minecraft.server.packs.PackResources;
|
||||||
import net.minecraft.server.packs.PackType;
|
import net.minecraft.server.packs.PackType;
|
||||||
|
import net.minecraftforge.forgespi.locating.IModFile;
|
||||||
import net.minecraftforge.resource.PathPackResources;
|
import net.minecraftforge.resource.PathPackResources;
|
||||||
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
import org.embeddedt.modernfix.forge.load.ModResourcePackPathFixer;
|
||||||
import org.embeddedt.modernfix.resources.ICachingResourcePack;
|
import org.embeddedt.modernfix.resources.ICachingResourcePack;
|
||||||
import org.embeddedt.modernfix.resources.NewResourcePackAdapter;
|
import org.embeddedt.modernfix.resources.NewResourcePackAdapter;
|
||||||
import org.embeddedt.modernfix.resources.PackResourcesCacheEngine;
|
import org.embeddedt.modernfix.resources.PackResourcesCacheEngine;
|
||||||
|
|
@ -36,12 +39,26 @@ public abstract class ForgePathPackResourcesMixin implements ICachingResourcePac
|
||||||
|
|
||||||
private PackResourcesCacheEngine cacheEngine;
|
private PackResourcesCacheEngine cacheEngine;
|
||||||
|
|
||||||
|
private IModFile mfix$resolveFileOverride;
|
||||||
|
|
||||||
@Inject(method = "<init>", at = @At("TAIL"))
|
@Inject(method = "<init>", at = @At("TAIL"))
|
||||||
private void cacheResources(CallbackInfo ci) {
|
private void cacheResources(String packId, boolean isBuiltin, final Path source, CallbackInfo ci) {
|
||||||
|
// handle buggy mods instantiating at the root path, but only if they didn't override at all
|
||||||
|
// (otherwise they may have handled resolve() already)
|
||||||
|
if(((Object)this).getClass() == PathPackResources.class)
|
||||||
|
this.mfix$resolveFileOverride = ModResourcePackPathFixer.getModFileByRootPath(source);
|
||||||
|
if(this.mfix$resolveFileOverride != null)
|
||||||
|
ModernFix.LOGGER.warn("PathResourcePack base class instantiated with root path of mod file {}. This probably means a mod should be calling ResourcePackLoader.createPackForMod instead. Applying workaround.", mfix$resolveFileOverride.getFileName());
|
||||||
invalidateCache();
|
invalidateCache();
|
||||||
PackResourcesCacheEngine.track(this);
|
PackResourcesCacheEngine.track(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject(method = "resolve", at = @At("HEAD"), cancellable = true, remap = false)
|
||||||
|
private void resolveViaModFile(String[] paths, CallbackInfoReturnable<Path> cir) {
|
||||||
|
if(this.mfix$resolveFileOverride != null)
|
||||||
|
cir.setReturnValue(this.mfix$resolveFileOverride.findResource(paths));
|
||||||
|
}
|
||||||
|
|
||||||
private PackResourcesCacheEngine generateResourceCache() {
|
private PackResourcesCacheEngine generateResourceCache() {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
PackResourcesCacheEngine engine = this.cacheEngine;
|
PackResourcesCacheEngine engine = this.cacheEngine;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user