class load bukkit.Registry super early

This commit is contained in:
Jake Potrebic 2024-12-23 08:02:02 -08:00
parent fc72e384a5
commit 011b91b1da
No known key found for this signature in database
GPG key ID: 27CC63F7CBC866C7
5 changed files with 18 additions and 15 deletions

View file

@ -31,6 +31,8 @@ ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true ij_java_generate_final_parameters = true
ij_java_method_parameters_new_line_after_left_paren = true ij_java_method_parameters_new_line_after_left_paren = true
ij_java_method_parameters_right_paren_on_new_line = true ij_java_method_parameters_right_paren_on_new_line = true
ij_java_use_fq_class_names = false
ij_java_class_names_in_javadoc = 1
[paper-server/src/minecraft/java/**/*.java] [paper-server/src/minecraft/java/**/*.java]
ij_java_use_fq_class_names = true ij_java_use_fq_class_names = true

View file

@ -1,6 +1,5 @@
package io.papermc.paper.registry; package io.papermc.paper.registry;
import com.google.common.base.Preconditions;
import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.entry.RegistryEntry;
import io.papermc.paper.registry.entry.RegistryEntryMeta; import io.papermc.paper.registry.entry.RegistryEntryMeta;
import io.papermc.paper.registry.legacy.DelayedRegistry; import io.papermc.paper.registry.legacy.DelayedRegistry;
@ -74,7 +73,7 @@ public class PaperRegistryAccess implements RegistryAccess {
if (PaperRegistries.getEntry(key) == null) { if (PaperRegistries.getEntry(key) == null) {
throw new NoSuchElementException(key + " is not a valid registry key"); throw new NoSuchElementException(key + " is not a valid registry key");
} }
final @Nullable RegistryHolder<T> registryHolder = (RegistryHolder<T>) this.registries.get(key); final RegistryHolder<T> registryHolder = (RegistryHolder<T>) this.registries.get(key);
if (registryHolder == null) { if (registryHolder == null) {
throw new IllegalArgumentException(key + " points to a registry that is not available yet"); throw new IllegalArgumentException(key + " points to a registry that is not available yet");
} }
@ -112,22 +111,16 @@ public class PaperRegistryAccess implements RegistryAccess {
return; return;
} }
final CraftRegistry<?, M> registry = (CraftRegistry<?, M>) this.getRegistry(entry.apiKey()); final CraftRegistry<?, M> registry = (CraftRegistry<?, M>) this.getRegistry(entry.apiKey());
Preconditions.checkState(registry.isUnloaded(), "Registry %s is already loaded", resourceKey);
try {
Class.forName(serverSide.classToPreload().getName()); // this should always trigger the initialization of the class
} catch (final ClassNotFoundException e) {
throw new IllegalStateException("Failed to load class " + serverSide.classToPreload().getName(), e);
}
registry.lockReferenceHolders(); registry.lockReferenceHolders();
} }
@SuppressWarnings("unchecked") // this method should be called right after any new MappedRegistry instances are created to later be used by the server. @SuppressWarnings("unchecked") // this method should be called right after any new MappedRegistry instances are created to later be used by the server.
private <M, B extends Keyed, R extends Registry<B>> void registerRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry, final boolean replace) { private <M, B extends Keyed, R extends Registry<B>> void registerRegistry(final ResourceKey<? extends net.minecraft.core.Registry<M>> resourceKey, final net.minecraft.core.Registry<M> registry, final boolean replace) {
final @Nullable RegistryEntry<M, B> entry = PaperRegistries.getEntry(resourceKey); final RegistryEntry<M, B> entry = PaperRegistries.getEntry(resourceKey);
if (entry == null) { // skip registries that don't have API entries if (entry == null) { // skip registries that don't have API entries
return; return;
} }
final @Nullable RegistryHolder<B> registryHolder = (RegistryHolder<B>) this.registries.get(entry.apiKey()); final RegistryHolder<B> registryHolder = (RegistryHolder<B>) this.registries.get(entry.apiKey());
if (registryHolder == null || replace) { if (registryHolder == null || replace) {
// if the holder doesn't exist yet, or is marked as "replaceable", put it in the map. // if the holder doesn't exist yet, or is marked as "replaceable", put it in the map.
this.registries.put(entry.apiKey(), entry.createRegistryHolder(registry)); this.registries.put(entry.apiKey(), entry.createRegistryHolder(registry));

View file

@ -181,11 +181,17 @@ public class CraftRegistry<B extends Keyed, M> implements Registry<B> {
this.lockReferenceHolders = !this.minecraftToBukkit.supportsDirectHolders(); this.lockReferenceHolders = !this.minecraftToBukkit.supportsDirectHolders();
} }
public boolean isUnloaded() {
return this.cache.isEmpty();
}
public void lockReferenceHolders() { public void lockReferenceHolders() {
Preconditions.checkState(this.cache.isEmpty(), "Registry %s is already loaded", this.minecraftRegistry.key());
try {
Class.forName(this.bukkitClass.getName()); // this should always trigger the initialization of the class
} catch (final ClassNotFoundException e) {
throw new IllegalStateException("Failed to load class " + this.bukkitClass.getSimpleName(), e);
}
if (!this.minecraftToBukkit.supportsDirectHolders()) {
return;
}
Preconditions.checkState(!this.lockReferenceHolders, "Reference holders are already locked"); Preconditions.checkState(!this.lockReferenceHolders, "Reference holders are already locked");
this.lockReferenceHolders = true; this.lockReferenceHolders = true;
} }

View file

@ -16,6 +16,7 @@ import net.minecraft.resources.ResourceKey;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Keyed; import org.bukkit.Keyed;
import org.bukkit.Registry; import org.bukkit.Registry;
import org.bukkit.craftbukkit.CraftRegistry;
import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.craftbukkit.util.Handleable;
import org.bukkit.support.environment.AllFeatures; import org.bukkit.support.environment.AllFeatures;
import org.bukkit.support.provider.RegistryArgumentProvider; import org.bukkit.support.provider.RegistryArgumentProvider;

View file

@ -25,7 +25,7 @@ public class RegistryLoadOrderTest {
private static boolean initInterface = false; private static boolean initInterface = false;
private static boolean initAbstract = false; private static boolean initAbstract = false;
private static org.bukkit.Registry<Keyed> registry; // Paper - remap fix private static Registry<Keyed> registry;
public static Stream<Arguments> data() { public static Stream<Arguments> data() {
return Stream.of( return Stream.of(
@ -60,6 +60,7 @@ public class RegistryLoadOrderTest {
RegistryLoadOrderTest.registry = new CraftRegistry<>(keyedClass, minecraftRegistry, minecraftToBukkit, (namespacedKey, apiVersion) -> namespacedKey); RegistryLoadOrderTest.registry = new CraftRegistry<>(keyedClass, minecraftRegistry, minecraftToBukkit, (namespacedKey, apiVersion) -> namespacedKey);
this.testClassNotLoaded(init.get()); this.testClassNotLoaded(init.get());
((CraftRegistry<?, ?>) RegistryLoadOrderTest.registry).lockReferenceHolders();
Object testOne = RegistryLoadOrderTest.registry.get(new NamespacedKey("bukkit", "test-one")); Object testOne = RegistryLoadOrderTest.registry.get(new NamespacedKey("bukkit", "test-one"));
Object otherTestOne = RegistryLoadOrderTest.registry.get(new NamespacedKey("bukkit", "test-one")); Object otherTestOne = RegistryLoadOrderTest.registry.get(new NamespacedKey("bukkit", "test-one"));