Provide emulated registries permanently

This commit is contained in:
embeddedt 2024-12-24 15:14:41 -05:00
parent 46913ac8b2
commit 9ed71dcdb4
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
2 changed files with 44 additions and 47 deletions

View File

@ -25,8 +25,10 @@ import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Unique;
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.ModifyArg; import org.spongepowered.asm.mixin.injection.ModifyArg;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Map; import java.util.Map;
@ -36,7 +38,10 @@ import java.util.concurrent.Executor;
@Mixin(ModelManager.class) @Mixin(ModelManager.class)
@ClientOnlyMixin @ClientOnlyMixin
public class ModelManagerMixin implements DynamicModelProvider.ModelManagerExtension { public class ModelManagerMixin implements DynamicModelProvider.ModelManagerExtension {
@Shadow private BakedModel missingModel; @Shadow private Map<ModelResourceLocation, BakedModel> bakedBlockStateModels;
@Shadow private Map<ResourceLocation, ItemModel> bakedItemStackModels;
@Shadow private Map<ResourceLocation, ClientItem.Properties> itemProperties;
@Unique @Unique
private DynamicModelProvider mfix$modelProvider; private DynamicModelProvider mfix$modelProvider;
@ -79,35 +84,11 @@ public class ModelManagerMixin implements DynamicModelProvider.ModelManagerExten
return ArrayUtils.add(cfs, makeModelProviderFuture); return ArrayUtils.add(cfs, makeModelProviderFuture);
} }
/** @Inject(method = "apply", at = @At("RETURN"))
* @author embeddedt private void setModelRegistries(CallbackInfo ci) {
* @reason use dynamic model system this.bakedBlockStateModels = this.mfix$modelProvider.getTopLevelEmulatedRegistry();
*/ this.bakedItemStackModels = this.mfix$modelProvider.getItemModelEmulatedRegistry();
@Overwrite this.itemProperties = this.mfix$modelProvider.getItemPropertiesEmulatedRegistry();
public BakedModel getModel(ModelResourceLocation modelLocation) {
if(this.mfix$modelProvider != null) {
return this.mfix$modelProvider.getModel(modelLocation);
} else {
return this.missingModel;
}
}
/**
* @author embeddedt
* @reason use dynamic model system
*/
@Overwrite
public ItemModel getItemModel(ResourceLocation resourceLocation) {
return this.mfix$modelProvider.getItemModel(resourceLocation);
}
/**
* @author embeddedt
* @reason use dynamic model system
*/
@Overwrite
public ClientItem.Properties getItemProperties(ResourceLocation resourceLocation) {
return this.mfix$modelProvider.getClientItemProperties(resourceLocation);
} }
@Override @Override

View File

