Procházet zdrojové kódy

Simplify "no property map" code using the new ImmutableMap implementation

malte0811 před 4 roky
rodič
revize
2c358a6c74

+ 0 - 1
build.gradle

@@ -15,7 +15,6 @@ subprojects {
     def fcMixinConfigs = [
             "predicates",
             "fastmap",
-            "nopropertymap",
             "mrl",
             "dedupmultipart",
             "blockstatecache",

+ 12 - 11
common/src/main/java/com/google/common/collect/FerriteCoreEntrySet.java

@@ -7,27 +7,28 @@ import org.jetbrains.annotations.Nullable;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.IntFunction;
+import java.util.function.IntSupplier;
 
-public class FerriteCoreEntrySet<K, V> extends ImmutableSet<Map.Entry<K, V>> {
-    private final int numProperties;
-    private final Function<Object, V> getValue;
-    private final IntFunction<Map.Entry<K, V>> getIth;
+public class FerriteCoreEntrySet<K, V, F extends Function<Object, V> & IntFunction<Map.Entry<K, V>> & IntSupplier>
+        extends ImmutableSet<Map.Entry<K, V>> {
+    // Function<Object, V>: Map#get
+    // IntFunction<Entry<K, V>>: get i-th entry of the map
+    // IntSupplier: Map#size
+    private final F access;
 
-    public FerriteCoreEntrySet(int numProperties, Function<Object, V> getValue, IntFunction<Map.Entry<K, V>> getIth) {
-        this.numProperties = numProperties;
-        this.getValue = getValue;
-        this.getIth = getIth;
+    public FerriteCoreEntrySet(F access) {
+        this.access = access;
     }
 
     @Override
     @NotNull
     public UnmodifiableIterator<Map.Entry<K, V>> iterator() {
-        return new FerriteCoreIterator<>(getIth, size());
+        return new FerriteCoreIterator<>(access, size());
     }
 
     @Override
     public int size() {
-        return numProperties;
+        return access.getAsInt();
     }
 
     @Override
@@ -39,7 +40,7 @@ public class FerriteCoreEntrySet<K, V> extends ImmutableSet<Map.Entry<K, V>> {
         if (!(entry.getKey() instanceof Property<?>)) {
             return false;
         }
-        Object valueInMap = getValue.apply(entry.getKey());
+        Object valueInMap = access.apply(entry.getKey());
         return valueInMap != null && valueInMap.equals(((Map.Entry<?, ?>) object).getValue());
     }
 

+ 13 - 12
common/src/main/java/com/google/common/collect/FerriteCoreImmutableMap.java

@@ -5,32 +5,33 @@ import org.jetbrains.annotations.Nullable;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.IntFunction;
+import java.util.function.IntSupplier;
 
-public class FerriteCoreImmutableMap<K, V> extends ImmutableMap<K, V> {
+public class FerriteCoreImmutableMap<K, V, F extends Function<Object, V> & IntFunction<Map.Entry<K, V>> & IntSupplier>
+        extends ImmutableMap<K, V> {
     // This is a quite inconvenient "handle" on a FastMap, but we need classloader separation
-    private final int numProperties;
-    private final Function<Object, V> getValue;
-    private final IntFunction<Entry<K, V>> getIth;
-
-    public FerriteCoreImmutableMap(int numProperties, Function<Object, V> getValue, IntFunction<Entry<K, V>> getIth) {
-        this.numProperties = numProperties;
-        this.getValue = getValue;
-        this.getIth = getIth;
+    // Function<Object, V>: Map#get
+    // IntFunction<Entry<K, V>>: get i-th entry of the map
+    // IntSupplier: Map#size
+    private final F access;
+
+    public FerriteCoreImmutableMap(F access) {
+        this.access = access;
     }
 
     @Override
     public int size() {
-        return numProperties;
+        return access.getAsInt();
     }
 
     @Override
     public V get(@Nullable Object key) {
-        return getValue.apply(key);
+        return access.apply(key);
     }
 
     @Override
     ImmutableSet<Map.Entry<K, V>> createEntrySet() {
-        return new FerriteCoreEntrySet<>(numProperties, getValue, getIth);
+        return new FerriteCoreEntrySet<>(access);
     }
 
     @Override

+ 9 - 6
common/src/main/java/malte0811/ferritecore/classloading/ClassDefiner.java

@@ -12,6 +12,7 @@ import java.lang.reflect.Method;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.function.IntFunction;
+import java.util.function.IntSupplier;
 
 public class ClassDefiner {
     private static final LazyValue<MethodHandle> MAKE_IMMUTABLE_FAST_MAP = new LazyValue<>(() -> {
@@ -20,19 +21,21 @@ public class ClassDefiner {
             define("com.google.common.collect.FerriteCoreEntrySet");
             Class<?> map = define("com.google.common.collect.FerriteCoreImmutableMap");
             MethodHandles.Lookup lookup = MethodHandles.lookup();
-            //int numProperties, Function<Object, V> getValue, IntFunction<Entry<K, V>> getIth
+            // Function is:
+            // Function<Object, V>: Map#get
+            // IntFunction<Entry<K, V>>: get i-th entry of the map
+            // IntSupplier: Map#size
             return lookup.findConstructor(map, MethodType.methodType(
-                    void.class, int.class, Function.class, IntFunction.class
+                    void.class, Function.class
             ));
         } catch (Exception x) {
             throw new RuntimeException(x);
         }
     });
 
-    public static <K, V> ImmutableMap<K, V> makeMap(
-            int numProperties, Function<Object, V> getValue, IntFunction<Map.Entry<K, V>> getIth
-    ) throws Throwable {
-        return (ImmutableMap<K, V>) MAKE_IMMUTABLE_FAST_MAP.getValue().invoke(numProperties, getValue, getIth);
+    public static <K, V, F extends Function<Object, V> & IntFunction<Map.Entry<K, V>> & IntSupplier>
+    ImmutableMap<K, V> makeMap(F mapAccess) throws Throwable {
+        return (ImmutableMap<K, V>) MAKE_IMMUTABLE_FAST_MAP.getValue().invoke(mapAccess);
     }
 
     private static Class<?> define(String name) throws Exception {

+ 1 - 1
common/src/main/java/malte0811/ferritecore/ducks/FastMapStateHolder.java

@@ -15,5 +15,5 @@ public interface FastMapStateHolder<S> {
 
     ImmutableMap<Property<?>, Comparable<?>> getVanillaPropertyMap();
 
-    void deleteVanillaPropertyMap();
+    void replacePropertyMap(ImmutableMap<Property<?>, Comparable<?>> newMap);
 }

+ 0 - 4
common/src/main/java/malte0811/ferritecore/ducks/NoPropertyStateHolder.java

@@ -1,4 +0,0 @@
-package malte0811.ferritecore.ducks;
-
-public interface NoPropertyStateHolder {
-}

+ 14 - 13
common/src/main/java/malte0811/ferritecore/fastmap/FastMap.java

@@ -9,22 +9,21 @@ import javax.annotation.Nullable;
 import java.util.*;
 import java.util.function.Function;
 import java.util.function.IntFunction;
+import java.util.function.IntSupplier;
 
 public class FastMap<Value> {
     private final List<FastMapKey<?>> keys;
-    private final List<Property<?>> rawKeys;
-    private final List<Value> values;
+    private final List<Value> valueMatrix;
     // It might be possible to get rid of this (and the equivalent map for values) by sorting the key vectors by
     // property name (natural order for values) and using a binary search above a given size, but choosing that size
     // would likely be more effort than it's worth
     private final Map<Property<?>, Integer> toKeyIndex;
 
     public FastMap(Collection<Property<?>> properties, Map<Map<Property<?>, Comparable<?>>, Value> valuesMap) {
-        this.rawKeys = ImmutableList.copyOf(properties);
-        List<FastMapKey<?>> keys = new ArrayList<>(rawKeys.size());
+        List<FastMapKey<?>> keys = new ArrayList<>(properties.size());
         int factorUpTo = 1;
         ImmutableMap.Builder<Property<?>, Integer> toKeyIndex = ImmutableMap.builder();
-        for (Property<?> prop : rawKeys) {
+        for (Property<?> prop : properties) {
             toKeyIndex.put(prop, keys.size());
             keys.add(new FastMapKey<>(prop, factorUpTo));
             factorUpTo *= prop.getAllowedValues().size();
@@ -39,7 +38,7 @@ public class FastMap<Value> {
         for (Map.Entry<Map<Property<?>, Comparable<?>>, Value> state : valuesMap.entrySet()) {
             valuesList.set(getIndexOf(state.getKey()), state.getValue());
         }
-        this.values = ImmutableList.copyOf(valuesList);
+        this.valueMatrix = ImmutableList.copyOf(valuesList);
     }
 
     @Nullable
@@ -53,7 +52,7 @@ public class FastMap<Value> {
         if (newIndex < 0) {
             return null;
         }
-        return values.get(newIndex);
+        return valueMatrix.get(newIndex);
     }
 
     public int getIndexOf(Map<Property<?>, Comparable<?>> state) {
@@ -74,13 +73,10 @@ public class FastMap<Value> {
         return propId.getValue(stateIndex);
     }
 
-    public List<Property<?>> getProperties() {
-        return rawKeys;
-    }
-
     public ImmutableMap<Property<?>, Comparable<?>> makeValuesFor(int index) {
         try {
-            class MapAccessor implements Function<Object, Comparable<?>>, IntFunction<Map.Entry<Property<?>, Comparable<?>>> {
+            class MapAccessor implements Function<Object, Comparable<?>>,
+                    IntFunction<Map.Entry<Property<?>, Comparable<?>>>, IntSupplier {
                 @Override
                 public Comparable<?> apply(Object obj) {
                     if (obj instanceof Property<?>) {
@@ -96,9 +92,14 @@ public class FastMap<Value> {
                             getKey(subIndex).getProperty(), getKey(subIndex).getValue(index)
                     );
                 }
+
+                @Override
+                public int getAsInt() {
+                    return numProperties();
+                }
             }
             MapAccessor func = new MapAccessor();
-            return ClassDefiner.makeMap(numProperties(), func, func);
+            return ClassDefiner.makeMap(func);
         } catch (Throwable throwable) {
             throw new RuntimeException(throwable);
         }

+ 3 - 3
common/src/main/java/malte0811/ferritecore/impl/StateHolderImpl.java

@@ -1,8 +1,8 @@
 package malte0811.ferritecore.impl;
 
 import malte0811.ferritecore.ducks.FastMapStateHolder;
-import malte0811.ferritecore.ducks.NoPropertyStateHolder;
 import malte0811.ferritecore.fastmap.FastMap;
+import malte0811.ferritecore.mixin.config.FerriteConfig;
 import net.minecraft.state.Property;
 
 import java.util.Map;
@@ -26,8 +26,8 @@ public class StateHolderImpl {
         }
         int index = holder.getStateMap().getIndexOf(holder.getVanillaPropertyMap());
         holder.setStateIndex(index);
-        if (holder instanceof NoPropertyStateHolder) {
-            holder.deleteVanillaPropertyMap();
+        if (FerriteConfig.PROPERTY_MAP.isEnabled()) {
+            holder.replacePropertyMap(holder.getStateMap().makeValuesFor(holder.getStateIndex()));
         }
     }
 }

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

@@ -61,8 +61,8 @@ public abstract class FastMapStateHolderMixin<O, S> implements FastMapStateHolde
     }
 
     @Override
-    public void deleteVanillaPropertyMap() {
-        properties = null;
+    public void replacePropertyMap(ImmutableMap<Property<?>, Comparable<?>> newMap) {
+        properties = newMap;
     }
 
     @Override

+ 0 - 24
common/src/main/java/malte0811/ferritecore/mixin/nopropertymap/Config.java

@@ -1,24 +0,0 @@
-package malte0811.ferritecore.mixin.nopropertymap;
-
-import com.google.common.collect.ImmutableList;
-import malte0811.ferritecore.mixin.config.FerriteConfig;
-import malte0811.ferritecore.mixin.config.FerriteMixinConfig;
-import org.objectweb.asm.tree.ClassNode;
-import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
-
-import java.util.List;
-
-public class Config extends FerriteMixinConfig {
-    @Override
-    protected List<String> getAllMixins() {
-        return ImmutableList.of("NoPropertyStateHolderMixin");
-    }
-
-    @Override
-    protected boolean isEnabled(String mixin) {
-        return FerriteConfig.PROPERTY_MAP.isEnabled();
-    }
-
-    @Override
-    public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {}
-}

+ 0 - 72
common/src/main/java/malte0811/ferritecore/mixin/nopropertymap/NoPropertyStateHolderMixin.java

@@ -1,72 +0,0 @@
-package malte0811.ferritecore.mixin.nopropertymap;
-
-import com.google.common.collect.ImmutableMap;
-import malte0811.ferritecore.ducks.FastMapStateHolder;
-import malte0811.ferritecore.ducks.NoPropertyStateHolder;
-import malte0811.ferritecore.fastmap.FastMap;
-import net.minecraft.state.Property;
-import net.minecraft.state.StateHolder;
-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.Coerce;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.Redirect;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import java.util.Collection;
-
-@Mixin(StateHolder.class)
-public abstract class NoPropertyStateHolderMixin implements NoPropertyStateHolder {
-    @Shadow
-    public abstract ImmutableMap<Property<?>, Comparable<?>> getValues();
-
-    // All other Mixins: If the new data structures are initialized, use those. Otherwise (if populateNeighbors didn't
-    // run yet) use the vanilla code using `properties`
-    @Redirect(
-            method = {"get", "func_235903_d_", "with"},
-            at = @At(
-                    value = "INVOKE",
-                    target = "Lcom/google/common/collect/ImmutableMap;get(Ljava/lang/Object;)Ljava/lang/Object;",
-                    remap = false
-            )
-    )
-    @Coerce
-    public Object getValueOfProperty(ImmutableMap<?, ?> vanillaMap, Object key) {
-        final FastMap<?> globalTable = ((FastMapStateHolder<?>) this).getStateMap();
-        final int globalTableIndex = ((FastMapStateHolder<?>) this).getStateIndex();
-        if (globalTable != null) {
-            return globalTable.getValue(globalTableIndex, (Property<?>) key);
-        } else {
-            return vanillaMap.get(key);
-        }
-    }
-
-    @Inject(method = "getValues", at = @At("HEAD"), cancellable = true)
-    public void getValuesHead(CallbackInfoReturnable<ImmutableMap<Property<?>, Comparable<?>>> cir) {
-        final FastMap<?> globalTable = ((FastMapStateHolder<?>) this).getStateMap();
-        if (globalTable != null) {
-            cir.setReturnValue(globalTable.makeValuesFor(((FastMapStateHolder<?>) this).getStateIndex()));
-            cir.cancel();
-        }
-    }
-
-    @Inject(method = "hasProperty", at = @At("HEAD"), cancellable = true)
-    public <T extends Comparable<T>>
-    void hasPropertyHead(Property<T> property, CallbackInfoReturnable<Boolean> cir) {
-        final FastMap<?> globalTable = ((FastMapStateHolder<?>) this).getStateMap();
-        if (globalTable != null) {
-            cir.setReturnValue(globalTable.getProperties().contains(property));
-            cir.cancel();
-        }
-    }
-
-    @Inject(method = "getProperties", at = @At("HEAD"), cancellable = true)
-    public void getPropertiesHead(CallbackInfoReturnable<Collection<Property<?>>> cir) {
-        final FastMap<?> globalTable = ((FastMapStateHolder<?>) this).getStateMap();
-        if (globalTable != null) {
-            cir.setReturnValue(globalTable.getProperties());
-            cir.cancel();
-        }
-    }
-}

+ 0 - 14
common/src/main/resources/ferritecore.nopropertymap.mixin.json

@@ -1,14 +0,0 @@
-{
-  "required": true,
-  "package": "malte0811.ferritecore.mixin.nopropertymap",
-  "compatibilityLevel": "JAVA_8",
-  "refmap": "ferritecore-common-refmap.json",
-  "mixins": [
-    "NoPropertyStateHolderMixin"
-  ],
-  "injectors": {
-    "defaultRequire": 1
-  },
-  "minVersion": "0.8",
-  "plugin": "malte0811.ferritecore.mixin.nopropertymap.Config"
-}

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

@@ -20,7 +20,6 @@
     "ferritecore.dedupmultipart.mixin.json",
     "ferritecore.fastmap.mixin.json",
     "ferritecore.mrl.mixin.json",
-    "ferritecore.nopropertymap.mixin.json",
     "ferritecore.predicates.mixin.json",
     "ferritecore.fabric.mixin.json"
   ]