invalidate everything

This commit is contained in:
TropheusJ 2025-02-15 19:54:44 -05:00
parent 3c9bfef30e
commit 6edf7ec68e
4 changed files with 11 additions and 31 deletions

View file

@ -31,10 +31,11 @@ public interface SimpleRegistry<K, V> {
void registerProvider(Provider<K, V> provider);
/**
* Invalidate the cached values provided by the given provider, so they get re-computed on the next query.
* @throws IllegalArgumentException if the provider is not registered to this registry
* Invalidate the cached values provided by all providers, so they get re-computed on the next query.
* This should be called by providers when something changes that would affect their results, such as
* a resource reload in the case of providers based on tags.
*/
void invalidateProvider(Provider<K, V> provider);
void invalidate();
/**
* Query the value associated with the given object. May be null if no association is present.
@ -48,10 +49,10 @@ public interface SimpleRegistry<K, V> {
/**
* A provider can provide values to the registry in a lazy fashion. When a key does not have an
* associated value, all providers will be queried in reverse-registration order.
* associated value, all providers will be queried in reverse-registration order (newest first).
* <p>
* The values returned by providers are cached so that repeated queries always return the same value.
* To invalidate the cache of a provider, call {@link SimpleRegistry#invalidateProvider(Provider)}.
* To invalidate the cache of a registry, call {@link SimpleRegistry#invalidate()}.
*/
@FunctionalInterface
interface Provider<K, V> {

View file

@ -73,7 +73,7 @@ public class MountedStorageTypeRegistryImpl {
public void onRegister(SimpleRegistry<Block, MountedItemStorageType<?>> registry) {
MinecraftForge.EVENT_BUS.addListener((TagsUpdatedEvent event) -> {
if (event.shouldUpdateStaticData()) {
registry.invalidateProvider(this);
registry.invalidate();
}
});
}

View file

@ -1,12 +1,10 @@
package com.simibubi.create.impl.registry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import org.jetbrains.annotations.Nullable;
@ -18,7 +16,6 @@ public class SimpleRegistryImpl<K, V> implements SimpleRegistry<K, V> {
private final Map<K, V> registrations = new IdentityHashMap<>();
private final List<Provider<K, V>> providers = new ArrayList<>();
private final Map<Provider<K, V>, Set<K>> providedKeys = new IdentityHashMap<>();
private final Map<K, V> providedValues = new IdentityHashMap<>();
@Override
@ -48,20 +45,8 @@ public class SimpleRegistryImpl<K, V> implements SimpleRegistry<K, V> {
}
@Override
public synchronized void invalidateProvider(Provider<K, V> provider) {
Objects.requireNonNull(provider);
if (!this.providers.contains(provider)) {
throw new IllegalArgumentException("Cannot invalidate non-registered provider: " + provider);
}
// discard all the values the provider has provided
Set<K> keys = providedKeys.remove(provider);
if (keys != null) {
keys.forEach(providedValues::remove);
}
// when a provider is invalidated, we need to clear all cached values that evaluated to null, so they can be re-queried
this.providedValues.values().removeIf(value -> value == nullMarker);
public synchronized void invalidate() {
this.providedValues.clear();
}
@Override
@ -75,13 +60,11 @@ public class SimpleRegistryImpl<K, V> implements SimpleRegistry<K, V> {
}
// no value known, check providers
// descendingSet: go in reverse-registration order
// new providers are added to the start, so normal iteration is reverse-registration order
for (Provider<K, V> provider : this.providers) {
V value = provider.get(object);
if (value != null) {
this.providedValues.put(object, value);
// track which provider provided the value for invalidation
this.providedKeys.computeIfAbsent(provider, $ -> identityHashSet()).add(object);
return value;
}
}
@ -95,8 +78,4 @@ public class SimpleRegistryImpl<K, V> implements SimpleRegistry<K, V> {
private static <T> T nullMarker() {
return (T) nullMarker;
}
private static <T> Set<T> identityHashSet() {
return Collections.newSetFromMap(new IdentityHashMap<>());
}
}

View file

@ -34,7 +34,7 @@ public class TagProviderImpl<K, V> implements SimpleRegistry.Provider<K, V> {
public void onRegister(SimpleRegistry<K, V> registry) {
MinecraftForge.EVENT_BUS.addListener((TagsUpdatedEvent event) -> {
if (event.shouldUpdateStaticData()) {
registry.invalidateProvider(this);
registry.invalidate();
}
});
}