package net.minecraft.core; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.Lifecycle; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; import net.minecraft.world.flag.FeatureElement; import net.minecraft.world.flag.FeatureFlagSet; public interface HolderLookup extends HolderGetter { Stream> listElements(); default Stream> listElementIds() { return this.listElements().map(Holder.Reference::key); } Stream> listTags(); default Stream> listTagIds() { return this.listTags().map(HolderSet.Named::key); } public interface Provider extends HolderGetter.Provider { Stream>> listRegistryKeys(); default Stream> listRegistries() { return this.listRegistryKeys().map(this::lookupOrThrow); } @Override Optional> lookup(final ResourceKey> key); default HolderLookup.RegistryLookup lookupOrThrow(final ResourceKey> key) { return (HolderLookup.RegistryLookup)this.lookup(key).orElseThrow(() -> new IllegalStateException("Registry " + key.identifier() + " not found")); } default RegistryOps createSerializationContext(final DynamicOps parent) { return RegistryOps.create(parent, this); } static HolderLookup.Provider create(final Stream> lookups) { final Map>, HolderLookup.RegistryLookup> map = (Map>, HolderLookup.RegistryLookup>)lookups.collect( Collectors.toUnmodifiableMap(HolderLookup.RegistryLookup::key, e -> e) ); return new HolderLookup.Provider() { @Override public Stream>> listRegistryKeys() { return map.keySet().stream(); } @Override public Optional> lookup(final ResourceKey> key) { return Optional.ofNullable((HolderLookup.RegistryLookup)map.get(key)); } }; } default Lifecycle allRegistriesLifecycle() { return (Lifecycle)this.listRegistries().map(HolderLookup.RegistryLookup::registryLifecycle).reduce(Lifecycle.stable(), Lifecycle::add); } } public interface RegistryLookup extends HolderLookup, HolderOwner { ResourceKey> key(); Lifecycle registryLifecycle(); default HolderLookup.RegistryLookup filterFeatures(final FeatureFlagSet enabledFeatures) { return FeatureElement.FILTERED_REGISTRIES.contains(this.key()) ? this.filterElements(t -> ((FeatureElement)t).isEnabled(enabledFeatures)) : this; } default HolderLookup.RegistryLookup filterElements(final Predicate filter) { return new HolderLookup.RegistryLookup.Delegate() { { Objects.requireNonNull(RegistryLookup.this); } @Override public HolderLookup.RegistryLookup parent() { return RegistryLookup.this; } @Override public Optional> get(final ResourceKey id) { return this.parent().get(id).filter(holder -> filter.test(holder.value())); } @Override public Stream> listElements() { return this.parent().listElements().filter(e -> filter.test(e.value())); } }; } public interface Delegate extends HolderLookup.RegistryLookup { HolderLookup.RegistryLookup parent(); @Override default ResourceKey> key() { return this.parent().key(); } @Override default Lifecycle registryLifecycle() { return this.parent().registryLifecycle(); } @Override default Optional> get(final ResourceKey id) { return this.parent().get(id); } @Override default Stream> listElements() { return this.parent().listElements(); } @Override default Optional> get(final TagKey id) { return this.parent().get(id); } @Override default Stream> listTags() { return this.parent().listTags(); } } } }