package net.minecraft.core; import com.mojang.datafixers.DataFixUtils; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.Keyable; import com.mojang.serialization.Lifecycle; import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.Map.Entry; import java.util.stream.Stream; import java.util.stream.StreamSupport; import net.minecraft.core.Holder.Reference; import net.minecraft.core.HolderLookup.RegistryLookup; import net.minecraft.core.HolderSet.Named; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.tags.TagLoader.LoadResult; import net.minecraft.util.ExtraCodecs; import net.minecraft.util.RandomSource; import org.jetbrains.annotations.Nullable; public interface Registry extends Keyable, RegistryLookup, IdMap { @Override ResourceKey> key(); default Codec byNameCodec() { return this.referenceHolderWithLifecycle().flatComapMap(Reference::value, object -> this.safeCastToReference(this.wrapAsHolder((T)object))); } default Codec> holderByNameCodec() { return this.referenceHolderWithLifecycle().flatComapMap(reference -> reference, this::safeCastToReference); } private Codec> referenceHolderWithLifecycle() { Codec> codec = ResourceLocation.CODEC .comapFlatMap( resourceLocation -> (DataResult)this.get(resourceLocation) .map(DataResult::success) .orElseGet(() -> DataResult.error(() -> "Unknown registry key in " + this.key() + ": " + resourceLocation)), reference -> reference.key().location() ); return ExtraCodecs.overrideLifecycle( codec, reference -> (Lifecycle)this.registrationInfo(reference.key()).map(RegistrationInfo::lifecycle).orElse(Lifecycle.experimental()) ); } private DataResult> safeCastToReference(Holder value) { return value instanceof Reference reference ? DataResult.success(reference) : DataResult.error(() -> "Unregistered holder in " + this.key() + ": " + value); } @Override default Stream keys(DynamicOps dynamicOps) { return this.keySet().stream().map(resourceLocation -> dynamicOps.createString(resourceLocation.toString())); } /** * @return the name used to identify the given object within this registry or {@code null} if the object is not within this registry */ @Nullable ResourceLocation getKey(T value); Optional> getResourceKey(T value); @Override int getId(@Nullable T value); @Nullable T getValue(@Nullable ResourceKey key); @Nullable T getValue(@Nullable ResourceLocation key); Optional registrationInfo(ResourceKey key); default Optional getOptional(@Nullable ResourceLocation name) { return Optional.ofNullable(this.getValue(name)); } default Optional getOptional(@Nullable ResourceKey registryKey) { return Optional.ofNullable(this.getValue(registryKey)); } Optional> getAny(); default T getValueOrThrow(ResourceKey key) { T object = this.getValue(key); if (object == null) { throw new IllegalStateException("Missing key in " + this.key() + ": " + key); } else { return object; } } /** * @return all keys in this registry */ Set keySet(); Set, T>> entrySet(); Set> registryKeySet(); Optional> getRandom(RandomSource random); default Stream stream() { return StreamSupport.stream(this.spliterator(), false); } boolean containsKey(ResourceLocation name); boolean containsKey(ResourceKey key); static T register(Registry registry, String name, T value) { return register(registry, ResourceLocation.parse(name), value); } static T register(Registry registry, ResourceLocation name, T value) { return register(registry, ResourceKey.create(registry.key(), name), value); } static T register(Registry registry, ResourceKey key, T value) { ((WritableRegistry)registry).register(key, (V)value, RegistrationInfo.BUILT_IN); return value; } static Reference registerForHolder(Registry registry, ResourceKey key, T value) { return ((WritableRegistry)registry).register(key, value, RegistrationInfo.BUILT_IN); } static Reference registerForHolder(Registry registry, ResourceLocation name, T value) { return registerForHolder(registry, ResourceKey.create(registry.key(), name), value); } Registry freeze(); Reference createIntrusiveHolder(T value); Optional> get(int index); Optional> get(ResourceLocation key); Holder wrapAsHolder(T value); default Iterable> getTagOrEmpty(TagKey key) { return DataFixUtils.orElse(this.get(key), List.of()); } default Optional> getRandomElementOf(TagKey key, RandomSource random) { return this.get(key).flatMap(named -> named.getRandomElement(random)); } Stream> getTags(); default IdMap> asHolderIdMap() { return new IdMap>() { public int getId(Holder holder) { return Registry.this.getId(holder.value()); } @Nullable public Holder byId(int i) { return (Holder)Registry.this.get(i).orElse(null); } @Override public int size() { return Registry.this.size(); } public Iterator> iterator() { return Registry.this.listElements().map(reference -> reference).iterator(); } }; } Registry.PendingTags prepareTagReload(LoadResult loadResult); public interface PendingTags { ResourceKey> key(); RegistryLookup lookup(); void apply(); int size(); } }