Jelajahi Sumber

Merge branch 'main' into 1.17

malte0811 3 tahun lalu
induk
melakukan
fb6dc31171

+ 1 - 4
README.md

@@ -5,10 +5,7 @@ or rather their modern equivalent: RAM.
 
 (Image: Konstantin Lanzet, CC BY-SA 3.0 <http://creativecommons.org/licenses/by-sa/3.0/>, via Wikimedia Commons)
 
-I am working on getting at least some of the changes made by this mod into Forge (
-see [this issue](https://github.com/MinecraftForge/MinecraftForge/issues/7559) for progress), features will be removed
-from the Forge version of FerriteCore if and when they are added to Forge. They will still be present on Fabric. For a
-high-level description of the improvements implemented by this mod see [here](summary.md).
+For a high-level description of the improvements implemented by this mod see [here](summary.md).
 
 ### Mappings
 

+ 58 - 0
common/src/main/java/malte0811/ferritecore/mixin/dedupmultipart/MixinMultipartModel.java

@@ -0,0 +1,58 @@
+package malte0811.ferritecore.mixin.dedupmultipart;
+
+import it.unimi.dsi.fastutil.objects.Object2ObjectOpenCustomHashMap;
+import net.minecraft.block.BlockState;
+import net.minecraft.client.renderer.model.MultipartBakedModel;
+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.Redirect;
+
+import java.util.BitSet;
+import java.util.Map;
+
+/**
+ * The map implementation used for {@link MultipartBakedModel#bitSetCache} ({@link Object2ObjectOpenCustomHashMap})
+ * is not thread-safe, but getQuads is called in parallel in vanilla (and even more so in Forge with
+ * alwaysSetupTerrainOffThread=true). The only reason this works for vanilla is that the cache will never contain more
+ * than a single blockstate, since a new instance is created for each blockstate (this is probably unintentional, a map
+ * would be a weird choice for this scenario). {@link MixinMultipartBuilder} re-uses the equivalent models, so the cache
+ * can grow beyond a single element (as is probably intended). If a put-call causes the backing array to be resized
+ * concurrent get-calls can (and will) crash, so we need to synchronize them.<br>
+ * It is not clear if this implementation (naive synchronization on the cache) is optimal w.r.t.
+ * runtime/parallelization, in my experience this part of the code is not runtime-critical enough to put significant
+ * effort into fancy parallelization solutions (may change in the future).
+ */
+// Non-final fields: Work around Java/Mixin limitations
+// Unresolved reference: Forge adds a parameter to getQuads, so the usual remapping process breaks and I need to specify
+// SRG and intermediary names directly, which confuses the MCDev IntelliJ plugin
+@SuppressWarnings({"SynchronizeOnNonFinalField", "UnresolvedMixinReference"})
+@Mixin(MultipartBakedModel.class)
+public class MixinMultipartModel {
+    @Shadow
+    @Final
+    private Map<BlockState, BitSet> bitSetCache;
+
+    @Redirect(
+            method = {"method_4707", "func_200117_a", "getQuads"},
+            at = @At(value = "INVOKE", target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;"),
+            remap = false
+    )
+    public <K, V> V redirectCacheGet(Map<K, V> map, K key) {
+        synchronized (bitSetCache) {
+            return map.get(key);
+        }
+    }
+
+    @Redirect(
+            method = {"method_4707", "func_200117_a", "getQuads"},
+            at = @At(value = "INVOKE", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
+            remap = false
+    )
+    public <K, V> V redirectCachePut(Map<K, V> map, K key, V value) {
+        synchronized (bitSetCache) {
+            return map.put(key, value);
+        }
+    }
+}

+ 11 - 7
common/src/main/java/malte0811/ferritecore/mixin/fastmap/FastMapStateHolderMixin.java

@@ -22,8 +22,8 @@ public abstract class FastMapStateHolderMixin<O, S> implements FastMapStateHolde
     @Shadow
     private Table<Property<?>, Comparable<?>, S> neighbours;
 
-    private int globalTableIndex;
-    private FastMap<S> globalTable;
+    private int ferritecore_globalTableIndex;
+    private FastMap<S> ferritecore_globalTable;
 
     @Redirect(
             method = "setValue",
@@ -34,7 +34,11 @@ public abstract class FastMapStateHolderMixin<O, S> implements FastMapStateHolde
             )
     )
     public Object getNeighborFromFastMap(Table<?, ?, ?> ignore, Object rowKey, Object columnKey) {
-        return this.globalTable.withUnsafe(this.globalTableIndex, (Property<?>) rowKey, columnKey);
+        return this.ferritecore_globalTable.withUnsafe(
+                this.ferritecore_globalTableIndex,
+                (Property<?>) rowKey,
+                columnKey
+        );
     }
 
     /**
@@ -49,12 +53,12 @@ public abstract class FastMapStateHolderMixin<O, S> implements FastMapStateHolde
 
     @Override
     public FastMap<S> getStateMap() {
-        return globalTable;
+        return ferritecore_globalTable;
     }
 
     @Override
     public int getStateIndex() {
-        return globalTableIndex;
+        return ferritecore_globalTableIndex;
     }
 
     @Override
@@ -69,12 +73,12 @@ public abstract class FastMapStateHolderMixin<O, S> implements FastMapStateHolde
 
     @Override
     public void setStateMap(FastMap<S> newValue) {
-        globalTable = newValue;
+        ferritecore_globalTable = newValue;
     }
 
     @Override
     public void setStateIndex(int newValue) {
-        globalTableIndex = newValue;
+        ferritecore_globalTableIndex = newValue;
     }
 
     @Override

+ 2 - 1
common/src/main/resources/ferritecore.dedupmultipart.mixin.json

@@ -8,7 +8,8 @@
   "minVersion": "0.8",
   "plugin": "malte0811.ferritecore.mixin.dedupmultipart.Config",
   "client": [
-    "MixinMultipartBuilder"
+    "MixinMultipartBuilder",
+    "MixinMultipartModel"
   ],
   "mixins": []
 }

+ 1 - 1
fabric/src/main/resources/fabric.mod.json

@@ -22,7 +22,7 @@
   },
   "depends": {
     "fabricloader": ">=0.7.4",
-    "minecraft": ">=1.17"
+    "minecraft": ">=1.17.1"
   },
   "mixins": [
     "ferritecore.blockstatecache.mixin.json",

+ 1 - 1
forge/src/main/resources/META-INF/mods.toml

@@ -8,7 +8,7 @@ version = "${version}"
 displayName = "Ferrite Core"
 authors="malte0811"
 description='''
-Reduces memory usage. Some of these changes will probably be PRd to Forge soon.
+Reduces memory usage.
 '''
 logoFile="logo.png"
 [[dependencies.ferritecore]]

+ 1 - 1
gradle/wrapper/gradle-wrapper.properties

@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists