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;
|
package io.papermc.paper.registry.event;
|
||||||
|
|
||||||
import io.papermc.paper.registry.RegistryBuilder;
|
import io.papermc.paper.registry.RegistryBuilder;
|
||||||
|
import io.papermc.paper.registry.RegistryBuilderFactory;
|
||||||
import io.papermc.paper.registry.TypedKey;
|
import io.papermc.paper.registry.TypedKey;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
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 key the entry's key (must be unique from others)
|
||||||
* @param value a consumer for the entry's builder
|
* @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
|
* Register a new value with the specified key. This will
|
||||||
* fire a {@link RegistryEntryAddEvent} for the new entry. The
|
* fire a {@link RegistryEntryAddEvent} for the new entry. The
|
||||||
* builder in the consumer will be pre-filled with the values
|
* {@link RegistryBuilderFactory} lets you pre-fill a builder with
|
||||||
* from the copyFrom key.
|
* an already-existing entry's properties.
|
||||||
*
|
*
|
||||||
* @param key the entry's key (must be unique from others)
|
* @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 of a builder factory
|
||||||
* @param value a consumer for the entry's builder
|
|
||||||
* @throws IllegalArgumentException if copyFrom doesn't exist
|
|
||||||
*/
|
*/
|
||||||
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;
|
package io.papermc.paper.registry;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.mojang.serialization.Lifecycle;
|
import com.mojang.serialization.Lifecycle;
|
||||||
import io.papermc.paper.adventure.PaperAdventure;
|
|
||||||
import io.papermc.paper.registry.data.util.Conversions;
|
import io.papermc.paper.registry.data.util.Conversions;
|
||||||
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
import io.papermc.paper.registry.entry.RegistryEntryMeta;
|
||||||
import io.papermc.paper.registry.event.WritableRegistry;
|
import io.papermc.paper.registry.event.WritableRegistry;
|
||||||
|
@ -13,7 +11,6 @@ import net.minecraft.core.RegistrationInfo;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
import org.bukkit.Keyed;
|
import org.bukkit.Keyed;
|
||||||
import org.bukkit.craftbukkit.CraftRegistry;
|
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> {
|
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;
|
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);
|
final ResourceKey<M> resourceKey = PaperRegistries.toNms(key);
|
||||||
this.registry.validateWrite(resourceKey);
|
this.registry.validateWrite(resourceKey);
|
||||||
final B builder;
|
final PaperRegistryBuilderFactory<M, T, B> builderFactory = new PaperRegistryBuilderFactory<>(conversions, this.meta, this.registry.temporaryUnfrozenMap::get);
|
||||||
if (copyFrom != null) {
|
value.accept(builderFactory);
|
||||||
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);
|
|
||||||
PaperRegistryListenerManager.INSTANCE.registerWithListeners(
|
PaperRegistryListenerManager.INSTANCE.registerWithListeners(
|
||||||
this.registry,
|
this.registry,
|
||||||
this.meta,
|
this.meta,
|
||||||
resourceKey,
|
resourceKey,
|
||||||
builder,
|
builderFactory.requireBuilder(),
|
||||||
FROM_PLUGIN,
|
FROM_PLUGIN,
|
||||||
conversions
|
conversions
|
||||||
);
|
);
|
||||||
|
@ -66,13 +56,8 @@ public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBu
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(final TypedKey<T> key, final Consumer<? super B> value) {
|
public void factoryRegister(final TypedKey<T> key, final Consumer<RegistryBuilderFactory<T, B>> value) {
|
||||||
WritableCraftRegistry.this.register(key, null, value, this.conversions);
|
WritableCraftRegistry.this.register(key, 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue