mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-26 14:30:17 +01:00
use a RegistryBuilderFactory to standarize creating registry builders
This commit is contained in:
parent
8551cb23b0
commit
c7d0436d2b
4 changed files with 105 additions and 28 deletions
|
@ -0,0 +1,39 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
||||
/**
|
||||
* A factory to create a {@link RegistryBuilder} for a given {@link TypedKey}. For
|
||||
* each instance of this class, once either {@link #empty()} or {@link #copyOf(TypedKey)}
|
||||
* is called once, any future calls to either method will throw an {@link IllegalStateException}.
|
||||
*
|
||||
* @param <T> The type of the registry
|
||||
* @param <B> The type of the registry builder
|
||||
*/
|
||||
@NullMarked
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.NonExtendable
|
||||
public interface RegistryBuilderFactory<T, B extends RegistryBuilder<T>> {
|
||||
|
||||
/**
|
||||
* Creates a new empty {@link RegistryBuilder}.
|
||||
*
|
||||
* @return A new empty {@link RegistryBuilder}
|
||||
* @throws IllegalStateException if this method or {@link #copyOf(TypedKey)}) has already been called once
|
||||
*/
|
||||
@Contract("-> new")
|
||||
B empty();
|
||||
|
||||
/**
|
||||
* Creates a new {@link RegistryBuilder} with the same properties as the given {@link TypedKey}.
|
||||
*
|
||||
* @param key The key to copy properties from
|
||||
* @return A new {@link RegistryBuilder} with the same properties as the given key
|
||||
* @throws IllegalStateException if this method or {@link #empty()} has already been called once
|
||||
* @throws IllegalArgumentException if key doesn't exist
|
||||
*/
|
||||
@Contract("_ -> new")
|
||||
B copyOf(TypedKey<T> key);
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package io.papermc.paper.registry.event;
|
||||
|
||||
import io.papermc.paper.registry.RegistryBuilder;
|
||||
import io.papermc.paper.registry.RegistryBuilderFactory;
|
||||
import io.papermc.paper.registry.TypedKey;
|
||||
import java.util.function.Consumer;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
@ -24,18 +25,18 @@ public interface WritableRegistry<T, B extends RegistryBuilder<T>> {
|
|||
* @param key the entry's key (must be unique from others)
|
||||
* @param value a consumer for the entry's builder
|
||||
*/
|
||||
void register(TypedKey<T> key, Consumer<? super B> value);
|
||||
default void register(final TypedKey<T> key, final Consumer<? super B> value) {
|
||||
this.factoryRegister(key, factory -> value.accept(factory.empty()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a new value with the specified key. This will
|
||||
* fire a {@link RegistryEntryAddEvent} for the new entry. The
|
||||
* builder in the consumer will be pre-filled with the values
|
||||
* from the copyFrom key.
|
||||
* {@link RegistryBuilderFactory} lets you pre-fill a builder with
|
||||
* an already-existing entry's properties.
|
||||
*
|
||||
* @param key the entry's key (must be unique from others)
|
||||
* @param copyFrom the key to copy values from (must already be registered)
|
||||
* @param value a consumer for the entry's builder
|
||||
* @throws IllegalArgumentException if copyFrom doesn't exist
|
||||
* @param value a consumer of a builder factory
|
||||
*/
|
||||
void register(TypedKey<T> key, TypedKey<T> copyFrom, Consumer<? super B> value);
|
||||
void factoryRegister(TypedKey<T> key, Consumer<RegistryBuilderFactory<T, B>> value);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
import java.util.function.Function;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.bukkit.Keyed;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class PaperRegistryBuilderFactory<M, A extends Keyed, B extends PaperRegistryBuilder<M, A>> implements RegistryBuilderFactory<A, B> { // TODO remove Keyed
|
||||
|
||||
private final Conversions conversions;
|
||||
private final RegistryEntryMeta.Buildable<M, A, B> meta;
|
||||
private final Function<? super ResourceLocation, ? extends @Nullable M> existingValueGetter;
|
||||
private @Nullable B builder;
|
||||
|
||||
public PaperRegistryBuilderFactory(final Conversions conversions, final RegistryEntryMeta.Buildable<M, A, B> meta, final Function<? super ResourceLocation, ? extends @Nullable M> existingValueGetter) {
|
||||
this.conversions = conversions;
|
||||
this.meta = meta;
|
||||
this.existingValueGetter = existingValueGetter;
|
||||
}
|
||||
|
||||
private void validate() {
|
||||
if (this.builder != null) {
|
||||
throw new IllegalStateException("Already created a builder");
|
||||
}
|
||||
}
|
||||
|
||||
public B requireBuilder() {
|
||||
if (this.builder == null) {
|
||||
throw new IllegalStateException("Builder not created yet");
|
||||
}
|
||||
return this.builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public B empty() {
|
||||
this.validate();
|
||||
return this.builder = this.meta.builderFiller().create(this.conversions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public B copyOf(final TypedKey<A> key) {
|
||||
this.validate();
|
||||
final M existing = this.existingValueGetter.apply(PaperAdventure.asVanilla(key));
|
||||
if (existing == null) {
|
||||
throw new IllegalArgumentException("Key " + key + " doesn't exist");
|
||||
}
|
||||
return this.builder = this.meta.builderFiller().fill(this.conversions, existing);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
package io.papermc.paper.registry;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.mojang.serialization.Lifecycle;
|
||||
import io.papermc.paper.adventure.PaperAdventure;
|
||||
import io.papermc.paper.registry.data.util.Conversions;
|
||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||
import io.papermc.paper.registry.event.WritableRegistry;
|
||||
|
@ -13,7 +11,6 @@ import net.minecraft.core.RegistrationInfo;
|
|||
import net.minecraft.resources.ResourceKey;
|
||||
import org.bukkit.Keyed;
|
||||
import org.bukkit.craftbukkit.CraftRegistry;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends CraftRegistry<T, M> {
|
||||
|
||||
|
@ -31,23 +28,16 @@ public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBu
|
|||
this.meta = meta;
|
||||
}
|
||||
|
||||
public void register(final TypedKey<T> key, final @Nullable TypedKey<T> copyFrom, final Consumer<? super B> value, final Conversions conversions) {
|
||||
public void register(final TypedKey<T> key, final Consumer<RegistryBuilderFactory<T, B>> value, final Conversions conversions) {
|
||||
final ResourceKey<M> resourceKey = PaperRegistries.toNms(key);
|
||||
this.registry.validateWrite(resourceKey);
|
||||
final B builder;
|
||||
if (copyFrom != null) {
|
||||
final M existing = this.registry.temporaryUnfrozenMap.get(PaperAdventure.asVanilla(copyFrom));
|
||||
Preconditions.checkArgument(existing != null, "Cannot copy from unregistered key: %s", copyFrom);
|
||||
builder = this.meta.builderFiller().fill(conversions, existing);
|
||||
} else {
|
||||
builder = this.meta.builderFiller().create(conversions);
|
||||
}
|
||||
value.accept(builder);
|
||||
final PaperRegistryBuilderFactory<M, T, B> builderFactory = new PaperRegistryBuilderFactory<>(conversions, this.meta, this.registry.temporaryUnfrozenMap::get);
|
||||
value.accept(builderFactory);
|
||||
PaperRegistryListenerManager.INSTANCE.registerWithListeners(
|
||||
this.registry,
|
||||
this.meta,
|
||||
resourceKey,
|
||||
builder,
|
||||
builderFactory.requireBuilder(),
|
||||
FROM_PLUGIN,
|
||||
conversions
|
||||
);
|
||||
|
@ -66,13 +56,8 @@ public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBu
|
|||
}
|
||||
|
||||
@Override
|
||||
public void register(final TypedKey<T> key, final Consumer<? super B> value) {
|
||||
WritableCraftRegistry.this.register(key, null, value, this.conversions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(final TypedKey<T> key, final TypedKey<T> copyFrom, final Consumer<? super B> value) {
|
||||
WritableCraftRegistry.this.register(key, copyFrom, value, this.conversions);
|
||||
public void factoryRegister(final TypedKey<T> key, final Consumer<RegistryBuilderFactory<T, B>> value) {
|
||||
WritableCraftRegistry.this.register(key, value, this.conversions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue