Merge remote-tracking branch 'origin/1.16' into 1.18
This commit is contained in:
commit
d92e48e1aa
|
|
@ -0,0 +1,22 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import org.embeddedt.modernfix.registry.DirectStorageRegistryObject;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
|
||||
@Mixin({ Block.class, Item.class })
|
||||
public class DirectObjectMixin implements DirectStorageRegistryObject {
|
||||
private ResourceLocation mfix$resourceKey;
|
||||
|
||||
@Override
|
||||
public ResourceLocation mfix$getResourceKey() {
|
||||
return mfix$resourceKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mfix$setResourceKey(ResourceLocation key) {
|
||||
mfix$resourceKey = key;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.compact_mojang_registries;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import net.minecraft.core.MappedRegistry;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.embeddedt.modernfix.annotation.IgnoreOutsideDev;
|
||||
import org.embeddedt.modernfix.registry.LifecycleMap;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Mutable;
|
||||
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.callback.CallbackInfo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(MappedRegistry.class)
|
||||
@IgnoreOutsideDev
|
||||
public abstract class MappedRegistryMixin<T> extends Registry<T> {
|
||||
@Shadow
|
||||
@Final
|
||||
@Mutable
|
||||
private Map<T, Lifecycle> lifecycles;
|
||||
|
||||
private static final ImmutableSet<ResourceLocation> MFIX$NEW_STORAGE_KEYS = ImmutableSet.of(new ResourceLocation("block"), new ResourceLocation("item"));
|
||||
|
||||
protected MappedRegistryMixin(ResourceKey<? extends Registry<T>> resourceKey, Lifecycle lifecycle) {
|
||||
super(resourceKey, lifecycle);
|
||||
}
|
||||
|
||||
@Inject(method = "<init>", at = @At("RETURN"))
|
||||
private void replaceStorage(CallbackInfo ci) {
|
||||
this.lifecycles = new LifecycleMap<>();
|
||||
/*
|
||||
if(MFIX$NEW_STORAGE_KEYS.contains(this.key().location())) {
|
||||
ModernFixMixinPlugin.instance.logger.info("Using experimental registry storage for {}", this.key());
|
||||
this.storage = (BiMap<ResourceLocation, T>) RegistryStorage.createStorage();
|
||||
this.keyStorage = (BiMap<ResourceKey<T>, T>)RegistryStorage.createKeyStorage(this.key(), (BiMap<ResourceLocation, DirectStorageRegistryObject>)this.storage);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package org.embeddedt.modernfix.common.mixin.perf.mojang_registry_size;
|
||||
|
||||
import com.google.common.collect.ArrayTable;
|
||||
import com.google.common.collect.HashBasedTable;
|
||||
import com.google.common.collect.ImmutableTable;
|
||||
import com.google.common.collect.Table;
|
||||
import net.minecraft.world.level.block.state.StateHolder;
|
||||
|
|
@ -23,7 +25,7 @@ public class StateHolderMixin {
|
|||
/* optimize the case where block has no properties */
|
||||
@Inject(method = "populateNeighbours", at = @At("RETURN"), require = 0)
|
||||
private void replaceEmptyTable(CallbackInfo ci) {
|
||||
if(this.neighbours.isEmpty())
|
||||
if((this.neighbours instanceof ArrayTable || this.neighbours instanceof HashBasedTable) && this.neighbours.isEmpty())
|
||||
this.neighbours = ImmutableTable.of();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import org.embeddedt.modernfix.ModernFix;
|
|||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.embeddedt.modernfix.annotation.IgnoreOutsideDev;
|
||||
import org.embeddedt.modernfix.annotation.RequiresMod;
|
||||
import org.embeddedt.modernfix.core.ModernFixMixinPlugin;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.Type;
|
||||
|
|
@ -250,6 +251,17 @@ public class ModernFixEarlyConfig {
|
|||
}
|
||||
}
|
||||
|
||||
private void readJVMProperties() {
|
||||
for(String optionKey : this.options.keySet()) {
|
||||
String value = System.getProperty("modernfix.config." + optionKey);
|
||||
if(value == null || value.length() == 0)
|
||||
continue;
|
||||
boolean isEnabled = Boolean.valueOf(value);
|
||||
ModernFixMixinPlugin.instance.logger.info("Configured {} to '{}' via JVM property.", optionKey, isEnabled);
|
||||
this.options.get(optionKey).setEnabled(isEnabled, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void readProperties(Properties props) {
|
||||
if(ALLOW_OVERRIDE_OVERRIDES)
|
||||
LOGGER.fatal("JVM argument given to override mod overrides. Issues opened with this option present will be ignored unless they can be reproduced without.");
|
||||
|
|
@ -338,6 +350,8 @@ public class ModernFixEarlyConfig {
|
|||
} catch (IOException e) {
|
||||
LOGGER.warn("Could not write configuration file", e);
|
||||
}
|
||||
|
||||
config.readJVMProperties();
|
||||
}
|
||||
|
||||
return config;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.embeddedt.modernfix.dynamicresources;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.mojang.math.Transformation;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
|
|
@ -25,6 +26,15 @@ import java.util.function.BiFunction;
|
|||
import java.util.stream.Collectors;
|
||||
|
||||
public class DynamicBakedModelProvider implements Map<ResourceLocation, BakedModel> {
|
||||
/**
|
||||
* The list of blacklisted resource locations that are never baked as top-level models.
|
||||
*
|
||||
* This is a hack to get around the fact that we don't really know exactly what models were supposed to end up
|
||||
* in the baked registry ahead of time.
|
||||
*/
|
||||
private static final ImmutableSet<ResourceLocation> BAKE_SKIPPED_TOPLEVEL = ImmutableSet.<ResourceLocation>builder()
|
||||
.add(new ResourceLocation("custommachinery", "block/custom_machine_block"))
|
||||
.build();
|
||||
public static DynamicBakedModelProvider currentInstance = null;
|
||||
private final ModelBakery bakery;
|
||||
private final Map<Triple<ResourceLocation, Transformation, Boolean>, BakedModel> bakedCache;
|
||||
|
|
@ -135,7 +145,10 @@ public class DynamicBakedModelProvider implements Map<ResourceLocation, BakedMod
|
|||
return model;
|
||||
else {
|
||||
try {
|
||||
model = bakery.bake((ResourceLocation)o, BlockModelRotation.X0_Y0);
|
||||
if(BAKE_SKIPPED_TOPLEVEL.contains((ResourceLocation)o))
|
||||
model = missingModel;
|
||||
else
|
||||
model = bakery.bake((ResourceLocation)o, BlockModelRotation.X0_Y0);
|
||||
} catch(RuntimeException e) {
|
||||
ModernFix.LOGGER.error("Exception baking {}: {}", o, e);
|
||||
model = missingModel;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
package org.embeddedt.modernfix.registry;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class DirectStorageBiMap<K, V> implements BiMap<K, V> {
|
||||
private final Function<V, K> keyGetter;
|
||||
private final BiConsumer<V, K> keySetter;
|
||||
private final Map<K, V> forwardMap;
|
||||
|
||||
public DirectStorageBiMap(Function<V, K> keyGetter, BiConsumer<V, K> keySetter) {
|
||||
Objects.requireNonNull(keyGetter);
|
||||
Objects.requireNonNull(keySetter);
|
||||
this.keyGetter = keyGetter;
|
||||
this.keySetter = keySetter;
|
||||
this.forwardMap = new Object2ObjectOpenHashMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.forwardMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.forwardMap.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object o) {
|
||||
return this.forwardMap.containsKey(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object o) {
|
||||
return o != null && keyGetter.apply((V)o) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public V get(Object o) {
|
||||
return this.forwardMap.get(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V put(K key, V value) {
|
||||
if(this.forwardMap.containsKey(key) || (value != null && keyGetter.apply(value) != null))
|
||||
throw new IllegalArgumentException("Already have mapping for " + key);
|
||||
return forcePut(key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V remove(Object o) {
|
||||
return put((K)o, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public V forcePut(K key, V value) {
|
||||
V previousValue = this.forwardMap.put(key, value);
|
||||
if(previousValue != null)
|
||||
keySetter.accept(previousValue, null);
|
||||
if(value != null)
|
||||
keySetter.accept(value, key);
|
||||
return previousValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends K, ? extends V> map) {
|
||||
map.forEach(this::put);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
for(V value : this.forwardMap.values()) {
|
||||
if(value != null)
|
||||
keySetter.accept(value, null);
|
||||
}
|
||||
this.forwardMap.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<K> keySet() {
|
||||
return this.forwardMap.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<V> values() {
|
||||
return new HashSet<>(this.forwardMap.values());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Entry<K, V>> entrySet() {
|
||||
return this.forwardMap.entrySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiMap<V, K> inverse() {
|
||||
return new Reverse();
|
||||
}
|
||||
|
||||
class Reverse implements BiMap<V, K> {
|
||||
@Override
|
||||
public int size() {
|
||||
return DirectStorageBiMap.this.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return DirectStorageBiMap.this.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object o) {
|
||||
return DirectStorageBiMap.this.containsValue(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object o) {
|
||||
return DirectStorageBiMap.this.containsKey(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public K get(Object o) {
|
||||
return o == null ? null : keyGetter.apply((V)o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public K put(V key, K value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public K remove(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public K forcePut(V key, K value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends V, ? extends K> map) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<V> keySet() {
|
||||
return DirectStorageBiMap.this.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<K> values() {
|
||||
return DirectStorageBiMap.this.keySet();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Entry<V, K>> entrySet() {
|
||||
return DirectStorageBiMap.this.entrySet().stream()
|
||||
.map(entry -> new AbstractMap.SimpleImmutableEntry<>(entry.getValue(), entry.getKey()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiMap<K, V> inverse() {
|
||||
return DirectStorageBiMap.this;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package org.embeddedt.modernfix.registry;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public interface DirectStorageRegistryObject {
|
||||
ResourceLocation mfix$getResourceKey();
|
||||
void mfix$setResourceKey(ResourceLocation key);
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.embeddedt.modernfix.registry;
|
||||
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceOpenHashMap;
|
||||
|
||||
public class LifecycleMap<T> extends Reference2ReferenceOpenHashMap<T, Lifecycle> {
|
||||
public LifecycleMap() {
|
||||
this.defaultReturnValue(Lifecycle.stable());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lifecycle put(T t, Lifecycle lifecycle) {
|
||||
if(lifecycle != defRetValue)
|
||||
return super.put(t, lifecycle);
|
||||
else {
|
||||
// need the duplicate containsKey/get logic here to override the default return value
|
||||
return super.containsKey(t) ? super.get(t) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package org.embeddedt.modernfix.registry;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class RegistryStorage {
|
||||
public static BiMap<ResourceLocation, DirectStorageRegistryObject> createStorage() {
|
||||
return new DirectStorageBiMap<>(DirectStorageRegistryObject::mfix$getResourceKey, DirectStorageRegistryObject::mfix$setResourceKey);
|
||||
}
|
||||
|
||||
public static <T> BiMap<ResourceKey<T>, DirectStorageRegistryObject> createKeyStorage(ResourceKey<? extends Registry<T>> registryKey, BiMap<ResourceLocation, DirectStorageRegistryObject> storage) {
|
||||
if(storage instanceof DirectStorageBiMap) {
|
||||
DirectStorageBiMap<ResourceLocation, DirectStorageRegistryObject> directStorageBiMap = (DirectStorageBiMap<ResourceLocation, DirectStorageRegistryObject>)storage;
|
||||
// silently ignore put/putAll calls on this map
|
||||
return new TransformingBiMap<ResourceLocation, DirectStorageRegistryObject, ResourceKey<T>, DirectStorageRegistryObject>(directStorageBiMap, loc -> ResourceKey.create(registryKey, loc), ResourceKey::location, Function.identity(), Function.identity()) {
|
||||
@Override
|
||||
public DirectStorageRegistryObject put(ResourceKey<T> key, DirectStorageRegistryObject value) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends ResourceKey<T>, ? extends DirectStorageRegistryObject> map) {
|
||||
|
||||
}
|
||||
};
|
||||
} else
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
package org.embeddedt.modernfix.registry;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.google.common.collect.Iterators;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class TransformingBiMap<KFrom, VFrom, KTo, VTo> implements BiMap<KTo, VTo> {
|
||||
private final BiMap<KFrom, VFrom> delegate;
|
||||
private final Function<KFrom, KTo> keyFwd;
|
||||
private final Function<KTo, KFrom> keyBack;
|
||||
private final Function<VFrom, VTo> valueFwd;
|
||||
private final Function<VTo, VFrom> valueBack;
|
||||
|
||||
public TransformingBiMap(BiMap<KFrom, VFrom> map, Function<KFrom, KTo> keyFwd, Function<KTo, KFrom> keyBack, Function<VFrom, VTo> valueFwd, Function<VTo, VFrom> valueBack) {
|
||||
this.delegate = map;
|
||||
this.keyFwd = keyFwd;
|
||||
this.keyBack = keyBack;
|
||||
this.valueFwd = valueFwd;
|
||||
this.valueBack = valueBack;
|
||||
}
|
||||
|
||||
private KFrom keyBack(KTo key) {
|
||||
return key == null ? null : this.keyBack.apply(key);
|
||||
}
|
||||
|
||||
private KTo keyFwd(KFrom key) {
|
||||
return key == null ? null : this.keyFwd.apply(key);
|
||||
}
|
||||
|
||||
private VFrom valueBack(VTo value) {
|
||||
return value == null ? null : this.valueBack.apply(value);
|
||||
}
|
||||
|
||||
private VTo valueFwd(VFrom value) {
|
||||
return value == null ? null : this.valueFwd.apply(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.delegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.delegate.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object o) {
|
||||
return this.delegate.containsKey(keyBack((KTo)o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsValue(Object o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public VTo get(Object o) {
|
||||
return valueFwd(this.delegate.get(keyBack((KTo)o)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VTo put(KTo key, VTo value) {
|
||||
return valueFwd(this.delegate.put(keyBack(key), valueBack(value)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VTo remove(Object o) {
|
||||
return valueFwd(this.delegate.remove(keyBack((KTo)o)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public VTo forcePut(KTo key, VTo value) {
|
||||
return valueFwd(this.delegate.forcePut(keyBack(key), valueBack(value)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putAll(Map<? extends KTo, ? extends VTo> map) {
|
||||
map.forEach((key, value) -> {
|
||||
this.delegate.put(keyBack(key), valueBack(value));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.delegate.clear();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<KTo> keySet() {
|
||||
return new TransformingSet<>(this.delegate.keySet(), this.keyFwd, this.keyBack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<VTo> values() {
|
||||
return new TransformingSet<>(this.delegate.values(), this.valueFwd, this.valueBack);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Set<Entry<KTo, VTo>> entrySet() {
|
||||
return new TransformingSet<>(this.delegate.entrySet(), entry -> {
|
||||
return new AbstractMap.SimpleImmutableEntry<>(keyFwd(entry.getKey()), valueFwd(entry.getValue()));
|
||||
}, entry -> {
|
||||
return new AbstractMap.SimpleImmutableEntry<>(keyBack(entry.getKey()), valueBack(entry.getValue()));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public BiMap<VTo, KTo> inverse() {
|
||||
return new TransformingBiMap<>(this.delegate.inverse(), this.valueFwd, this.valueBack, this.keyFwd, this.keyBack);
|
||||
}
|
||||
|
||||
static class TransformingSet<TypeFrom, TypeTo> implements Set<TypeTo> {
|
||||
private final Set<TypeFrom> delegate;
|
||||
private final Function<TypeFrom, TypeTo> forward;
|
||||
private final Function<TypeTo, TypeFrom> reverse;
|
||||
|
||||
public TransformingSet(Set<TypeFrom> set, Function<TypeFrom, TypeTo> forward, Function<TypeTo, TypeFrom> reverse) {
|
||||
this.delegate = set;
|
||||
this.forward = forward;
|
||||
this.reverse = reverse;
|
||||
}
|
||||
|
||||
private TypeTo forward(TypeFrom t) {
|
||||
return t == null ? null : this.forward.apply(t);
|
||||
}
|
||||
|
||||
private TypeFrom reverse(TypeTo t) {
|
||||
return t == null ? null : this.reverse.apply(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.delegate.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.delegate.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return this.delegate.contains(reverse((TypeTo)o));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<TypeTo> iterator() {
|
||||
return Iterators.transform(this.delegate.iterator(), this::forward);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
Object[] array = this.delegate.toArray();
|
||||
for(int i = 0; i < array.length; i++) {
|
||||
array[i] = this.forward((TypeFrom)array[i]);
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> T[] toArray(@NotNull T[] ts) {
|
||||
if(ts.length >= this.delegate.size()) {
|
||||
Object[] setContents = toArray();
|
||||
System.arraycopy(setContents, 0, ts, 0, Math.min(setContents.length, ts.length));
|
||||
if(ts.length > setContents.length)
|
||||
ts[setContents.length] = null;
|
||||
return ts;
|
||||
} else {
|
||||
T[] realArray = Arrays.copyOf(ts, this.delegate.size());
|
||||
Iterator<TypeTo> iterator = this.iterator();
|
||||
int i = 0;
|
||||
while(iterator.hasNext())
|
||||
realArray[i++] = (T)iterator.next();
|
||||
return realArray;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(TypeTo typeFrom) {
|
||||
return this.delegate.add(reverse(typeFrom));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return this.delegate.remove(reverse((TypeTo)o));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(@NotNull Collection<?> collection) {
|
||||
return this.delegate.containsAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(@NotNull Collection<? extends TypeTo> collection) {
|
||||
return this.delegate.addAll(Collections2.transform(collection, this::reverse));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(@NotNull Collection<?> collection) {
|
||||
return this.delegate.retainAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(@NotNull Collection<?> collection) {
|
||||
return this.delegate.removeAll(Collections2.transform(collection, obj -> reverse((TypeTo)obj)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.delegate.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.embeddedt.modernfix.fabric.api.dynresources;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class ModelScanController {
|
||||
public static final List<Predicate<ResourceLocation>> SCAN_PREDICATES = new ArrayList<>();
|
||||
public static boolean shouldScanAndTestWrapping(ResourceLocation location) {
|
||||
if(SCAN_PREDICATES.size() > 0) {
|
||||
for(Predicate<ResourceLocation> predicate : SCAN_PREDICATES) {
|
||||
if(!predicate.test(location))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package org.embeddedt.modernfix.fabric.mixin.perf.blast_search_trees;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.searchtree.SearchRegistry;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.world.item.CreativeModeTab;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||
import org.embeddedt.modernfix.searchtree.DummySearchTree;
|
||||
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.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Minecraft.class)
|
||||
@ClientOnlyMixin
|
||||
public class MinecraftMixin {
|
||||
@Shadow @Final private SearchRegistry searchRegistry;
|
||||
|
||||
@Inject(method = "createSearchTrees", at = @At("HEAD"), cancellable = true)
|
||||
private void replaceSearchTrees(CallbackInfo ci) {
|
||||
ci.cancel();
|
||||
ModernFix.LOGGER.warn("Disabling creative search");
|
||||
NonNullList<ItemStack> stacks = NonNullList.create();
|
||||
for(Item item : Registry.ITEM) {
|
||||
stacks.clear();
|
||||
item.fillItemCategory(CreativeModeTab.TAB_SEARCH, stacks);
|
||||
}
|
||||
this.searchRegistry.register(SearchRegistry.CREATIVE_NAMES, new DummySearchTree<>());
|
||||
this.searchRegistry.register(SearchRegistry.CREATIVE_TAGS, new DummySearchTree<>());
|
||||
this.searchRegistry.register(SearchRegistry.RECIPE_COLLECTIONS, new DummySearchTree<>());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -38,6 +38,7 @@ import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration;
|
|||
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
|
||||
import org.embeddedt.modernfix.dynamicresources.DynamicBakedModelProvider;
|
||||
import org.embeddedt.modernfix.dynamicresources.ModelBakeryHelpers;
|
||||
import org.embeddedt.modernfix.fabric.api.dynresources.ModelScanController;
|
||||
import org.embeddedt.modernfix.fabric.bridge.ModelV0Bridge;
|
||||
import org.embeddedt.modernfix.util.LayeredForwardingMap;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
|
@ -181,6 +182,13 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
|
|||
|
||||
private boolean forceLoadModel = false;
|
||||
|
||||
@Inject(method = "loadTopLevel", at = @At("HEAD"), cancellable = true)
|
||||
private void ignoreRejectedModel(ModelResourceLocation location, CallbackInfo ci) {
|
||||
if(this.inTextureGatheringPass && !this.forceLoadModel && !ModelScanController.shouldScanAndTestWrapping(location)) {
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "loadModel", at = @At(value = "HEAD"), cancellable = true)
|
||||
private void ignoreNonFabricModel(ResourceLocation modelLocation, CallbackInfo ci) throws Exception {
|
||||
if(this.inTextureGatheringPass && !this.forceLoadModel && !this.injectedModels.contains(modelLocation)) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,14 @@ apply plugin: "dev.architectury.loom"
|
|||
|
||||
loom {
|
||||
accessWidenerPath = project(":common").loom.accessWidenerPath
|
||||
runs {
|
||||
client {
|
||||
vmArgs "-Xmx8G"
|
||||
property("modernfix.config.mixin.perf.blast_search_trees", "true")
|
||||
property("modernfix.config.mixin.perf.dynamic_resources", "true")
|
||||
property("modernfix.config.mixin.perf.dynamic_block_codecs", "true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
|
@ -18,6 +26,8 @@ dependencies {
|
|||
modImplementation(fabricApi.module("fabric-models-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||
modImplementation(fabricApi.module("fabric-registry-sync-v0", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||
modImplementation(fabricApi.module("fabric-renderer-api-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||
modImplementation(fabricApi.module("fabric-rendering-data-attachment-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||
modImplementation(fabricApi.module("fabric-rendering-fluids-v1", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||
modRuntimeOnly(fabricApi.module("fabric-renderer-indigo", rootProject.fabric_api_version)) { exclude group: 'net.fabricmc', module: 'fabric-loader' }
|
||||
|
||||
implementation project(path: ":common", configuration: "namedElements")
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ public class TestMod implements ModInitializer {
|
|||
public static final String ID = "mfix_testmod";
|
||||
public static final Logger LOGGER = LogManager.getLogger("ModernFix TestMod");
|
||||
|
||||
public static final int NUM_COLORS = 100;
|
||||
public static final int NUM_COLORS = 32;
|
||||
public static final int MAX_COLOR = NUM_COLORS - 1;
|
||||
|
||||
public static final List<BlockState> WOOL_STATES = new ArrayList<>();
|
||||
|
|
@ -34,7 +34,7 @@ public class TestMod implements ModInitializer {
|
|||
ResourceLocation name = new ResourceLocation(ID, "wool_" + r + "_" + g + "_" + b);
|
||||
TestBlock block = Registry.register(Registry.BLOCK, name, new TestBlock());
|
||||
WOOL_STATES.add(block.defaultBlockState());
|
||||
Registry.register(Registry.ITEM, name, new TestBlockItem(block));
|
||||
//Registry.register(Registry.ITEM, name, new TestBlockItem(block));
|
||||
numRegistered++;
|
||||
if((numRegistered % progressReport) == 0) {
|
||||
LOGGER.info(String.format("Registering... %.02f%%", ((float)numRegistered)/totalToRegister * 100));
|
||||
|
|
@ -49,11 +49,14 @@ public class TestMod implements ModInitializer {
|
|||
private static final BlockState AIR = Blocks.AIR.defaultBlockState();
|
||||
|
||||
public static BlockState getColorCubeStateFor(int chunkX, int chunkY, int chunkZ) {
|
||||
BlockState blockState = AIR;
|
||||
if (chunkX >= 0 && chunkY >= 0 && chunkZ >= 0 && chunkX % 2 == 0 && chunkY % 2 == 0 && chunkZ % 2 == 0) {
|
||||
BlockState blockState = null;
|
||||
if (chunkX >= 0 && chunkY >= 0 && chunkZ >= 0) { // && chunkX % 2 == 0 && chunkY % 2 == 0 && chunkZ % 2 == 0) {
|
||||
/*
|
||||
chunkX /= 2;
|
||||
chunkY /= 2;
|
||||
chunkZ /= 2;
|
||||
|
||||
*/
|
||||
if(chunkX <= TestMod.MAX_COLOR && chunkY <= TestMod.MAX_COLOR && chunkZ <= TestMod.MAX_COLOR) {
|
||||
blockState = TestMod.WOOL_STATES.get((chunkX * TestMod.NUM_COLORS * TestMod.NUM_COLORS) + (chunkY * TestMod.NUM_COLORS) + chunkZ);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package org.embeddedt.modernfix.testmod.client;
|
|||
|
||||
import net.fabricmc.api.ClientModInitializer;
|
||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import org.embeddedt.modernfix.fabric.api.dynresources.ModelScanController;
|
||||
import org.embeddedt.modernfix.testmod.TestMod;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
|
|
@ -12,6 +12,7 @@ public class TestModClient implements ClientModInitializer {
|
|||
private static final Pattern RGB_PATTERN = Pattern.compile("^wool_([0-9]+)_([0-9]+)_([0-9]+)$");
|
||||
@Override
|
||||
public void onInitializeClient() {
|
||||
ModelScanController.SCAN_PREDICATES.add(rl -> !rl.getNamespace().equals(TestMod.ID));
|
||||
ModelLoadingRegistry.INSTANCE.registerVariantProvider(resourceManager -> (modelId, context) -> {
|
||||
if(modelId.getNamespace().equals(TestMod.ID)) {
|
||||
Matcher matcher = RGB_PATTERN.matcher(modelId.getPath());
|
||||
|
|
@ -24,7 +25,5 @@ public class TestModClient implements ClientModInitializer {
|
|||
}
|
||||
return null;
|
||||
});
|
||||
// needed to make debug level rendering work correctly
|
||||
Minecraft.getInstance().smartCull = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,21 @@
|
|||
package org.embeddedt.modernfix.testmod.mixin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.embeddedt.modernfix.testmod.TestMod;
|
||||
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.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(LevelChunk.class)
|
||||
public class ChunkMixin {
|
||||
@Shadow @Final private Level level;
|
||||
|
||||
@Inject(method = "getBlockState", at = @At("HEAD"), cancellable = true)
|
||||
private void redirectDebugWorld(BlockPos pos, CallbackInfoReturnable<BlockState> cir) {
|
||||
if(this.level.isDebug()) {
|
||||
cir.setReturnValue(TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ()));
|
||||
BlockState overrideState = TestMod.getColorCubeStateFor(pos.getX(), pos.getY(), pos.getZ());
|
||||
if(overrideState != null) {
|
||||
cir.setReturnValue(overrideState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,24 +1,31 @@
|
|||
package org.embeddedt.modernfix.testmod.mixin;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.HolderSet;
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.StructureFeatureManager;
|
||||
import net.minecraft.world.level.WorldGenLevel;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.world.level.levelgen.DebugLevelSource;
|
||||
import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.FlatLevelSource;
|
||||
import net.minecraft.world.level.levelgen.structure.StructureSet;
|
||||
import org.embeddedt.modernfix.testmod.TestMod;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(DebugLevelSource.class)
|
||||
public class DebugLevelSourceMixin {
|
||||
@Inject(method = "applyBiomeDecoration", at = @At("HEAD"), cancellable = true)
|
||||
private void showColorCube(WorldGenLevel level, ChunkAccess chunk, StructureFeatureManager structureFeatureManager, CallbackInfo ci) {
|
||||
ci.cancel();
|
||||
import java.util.Optional;
|
||||
|
||||
@Mixin(FlatLevelSource.class)
|
||||
public abstract class DebugLevelSourceMixin extends ChunkGenerator {
|
||||
public DebugLevelSourceMixin(Registry<StructureSet> registry, Optional<HolderSet<StructureSet>> optional, BiomeSource biomeSource) {
|
||||
super(registry, optional, biomeSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyBiomeDecoration(WorldGenLevel level, ChunkAccess chunk, StructureFeatureManager structureFeatureManager) {
|
||||
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||
ChunkPos chunkPos = chunk.getPos();
|
||||
int i = chunkPos.x;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,22 @@ configurations {
|
|||
runtimeClasspath.extendsFrom common
|
||||
}
|
||||
|
||||
def extraModsDir = "extra-mods"
|
||||
|
||||
repositories {
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
flatDir {
|
||||
name "extra-mods"
|
||||
dir file(extraModsDir)
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup "extra-mods"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
forge "net.minecraftforge:forge:${rootProject.forge_version}"
|
||||
// Remove the next line if you don't want to depend on the API
|
||||
|
|
@ -46,6 +62,16 @@ dependencies {
|
|||
|
||||
modCompileOnly("curse.maven:blueprint-382216:3991478")
|
||||
|
||||
// runtime remapping at home
|
||||
for (extraModJar in fileTree(dir: extraModsDir, include: '*.jar')) {
|
||||
def basename = extraModJar.name.substring(0, extraModJar.name.length() - ".jar".length())
|
||||
def versionSep = basename.lastIndexOf('-')
|
||||
assert versionSep != -1
|
||||
def artifactId = basename.substring(0, versionSep)
|
||||
def version = basename.substring(versionSep + 1)
|
||||
modRuntimeOnly("extra-mods:$artifactId:$version")
|
||||
}
|
||||
|
||||
common(project(path: ":common", configuration: "namedElements")) { transitive false }
|
||||
shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false }
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user