For new registry values, allow copying from existing (#11796)

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
This commit is contained in:
Jake Potrebic
2024-12-26 13:41:15 -08:00
committed by GitHub
parent f51aa3e3e1
commit af2812fb0f
8 changed files with 177 additions and 20 deletions

View File

@@ -0,0 +1,51 @@
package io.papermc.paper.registry;
import io.papermc.paper.adventure.PaperAdventure;
import io.papermc.paper.registry.data.util.Conversions;
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 PaperRegistryBuilder.Filler<M, A, B> builderFiller;
private final Function<? super ResourceLocation, ? extends @Nullable M> existingValueGetter;
private @Nullable B builder;
public PaperRegistryBuilderFactory(final Conversions conversions, final PaperRegistryBuilder.Filler<M, A, B> builderFiller, final Function<? super ResourceLocation, ? extends @Nullable M> existingValueGetter) {
this.conversions = conversions;
this.builderFiller = builderFiller;
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.builderFiller.create(this.conversions);
}
@Override
public B copyFrom(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.builderFiller.fill(this.conversions, existing);
}
}

View File

@@ -2,20 +2,15 @@ package io.papermc.paper.registry;
import com.mojang.serialization.Lifecycle;
import io.papermc.paper.registry.data.util.Conversions;
import io.papermc.paper.registry.entry.RegistryEntry;
import io.papermc.paper.registry.entry.RegistryEntryMeta;
import io.papermc.paper.registry.entry.RegistryTypeMapper;
import io.papermc.paper.registry.event.WritableRegistry;
import java.util.Optional;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import net.minecraft.core.MappedRegistry;
import net.minecraft.core.RegistrationInfo;
import net.minecraft.resources.ResourceKey;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.util.ApiVersion;
public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBuilder<M, T>> extends CraftRegistry<T, M> {
@@ -33,16 +28,16 @@ public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBu
this.meta = meta;
}
public void register(final TypedKey<T> key, 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 = this.newBuilder(conversions);
value.accept(builder);
final PaperRegistryBuilderFactory<M, T, B> builderFactory = new PaperRegistryBuilderFactory<>(conversions, this.meta.builderFiller(), this.registry.temporaryUnfrozenMap::get);
value.accept(builderFactory);
PaperRegistryListenerManager.INSTANCE.registerWithListeners(
this.registry,
this.meta,
resourceKey,
builder,
builderFactory.requireBuilder(),
FROM_PLUGIN,
conversions
);
@@ -52,10 +47,6 @@ public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBu
return new ApiWritableRegistry(conversions);
}
protected B newBuilder(final Conversions conversions) {
return this.meta.builderFiller().create(conversions);
}
public class ApiWritableRegistry implements WritableRegistry<T, B> {
private final Conversions conversions;
@@ -65,7 +56,7 @@ public class WritableCraftRegistry<M, T extends Keyed, B extends PaperRegistryBu
}
@Override
public void register(final TypedKey<T> key, final Consumer<? super B> value) {
public void registerWith(final TypedKey<T> key, final Consumer<RegistryBuilderFactory<T, B>> value) {
WritableCraftRegistry.this.register(key, value, this.conversions);
}
}