Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[21.2] Add more specialized DeferredRegister types #1516

Draft
wants to merge 11 commits into
base: 1.21.x
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

+ /**
+ * Forge: Use this in conjunction with a
+ * {@link net.neoforged.neoforge.registries.DeferredRegister#register(String, java.util.function.Supplier) DeferredRegister#register(String, Supplier)}
+ * {@link net.neoforged.neoforge.registries.deferred.DeferredRegister#register(String, java.util.function.Supplier) DeferredRegister#register(String, Supplier)}
+ * call to both populate the {@code BY_CLASS} map and register the argument type info so it can be used in commands.
+ *
+ * @param infoClass the class type of the argument type info
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/net/neoforged/neoforge/common/NeoForgeMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;
import net.neoforged.neoforge.network.DualStackUtils;
import net.neoforged.neoforge.registries.DataPackRegistryEvent;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.NeoForgeRegistries;
import net.neoforged.neoforge.registries.NeoForgeRegistriesSetup;
import net.neoforged.neoforge.registries.RegisterEvent;
import net.neoforged.neoforge.registries.datamaps.builtin.NeoForgeDataMaps;
import net.neoforged.neoforge.registries.deferred.DeferredHolder;
import net.neoforged.neoforge.registries.deferred.DeferredRegister;
import net.neoforged.neoforge.registries.holdersets.AndHolderSet;
import net.neoforged.neoforge.registries.holdersets.AnyHolderSet;
import net.neoforged.neoforge.registries.holdersets.HolderSetType;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import net.minecraft.sounds.SoundEvent;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.SoundType;
import net.neoforged.neoforge.registries.DeferredHolder;
import net.neoforged.neoforge.registries.DeferredRegister;
import net.neoforged.neoforge.registries.deferred.DeferredHolder;
import net.neoforged.neoforge.registries.deferred.DeferredRegister;

/**
* A subclass of {@link SoundType} that uses {@link Supplier<SoundEvent>}s.
Expand Down
636 changes: 0 additions & 636 deletions src/main/java/net/neoforged/neoforge/registries/DeferredRegister.java

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import net.neoforged.neoforge.fluids.FluidType;
import net.neoforged.neoforge.fluids.crafting.FluidIngredientType;
import net.neoforged.neoforge.internal.versions.neoforge.NeoForgeVersion;
import net.neoforged.neoforge.registries.deferred.DeferredRegister;
import net.neoforged.neoforge.registries.holdersets.HolderSetType;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import net.neoforged.neoforge.registries.callback.BakeCallback;
import net.neoforged.neoforge.registries.callback.ClearCallback;
import net.neoforged.neoforge.registries.callback.RegistryCallback;
import net.neoforged.neoforge.registries.deferred.DeferredRegister;
import org.jetbrains.annotations.Nullable;

public class RegistryBuilder<T> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.registries.deferred;

import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.registries.NeoForgeRegistries;

/**
* Special {@link DeferredHolder} for {@link AttachmentType AttachmentTypes}.
*
* @param <TData> The specific data type.
*/
public class DeferredAttachmentType<TData> extends DeferredHolder<AttachmentType<?>, AttachmentType<TData>> {
protected DeferredAttachmentType(ResourceKey<AttachmentType<?>> key) {
super(key);
}

/**
* Creates a new {@link DeferredHolder} targeting the specified {@link AttachmentType}.
*
* @param <TData> The type of the target {@link AttachmentType}.
* @param registryKey The resource key of the target {@link AttachmentType}.
*/
public static <TData> DeferredAttachmentType<TData> createAttachmentType(ResourceKey<AttachmentType<?>> registryKey) {
return new DeferredAttachmentType<>(registryKey);
}

/**
* Creates a new {@link DeferredHolder} targeting the {@link AttachmentType} with the specified name.
*
* @param <TData> The type of the target {@link AttachmentType}.
* @param registryName The name of the target {@link AttachmentType}.
*/
public static <TData> DeferredAttachmentType<TData> createAttachmentType(ResourceLocation registryName) {
return createAttachmentType(ResourceKey.create(NeoForgeRegistries.Keys.ATTACHMENT_TYPES, registryName));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.registries.deferred;

import java.util.function.Function;
import java.util.function.Supplier;
import java.util.function.UnaryOperator;
import net.minecraft.core.Registry;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.neoforged.neoforge.attachment.AttachmentType;
import net.neoforged.neoforge.attachment.IAttachmentHolder;
import net.neoforged.neoforge.common.util.INBTSerializable;
import net.neoforged.neoforge.registries.NeoForgeRegistries;

/**
* Specialized DeferredRegister for {@link AttachmentType AttachmentTypes} that uses the specialized {@link DeferredAttachmentType} as the return type for {@link #register}.
*/
public class DeferredAttachmentTypes extends DeferredRegister<AttachmentType<?>> {
protected DeferredAttachmentTypes(String namespace) {
super(NeoForgeRegistries.Keys.ATTACHMENT_TYPES, namespace);
}

@Override
protected <TAttachmentType extends AttachmentType<?>> DeferredHolder<AttachmentType<?>, TAttachmentType> createHolder(ResourceKey<? extends Registry<AttachmentType<?>>> registryType, ResourceLocation registryName) {
return (DeferredHolder<AttachmentType<?>, TAttachmentType>) DeferredAttachmentType.createAttachmentType(ResourceKey.create(registryType, registryName));
}

/**
* Adds a new attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @param builderAction Action to be invoked with the builder during registration.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData> DeferredAttachmentType<TData> registerAttachmentType(String identifier, Function<IAttachmentHolder, TData> factory, UnaryOperator<AttachmentType.Builder<TData>> builderAction) {
return (DeferredAttachmentType<TData>) register(identifier, () -> builderAction.apply(AttachmentType.builder(factory)).build());
}

/**
* Adds a new attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData> DeferredAttachmentType<TData> registerAttachmentType(String identifier, Function<IAttachmentHolder, TData> factory) {
return registerAttachmentType(identifier, factory, UnaryOperator.identity());
}

/**
* Adds a new attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @param builderAction Action to be invoked with the builder during registration.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData> DeferredAttachmentType<TData> registerAttachmentType(String identifier, Supplier<TData> factory, UnaryOperator<AttachmentType.Builder<TData>> builderAction) {
return registerAttachmentType(identifier, holder -> factory.get(), builderAction);
}

/**
* Adds a new attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData> DeferredAttachmentType<TData> registerAttachmentType(String identifier, Supplier<TData> factory) {
return registerAttachmentType(identifier, factory, UnaryOperator.identity());
}

/**
* Adds a new serializable attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @param builderAction Action to be invoked with the builder during registration.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData extends INBTSerializable<TTag>, TTag extends Tag> DeferredAttachmentType<TData> registerSerializableAttachmentType(String identifier, Function<IAttachmentHolder, TData> factory, UnaryOperator<AttachmentType.Builder<TData>> builderAction) {
return (DeferredAttachmentType<TData>) register(identifier, () -> builderAction.apply(AttachmentType.serializable(factory)).build());
}

/**
* Adds a new serializable attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData extends INBTSerializable<TTag>, TTag extends Tag> DeferredAttachmentType<TData> registerSerializableAttachmentType(String identifier, Function<IAttachmentHolder, TData> factory) {
return registerSerializableAttachmentType(identifier, factory, UnaryOperator.identity());
}

/**
* Adds a new serializable attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @param builderAction Action to be invoked with the builder during registration.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData extends INBTSerializable<TTag>, TTag extends Tag> DeferredAttachmentType<TData> registerSerializableAttachmentType(String identifier, Supplier<TData> factory, UnaryOperator<AttachmentType.Builder<TData>> builderAction) {
return registerSerializableAttachmentType(identifier, holder -> factory.get(), builderAction);
}

/**
* Adds a new serializable attachment type to the list of entries to be registered and returns a {@link DeferredAttachmentType} that will be populated with the created entry automatically.
*
* @param identifier The new entry's identifier. It will automatically have the {@linkplain #getNamespace() namespace} prefixed.
* @param factory A factory for the new entry. The factory should not cache the created entry.
* @return A {@link DeferredAttachmentType} that will track updates from the registry for this entry.
*/
public <TData extends INBTSerializable<TTag>, TTag extends Tag> DeferredAttachmentType<TData> registerSerializableAttachmentType(String identifier, Supplier<TData> factory) {
return registerSerializableAttachmentType(identifier, factory, UnaryOperator.identity());
}

/**
* Factory for a specialized DeferredRegister for {@link AttachmentType AttachmentTypes}.
*
* @param namespace The namespace for all objects registered to this DeferredRegister
*/
public static DeferredAttachmentTypes createAttachmentTypes(String namespace) {
return new DeferredAttachmentTypes(namespace);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.registries;
package net.neoforged.neoforge.registries.deferred;

import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.registries.deferred;

import java.util.Objects;
import java.util.Optional;
import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import org.jetbrains.annotations.Nullable;

/**
* Special {@link DeferredHolder} for {@link BlockEntityType BlockEntityTypes}.
*
* @param <TBlockEntity> The specific {@link BlockEntityType}.
*/
public class DeferredBlockEntityType<TBlockEntity extends BlockEntity> extends DeferredHolder<BlockEntityType<?>, BlockEntityType<TBlockEntity>> {
protected DeferredBlockEntityType(ResourceKey<BlockEntityType<?>> key) {
super(key);
}

/**
* Returns true if the given {@link BlockState} is valid for this {@link BlockEntityType}.
*
* @param blockState {@link BlockState} to validate.
* @return {@code true} if {@link BlockState} is valid.
*/
public boolean isValid(BlockState blockState) {
return value().isValid(blockState);
}

/**
* Returns true if the given {@link Block} is valid for this {@link BlockEntityType}.
*
* @param block {@link Block} to validate.
* @return {@code true} if {@link Block} is valid.
*/
public boolean isValid(Block block) {
return value().getValidBlocks().contains(block);
}

/**
* Looks up {@link BlockEntity} in world at given position returning if it matches this {@link BlockEntityType}.
*
* @param level The level to lookup the {@link BlockEntity} from.
* @param pos The position to lookup the {@link BlockEntity} at.
* @return {@link BlockEntity} matching this type or null if none exists.
*/
@Nullable
public TBlockEntity get(BlockGetter level, BlockPos pos) {
return value().getBlockEntity(level, pos);
}

/**
* Looks up {@link BlockEntity} in world at given position returning if it matches this {@link BlockEntityType}.
*
* @param level The level to lookup the {@link BlockEntity} from.
* @param pos The position to lookup the {@link BlockEntity} at.
* @return {@link BlockEntity} matching this type.
* @throws NullPointerException if no matching {@link BlockEntity} could be found.
*/
public TBlockEntity getOrThrow(BlockGetter level, BlockPos pos) {
return Objects.requireNonNull(get(level, pos), () -> "Invalid or no BlockEntity as position: " + pos.toShortString());
}

/**
* Looks up {@link BlockEntity} in world at given position returning if it matches this {@link BlockEntityType}.
*
* @param level The level to lookup the {@link BlockEntity} from.
* @param pos The position to lookup the {@link BlockEntity} at.
* @return {@link BlockEntity} matching this type or {@link Optional#empty()} if none exists.
*/
public Optional<TBlockEntity> find(BlockGetter level, BlockPos pos) {
return level.getBlockEntity(pos, value());
}

/**
* Creates a new {@link DeferredHolder} targeting the specified {@link BlockEntityType}.
*
* @param <TBlockEntity> The type of the target {@link BlockEntityType}.
* @param registryKey The resource key of the target {@link BlockEntityType}.
*/
public static <TBlockEntity extends BlockEntity> DeferredBlockEntityType<TBlockEntity> createBlockEntityType(ResourceKey<BlockEntityType<?>> registryKey) {
return new DeferredBlockEntityType<>(registryKey);
}

/**
* Creates a new {@link DeferredHolder} targeting the {@link BlockEntityType} with the specified name.
*
* @param <TBlockEntity> The type of the target {@link BlockEntityType}.
* @param registryName The name of the target {@link BlockEntityType}.
*/
public static <TBlockEntity extends BlockEntity> DeferredBlockEntityType<TBlockEntity> createBlockEntityType(ResourceLocation registryName) {
return createBlockEntityType(ResourceKey.create(Registries.BLOCK_ENTITY_TYPE, registryName));
}
}
Loading
Loading