@ -1,8 +1,10 @@
package org.embeddedt.modernfix.dynamicresources; package org.embeddedt.modernfix.dynamicresources;
import com.google.common.base.Suppliers;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.Collections2;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@ -61,6 +63,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -149,28 +152,32 @@ public class DynamicModelProvider {
return this.missingItemModel; return this.missingItemModel;
} }
public Map<ModelResourceLocation, BakedModel> getTopLevelEmulatedRegistry() { private static final Supplier<Set<ModelResourceLocation>> TOP_LEVEL_LOCATIONS_SUPPLIER = Suppliers.memoizeWithExpiration(() -> {
Set<ModelResourceLocation> topLevelModelLocations = new HashSet<>(); Set<ModelResourceLocation> set = new HashSet<>();
// Skip going through ModelLocationCache because most of the accesses will be misses // Skip going through ModelLocationCache because most of the accesses will be misses
BuiltInRegistries.BLOCK.entrySet().forEach(entry -> { BuiltInRegistries.BLOCK.entrySet().forEach(entry -> {
var location = entry.getKey().location(); var location = entry.getKey().location();
for(BlockState state : entry.getValue().getStateDefinition().getPossibleStates()) { for(BlockState state : entry.getValue().getStateDefinition().getPossibleStates()) {
topLevelModelLocations.add(BlockModelShaper.stateToModelLocation(location, state)); set.add(BlockModelShaper.stateToModelLocation(location, state));
} }
}); });
return new EmulatedRegistry<>(ModelResourceLocation.class, this.loadedBakedModels, topLevelModelLocations, this.mrlModelOverrides); return Collections.unmodifiableSet(set);
}, 2, TimeUnit.MINUTES);
public Map<ModelResourceLocation, BakedModel> getTopLevelEmulatedRegistry() {
return new EmulatedRegistry<>(ModelResourceLocation.class, this.loadedBakedModels, TOP_LEVEL_LOCATIONS_SUPPLIER, this.mrlModelOverrides);
} }
public Map<ResourceLocation, BakedModel> getStandaloneEmulatedRegistry() { public Map<ResourceLocation, BakedModel> getStandaloneEmulatedRegistry() {
return new EmulatedRegistry<>(ResourceLocation.class, this.loadedStandaloneModels, Set.of(), this.standaloneModelOverrides); return new EmulatedRegistry<>(ResourceLocation.class, this.loadedStandaloneModels, Set::of, this.standaloneModelOverrides);
} }
public Map<ResourceLocation, ItemModel> getItemModelEmulatedRegistry() { public Map<ResourceLocation, ItemModel> getItemModelEmulatedRegistry() {
return new EmulatedRegistry<>(ResourceLocation.class, this.loadedItemModels, BuiltInRegistries.ITEM.keySet(), this.itemStackModelOverrides); return new EmulatedRegistry<>(ResourceLocation.class, this.loadedItemModels, BuiltInRegistries.ITEM::keySet, this.itemStackModelOverrides);
} }
public Map<ResourceLocation, ClientItem.Properties> getItemPropertiesEmulatedRegistry() { public Map<ResourceLocation, ClientItem.Properties> getItemPropertiesEmulatedRegistry() {
return Maps.transformValues(new EmulatedRegistry<>(ResourceLocation.class, this.loadedClientItemProperties, BuiltInRegistries.ITEM.keySet(), Map.of()), ClientItem::properties); return Maps.transformValues(new EmulatedRegistry<>(ResourceLocation.class, this.loadedClientItemProperties, BuiltInRegistries.ITEM::keySet, Map.of()), ClientItem::properties);
} }
private <K, V> LoadingCache<K, Optional<V>> makeLoadingCache(Function<K, Optional<V>> loadingFunction) { private <K, V> LoadingCache<K, Optional<V>> makeLoadingCache(Function<K, Optional<V>> loadingFunction) {
@ -189,14 +196,14 @@ public class DynamicModelProvider {
private static class EmulatedRegistry<K, V> implements Map<K, V> { private static class EmulatedRegistry<K, V> implements Map<K, V> {
private final LoadingCache<K, Optional<V>> realCache; private final LoadingCache<K, Optional<V>> realCache;
private final Set<K> keys; private final Supplier<Set<K>> keys;
private final Map<K, V> overrides; private final Map<K, V> overrides;
private final Class<K> keyClass; private final Class<K> keyClass;
public EmulatedRegistry(Class<K> keyClass, LoadingCache<K, Optional<V>> realCache, Set<K> keys, Map<K, V> overrides) { public EmulatedRegistry(Class<K> keyClass, LoadingCache<K, Optional<V>> realCache, Supplier<Set<K>> keys, Map<K, V> overrides) {
this.keyClass = keyClass; this.keyClass = keyClass;
this.realCache = realCache; this.realCache = realCache;
this.keys = Collections.unmodifiableSet(keys); this.keys = keys;
this.overrides = overrides; this.overrides = overrides;
} }
@ -209,6 +216,15 @@ public class DynamicModelProvider {
} }
} }
@Override
public V getOrDefault(Object key, V defaultValue) {
if (this.keyClass.isAssignableFrom(key.getClass())) {
return this.realCache.getUnchecked((K)key).orElse(defaultValue);
} else {
return defaultValue;
}
}
@Override @Override
public V put(K key, V value) { public V put(K key, V value) {
V oldValue = this.realCache.getUnchecked(key).orElse(null); V oldValue = this.realCache.getUnchecked(key).orElse(null);
@ -237,17 +253,17 @@ public class DynamicModelProvider {
@Override @Override
public @NotNull Set<K> keySet() { public @NotNull Set<K> keySet() {
return keys; return keys.get();
} }
@Override @Override
public @NotNull Collection<V> values() { public @NotNull Collection<V> values() {
return List.of(); return Collections2.transform(this.realCache.asMap().values(), v -> v.orElse(null));
} }
@Override @Override
public int size() { public int size() {
return keys.size(); return keys.get().size();
} }
@Override @Override
@ -257,7 +273,7 @@ public class DynamicModelProvider {
@Override @Override
public boolean containsKey(Object key) { public boolean containsKey(Object key) {
return keys.contains(key); return keys.get().contains(key);
} }
@Override @Override
@ -270,7 +286,7 @@ public class DynamicModelProvider {
return new AbstractSet<>() { return new AbstractSet<>() {
@Override @Override
public Iterator<Entry<K, V>> iterator() { public Iterator<Entry<K, V>> iterator() {
return Iterators.transform(keys.iterator(), key -> new Entry<>() { return Iterators.transform(keys.get().iterator(), key -> new Entry<>() {
@Override @Override
public K getKey() { public K getKey() {
return key; return key;
@ -290,14 +306,14 @@ public class DynamicModelProvider {
@Override @Override
public int size() { public int size() {
return keys.size(); return keys.get().size();
} }
}; };
} }
@Override @Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
for(K location : keys) { for(K location : keys.get()) {
/* /*
* Fetching every model is insanely slow. So we call the function with a null object first, since it * Fetching every model is insanely slow. So we call the function with a null object first, since it
* probably isn't expecting that. If we get an exception thrown, or it returns nonnull, then we know * probably isn't expecting that. If we get an exception thrown, or it returns nonnull, then we know