From f274dc1f5f2a38621d2a413a820d5f97cc9314e3 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 2 May 2023 14:44:48 -0400 Subject: [PATCH 1/2] Add resource caching to Fabric --- fabric/build.gradle | 1 + .../ModNioResourcePackMixin.java | 56 +++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java diff --git a/fabric/build.gradle b/fabric/build.gradle index 8cedb676..a7d20969 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -32,6 +32,7 @@ dependencies { modIncludeImplementation(fabricApi.module("fabric-api-base", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modIncludeImplementation(fabricApi.module("fabric-lifecycle-events-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } modIncludeImplementation(fabricApi.module("fabric-screen-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } + modImplementation(fabricApi.module("fabric-resource-loader-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' } // Remove the next line if you don't want to depend on the API // modApi "me.shedaniel:architectury-fabric:${rootProject.architectury_version}" diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java new file mode 100644 index 00000000..f115f943 --- /dev/null +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java @@ -0,0 +1,56 @@ +package org.embeddedt.modernfix.fabric.mixin.perf.fabric_resourcepacks; + +import net.fabricmc.fabric.impl.resource.loader.ModNioResourcePack; +import net.minecraft.server.packs.PackType; +import org.embeddedt.modernfix.annotation.RequiresMod; +import org.embeddedt.modernfix.resources.PackResourcesCacheEngine; +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.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.util.Set; + +@Mixin(ModNioResourcePack.class) +@RequiresMod("fabric-resource-loader-v0") +public abstract class ModNioResourcePackMixin { + @Shadow public abstract Set getNamespaces(PackType type); + + @Shadow @Final private Path basePath; + private PackResourcesCacheEngine cacheEngine; + + @Inject(method = "", at = @At("RETURN")) + private void cacheResources(CallbackInfo ci) { + this.cacheEngine = new PackResourcesCacheEngine(this::getNamespaces, (type, namespace) -> { + return basePath.resolve(type.getDirectory()).resolve(namespace); + }); + } + + // this check wastes CPU time, it is checked later anyway + @Redirect(method = "getPath", at = @At(value = "INVOKE", target = "Ljava/nio/file/Files;exists(Ljava/nio/file/Path;[Ljava/nio/file/LinkOption;)Z"), remap = false) + private boolean checkExists(Path p, LinkOption[] opts) { + return true; + } + + // TODO might be redundant + @Inject(method = "getNamespaces", at = @At("HEAD"), cancellable = true) + private void useCacheForNamespaces(PackType type, CallbackInfoReturnable> cir) { + if(cacheEngine != null) { + Set namespaces = cacheEngine.getNamespaces(type); + if(namespaces != null) + cir.setReturnValue(namespaces); + } + } + + @Inject(method = "hasResource", at = @At(value = "HEAD"), cancellable = true) + private void useCacheForExistence(String path, CallbackInfoReturnable cir) { + if(cacheEngine != null) + cir.setReturnValue(this.cacheEngine.hasResource(path)); + } +} From 3db4e9071f7dfd34778c0af31166be862c6ac017 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Tue, 2 May 2023 14:52:21 -0400 Subject: [PATCH 2/2] Update resource pack mixin --- .../ModNioResourcePackMixin.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java index f115f943..e0cd8827 100644 --- a/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java +++ b/fabric/src/main/java/org/embeddedt/modernfix/fabric/mixin/perf/fabric_resourcepacks/ModNioResourcePackMixin.java @@ -1,7 +1,9 @@ package org.embeddedt.modernfix.fabric.mixin.perf.fabric_resourcepacks; import net.fabricmc.fabric.impl.resource.loader.ModNioResourcePack; +import net.fabricmc.loader.api.metadata.ModMetadata; import net.minecraft.server.packs.PackType; +import org.embeddedt.modernfix.ModernFix; import org.embeddedt.modernfix.annotation.RequiresMod; import org.embeddedt.modernfix.resources.PackResourcesCacheEngine; import org.spongepowered.asm.mixin.Final; @@ -13,8 +15,8 @@ import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.nio.file.LinkOption; import java.nio.file.Path; +import java.util.List; import java.util.Set; @Mixin(ModNioResourcePack.class) @@ -22,19 +24,24 @@ import java.util.Set; public abstract class ModNioResourcePackMixin { @Shadow public abstract Set getNamespaces(PackType type); - @Shadow @Final private Path basePath; + @Shadow @Final private List basePaths; + @Shadow @Final private ModMetadata modInfo; private PackResourcesCacheEngine cacheEngine; @Inject(method = "", at = @At("RETURN")) private void cacheResources(CallbackInfo ci) { - this.cacheEngine = new PackResourcesCacheEngine(this::getNamespaces, (type, namespace) -> { - return basePath.resolve(type.getDirectory()).resolve(namespace); - }); + if(this.basePaths.size() == 1) { + Path basePath = this.basePaths.get(0); + this.cacheEngine = new PackResourcesCacheEngine(this::getNamespaces, (type, namespace) -> { + return basePath.resolve(type.getDirectory()).resolve(namespace); + }); + } else + ModernFix.LOGGER.warn("Cannot cache resource pack for mod '{}' as it uses multiple base paths", modInfo.getId()); } // this check wastes CPU time, it is checked later anyway - @Redirect(method = "getPath", at = @At(value = "INVOKE", target = "Ljava/nio/file/Files;exists(Ljava/nio/file/Path;[Ljava/nio/file/LinkOption;)Z"), remap = false) - private boolean checkExists(Path p, LinkOption[] opts) { + @Redirect(method = "getPath", at = @At(value = "INVOKE", target = "Lnet/fabricmc/fabric/impl/resource/loader/ModNioResourcePack;exists(Ljava/nio/file/Path;)Z"), remap = false) + private boolean checkExists(Path path) { return true; }