package net.minecraft.core; import com.google.common.collect.ImmutableMap; import com.mojang.logging.LogUtils; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Map.Entry; import java.util.stream.Collectors; import java.util.stream.Stream; import net.minecraft.resources.ResourceKey; import org.slf4j.Logger; public interface RegistryAccess extends HolderLookup.Provider { Logger LOGGER = LogUtils.getLogger(); RegistryAccess.Frozen EMPTY = new RegistryAccess.ImmutableRegistryAccess(Map.of()).freeze(); @Override Optional> lookup(final ResourceKey> registryKey); default Registry lookupOrThrow(final ResourceKey> name) { return this.lookup(name).orElseThrow(() -> new IllegalStateException("Missing registry: " + name)); } Stream> registries(); @Override default Stream>> listRegistryKeys() { return this.registries().map(e -> e.key); } static RegistryAccess.Frozen fromRegistryOfRegistries(final Registry> registries) { return new RegistryAccess.Frozen() { @Override public Optional> lookup(final ResourceKey> registryKey) { Registry> registry = (Registry>)registries; return registry.getOptional((ResourceKey>)registryKey); } @Override public Stream> registries() { return registries.entrySet().stream().map(RegistryAccess.RegistryEntry::fromMapEntry); } @Override public RegistryAccess.Frozen freeze() { return this; } }; } default RegistryAccess.Frozen freeze() { class FrozenAccess extends RegistryAccess.ImmutableRegistryAccess implements RegistryAccess.Frozen { protected FrozenAccess(final Stream> entries) { super(entries); } } return new FrozenAccess(this.registries().map(RegistryAccess.RegistryEntry::freeze)); } interface Frozen extends RegistryAccess { } class ImmutableRegistryAccess implements RegistryAccess { private final Map>, ? extends Registry> registries; public ImmutableRegistryAccess(final List> registries) { this.registries = registries.stream().collect(Collectors.toUnmodifiableMap(Registry::key, v -> v)); } public ImmutableRegistryAccess(final Map>, ? extends Registry> registries) { this.registries = Map.copyOf(registries); } public ImmutableRegistryAccess(final Stream> entries) { this.registries = entries.collect(ImmutableMap.toImmutableMap(RegistryAccess.RegistryEntry::key, RegistryAccess.RegistryEntry::value)); } @Override public Optional> lookup(final ResourceKey> registryKey) { return Optional.ofNullable(this.registries.get(registryKey)).map(r -> (Registry)r); } @Override public Stream> registries() { return this.registries.entrySet().stream().map(RegistryAccess.RegistryEntry::fromMapEntry); } } record RegistryEntry(ResourceKey> key, Registry value) { private static > RegistryAccess.RegistryEntry fromMapEntry( final Entry>, R> e ) { return fromUntyped((ResourceKey>)e.getKey(), e.getValue()); } private static RegistryAccess.RegistryEntry fromUntyped(final ResourceKey> key, final Registry value) { return new RegistryAccess.RegistryEntry<>((ResourceKey>)key, (Registry)value); } private RegistryAccess.RegistryEntry freeze() { return new RegistryAccess.RegistryEntry<>(this.key, this.value.freeze()); } } }