3
0
Mirror von https://github.com/GeyserMC/Geyser.git synchronisiert 2024-11-05 07:40:11 +01:00

Use deferred where needed instead of a load method on all registries (#5112)

* Use deferred where needed instead of a load method on all registries

* We don't have to load the registries, they're now safe to use for tests

* Renamed the deferred registries
Dieser Commit ist enthalten in:
Tim203 2024-10-30 10:41:00 +01:00 committet von GitHub
Ursprung 3f60db1483
Commit 74b25ea3a5
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: B5690EEEBB952194
13 geänderte Dateien mit 689 neuen und 156 gelöschten Zeilen

Datei anzeigen

@ -236,7 +236,6 @@ public class GeyserImpl implements GeyserApi, EventRegistrar {
Both the block registries and the common registries depend on each other,
so maintaining this order is crucial for Geyser to load.
*/
BlockRegistries.load();
Registries.load();
BlockRegistries.populate();
Registries.populate();

Datei anzeigen

@ -0,0 +1,103 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.registry.loader.RegistryLoader;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier;
public abstract class AbstractMappedDeferredRegistry<K, V, M extends Map<K, V>, R extends AbstractMappedRegistry<K, V, M>> extends DeferredRegistry<M, R> {
protected <I> AbstractMappedDeferredRegistry(Function<RegistryLoader<I, M>, R> registryLoader, RegistryLoader<I, M> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> AbstractMappedDeferredRegistry(Function<RegistryLoader<I, M>, R> registryLoader, Supplier<RegistryLoader<I, M>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> AbstractMappedDeferredRegistry(I input, RegistryInitializer<M, R> registryInitializer, RegistryLoader<I, M> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
protected <I> AbstractMappedDeferredRegistry(I input, RegistryInitializer<M, R> registryInitializer, Supplier<RegistryLoader<I, M>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
/**
* Returns the value registered by the given key.
*
* @param key the key
* @return the value registered by the given key.
*/
public @Nullable V get(K key) {
return get().get(key);
}
/**
* Returns and maps the value by the given key if present.
*
* @param key the key
* @param mapper the mapper
* @param <U> the type
* @return the mapped value from the given key if present
*/
public <U> Optional<U> map(K key, Function<? super V, ? extends U> mapper) {
V value = this.get(key);
if (value == null) {
return Optional.empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
/**
* Returns the value registered by the given key or the default value
* specified if null.
*
* @param key the key
* @param defaultValue the default value
* @return the value registered by the given key or the default value
* specified if null.
*/
public V getOrDefault(K key, V defaultValue) {
return get().getOrDefault(key, defaultValue);
}
/**
* Registers a new value into this registry with the given key.
*
* @param key the key
* @param value the value
* @return a new value into this registry with the given key.
*/
public V register(K key, V value) {
return get().put(key, value);
}
}

Datei anzeigen

@ -69,7 +69,7 @@ public class BlockRegistries {
/**
* A mapped registry containing which holds block IDs to its {@link BlockCollision}.
*/
public static final ListRegistry<BlockCollision> COLLISIONS = ListRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collisions.nbt"), CollisionRegistryLoader::new);
public static final ListDeferredRegistry<BlockCollision> COLLISIONS = ListDeferredRegistry.create(Pair.of("org.geysermc.geyser.translator.collision.CollisionRemapper", "mappings/collisions.nbt"), CollisionRegistryLoader::new);
/**
* A registry which stores Java IDs to {@link Block}, containing miscellaneous information about
@ -130,23 +130,6 @@ public class BlockRegistries {
*/
public static final SimpleMappedRegistry<String, CustomSkull> CUSTOM_SKULLS = SimpleMappedRegistry.create(RegistryLoaders.empty(Object2ObjectOpenHashMap::new));
public static void load() {
BLOCKS.load();
BLOCK_STATES.load();
// collisions are loaded later, because they are initialized later
JAVA_BLOCKS.load();
JAVA_IDENTIFIER_TO_ID.load();
WATERLOGGED.load();
INTERACTIVE.load();
INTERACTIVE_MAY_BUILD.load();
CUSTOM_BLOCKS.load();
CUSTOM_BLOCK_STATE_OVERRIDES.load();
NON_VANILLA_BLOCK_STATE_OVERRIDES.load();
CUSTOM_BLOCK_ITEM_OVERRIDES.load();
EXTENDED_COLLISION_BOXES.load();
CUSTOM_SKULLS.load();
}
public static void populate() {
Blocks.VAULT.javaId(); // FIXME
CustomSkullRegistryPopulator.populate();
@ -160,5 +143,4 @@ public class BlockRegistries {
BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.INIT_BEDROCK);
BlockRegistryPopulator.populate(BlockRegistryPopulator.Stage.POST_INIT);
}
}

Datei anzeigen

@ -43,32 +43,36 @@ import java.util.function.Supplier;
*
* @param <M> the value being held by the registry
*/
public final class DeferredRegistry<M> implements IRegistry<M> {
private final Registry<M> backingRegistry;
class DeferredRegistry<M, R extends IRegistry<M>> implements IRegistry<M> {
private final R backingRegistry;
private final Supplier<M> loader;
private boolean loaded;
private <I> DeferredRegistry(Function<RegistryLoader<I, M>, Registry<M>> registryLoader, RegistryLoader<I, M> deferredLoader) {
protected <I> DeferredRegistry(Function<RegistryLoader<I, M>, R> registryLoader, RegistryLoader<I, M> deferredLoader) {
this.backingRegistry = registryLoader.apply(RegistryLoaders.uninitialized());
this.loader = () -> deferredLoader.load(null);
}
private <I> DeferredRegistry(Function<RegistryLoader<I, M>, Registry<M>> registryLoader, Supplier<RegistryLoader<I, M>> deferredLoader) {
protected <I> DeferredRegistry(Function<RegistryLoader<I, M>, R> registryLoader, Supplier<RegistryLoader<I, M>> deferredLoader) {
this.backingRegistry = registryLoader.apply(RegistryLoaders.uninitialized());
this.loader = () -> deferredLoader.get().load(null);
}
private <I> DeferredRegistry(I input, RegistryInitializer<M> registryInitializer, RegistryLoader<I, M> deferredLoader) {
protected <I> DeferredRegistry(I input, RegistryInitializer<M, R> registryInitializer, RegistryLoader<I, M> deferredLoader) {
this.backingRegistry = registryInitializer.initialize(input, RegistryLoaders.uninitialized());
this.loader = () -> deferredLoader.load(input);
}
private <I> DeferredRegistry(I input, RegistryInitializer<M> registryInitializer, Supplier<RegistryLoader<I, M>> deferredLoader) {
protected <I> DeferredRegistry(I input, RegistryInitializer<M, R> registryInitializer, Supplier<RegistryLoader<I, M>> deferredLoader) {
this.backingRegistry = registryInitializer.initialize(input, RegistryLoaders.uninitialized());
this.loader = () -> deferredLoader.get().load(input);
}
protected R backingRegistry() {
return this.backingRegistry;
}
/**
* Gets the underlying value held by this registry.
*
@ -119,64 +123,12 @@ public final class DeferredRegistry<M> implements IRegistry<M> {
return this.loaded;
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @param <M> the registry type
* @return the new deferred registry
*/
public static <I, M> DeferredRegistry<M> create(Function<RegistryLoader<I, M>, Registry<M>> registryLoader, RegistryLoader<I, M> deferredLoader) {
return new DeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @param <M> the registry type
* @return the new deferred registry
*/
public static <I, M> DeferredRegistry<M> create(Function<RegistryLoader<I, M>, Registry<M>> registryLoader, Supplier<RegistryLoader<I, M>> deferredLoader) {
return new DeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @param <M> the registry type
* @return the new deferred registry
*/
public static <I, M> DeferredRegistry<M> create(I input, RegistryInitializer<M> registryInitializer, RegistryLoader<I, M> deferredLoader) {
return new DeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @param <M> the registry type
* @return the new deferred registry
*/
public static <I, M> DeferredRegistry<M> create(I input, RegistryInitializer<M> registryInitializer, Supplier<RegistryLoader<I, M>> deferredLoader) {
return new DeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* A registry initializer.
*
* @param <M> the registry type
*/
interface RegistryInitializer<M> {
public interface RegistryInitializer<M, R extends IRegistry<M>> {
/**
* Initializes the registry.
@ -186,6 +138,6 @@ public final class DeferredRegistry<M> implements IRegistry<M> {
* @param <I> the input type
* @return the initialized registry
*/
<I> Registry<M> initialize(I input, RegistryLoader<I, M> registryLoader);
<I> R initialize(I input, RegistryLoader<I, M> registryLoader);
}
}

Datei anzeigen

@ -0,0 +1,175 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.geysermc.geyser.registry.loader.RegistryLoader;
import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
public class ListDeferredRegistry<V> extends DeferredRegistry<List<V>, ListRegistry<V>> {
protected <I> ListDeferredRegistry(Function<RegistryLoader<I, List<V>>, ListRegistry<V>> registryLoader, RegistryLoader<I, List<V>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> ListDeferredRegistry(Function<RegistryLoader<I, List<V>>, ListRegistry<V>> registryLoader, Supplier<RegistryLoader<I, List<V>>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> ListDeferredRegistry(I input, RegistryInitializer<List<V>, ListRegistry<V>> registryInitializer, RegistryLoader<I, List<V>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
protected <I> ListDeferredRegistry(I input, RegistryInitializer<List<V>, ListRegistry<V>> registryInitializer, Supplier<RegistryLoader<I, List<V>>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
/**
* Returns the value registered by the given index.
*
* @param index the index
* @return the value registered by the given index.
*/
@Nullable
public V get(int index) {
return backingRegistry().get(index);
}
/**
* Returns the value registered by the given index or the default value
* specified if null.
*
* @param index the index
* @param defaultValue the default value
* @return the value registered by the given key or the default value
* specified if null.
*/
public V getOrDefault(int index, V defaultValue) {
return backingRegistry().getOrDefault(index, defaultValue);
}
/**
* Registers a new value into this registry with the given index.
*
* @param index the index
* @param value the value
* @return a new value into this registry with the given index.
*/
public V register(int index, V value) {
return backingRegistry().register(index, value);
}
/**
* Registers a new value into this registry with the given index, even if this value would normally be outside
* the range of a list.
*
* @param index the index
* @param value the value
* @param defaultValue the default value to fill empty spaces in the registry with.
* @return a new value into this registry with the given index.
*/
public V registerWithAnyIndex(int index, V value, V defaultValue) {
return backingRegistry().registerWithAnyIndex(index, value, defaultValue);
}
/**
* Mark this registry as unsuitable for new additions. The backing list will then be optimized for storage.
*/
public void freeze() {
backingRegistry().freeze();
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> ListDeferredRegistry<V> create(Function<RegistryLoader<I, List<V>>, ListRegistry<V>> registryLoader, RegistryLoader<I, List<V>> deferredLoader) {
return new ListDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> ListDeferredRegistry<V> create(Function<RegistryLoader<I, List<V>>, ListRegistry<V>> registryLoader, Supplier<RegistryLoader<I, List<V>>> deferredLoader) {
return new ListDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> ListDeferredRegistry<V> create(I input, RegistryInitializer<List<V>, ListRegistry<V>> registryInitializer, RegistryLoader<I, List<V>> deferredLoader) {
return new ListDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> ListDeferredRegistry<V> create(I input, RegistryInitializer<List<V>, ListRegistry<V>> registryInitializer, Supplier<RegistryLoader<I, List<V>>> deferredLoader) {
return new ListDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> ListDeferredRegistry<V> create(I input, RegistryLoader<I, List<V>> deferredLoader) {
return create(input, ListRegistry::create, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> ListDeferredRegistry<V> create(I input, Supplier<RegistryLoader<I, List<V>>> deferredLoader) {
return create(input, ListRegistry::create, deferredLoader);
}
}

Datei anzeigen

@ -140,6 +140,18 @@ public class ListRegistry<M> extends Registry<List<M>> {
return new ListRegistry<>(null, registryLoader);
}
/**
* Creates a new integer mapped registry with the given {@link RegistryLoader} and input.
*
* @param registryLoader the registry loader
* @param <I> the input
* @param <M> the type value
* @return a new registry with the given RegistryLoader
*/
public static <I, M> ListRegistry<M> create(I input, RegistryLoader<I, List<M>> registryLoader) {
return new ListRegistry<>(input, registryLoader);
}
/**
* Creates a new integer mapped registry with the given {@link RegistryLoader} and input.
*

Datei anzeigen

@ -37,10 +37,18 @@ import org.geysermc.geyser.api.pack.ResourcePack;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.inventory.recipe.GeyserRecipe;
import org.geysermc.geyser.item.type.Item;
import org.geysermc.geyser.registry.loader.*;
import org.geysermc.geyser.registry.loader.BiomeIdentifierRegistryLoader;
import org.geysermc.geyser.registry.loader.BlockEntityRegistryLoader;
import org.geysermc.geyser.registry.loader.ParticleTypesRegistryLoader;
import org.geysermc.geyser.registry.loader.PotionMixRegistryLoader;
import org.geysermc.geyser.registry.loader.ProviderRegistryLoader;
import org.geysermc.geyser.registry.loader.RecipeRegistryLoader;
import org.geysermc.geyser.registry.loader.RegistryLoaders;
import org.geysermc.geyser.registry.loader.SoundEventsRegistryLoader;
import org.geysermc.geyser.registry.loader.SoundRegistryLoader;
import org.geysermc.geyser.registry.loader.SoundTranslatorRegistryLoader;
import org.geysermc.geyser.registry.populator.ItemRegistryPopulator;
import org.geysermc.geyser.registry.populator.PacketRegistryPopulator;
import org.geysermc.geyser.registry.loader.RecipeRegistryLoader;
import org.geysermc.geyser.registry.provider.ProviderSupplier;
import org.geysermc.geyser.registry.type.ItemMappings;
import org.geysermc.geyser.registry.type.ParticleMapping;
@ -56,7 +64,13 @@ import org.geysermc.mcprotocollib.protocol.data.game.level.event.LevelEvent;
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
import org.geysermc.mcprotocollib.protocol.data.game.recipe.RecipeType;
import java.util.*;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Holds all the common registries in Geyser.
@ -73,7 +87,7 @@ public final class Registries {
/**
* A registry holding a NbtMap of the known entity identifiers.
*/
public static final SimpleRegistry<NbtMap> BEDROCK_ENTITY_IDENTIFIERS = SimpleRegistry.create("bedrock/entity_identifiers.dat", RegistryLoaders.NBT);
public static final SimpleDeferredRegistry<NbtMap> BEDROCK_ENTITY_IDENTIFIERS = SimpleDeferredRegistry.create("bedrock/entity_identifiers.dat", RegistryLoaders.NBT);
/**
* A registry containing all the Bedrock packet translators.
@ -83,17 +97,17 @@ public final class Registries {
/**
* A registry holding a NbtMap of all the known biomes.
*/
public static final SimpleRegistry<NbtMap> BIOMES_NBT = SimpleRegistry.create("bedrock/biome_definitions.dat", RegistryLoaders.NBT);
public static final SimpleDeferredRegistry<NbtMap> BIOMES_NBT = SimpleDeferredRegistry.create("bedrock/biome_definitions.dat", RegistryLoaders.NBT);
/**
* A mapped registry which stores Java biome identifiers and their Bedrock biome identifier.
*/
public static final SimpleRegistry<Object2IntMap<String>> BIOME_IDENTIFIERS = SimpleRegistry.create("mappings/biomes.json", BiomeIdentifierRegistryLoader::new);
public static final SimpleDeferredRegistry<Object2IntMap<String>> BIOME_IDENTIFIERS = SimpleDeferredRegistry.create("mappings/biomes.json", BiomeIdentifierRegistryLoader::new);
/**
* A mapped registry which stores a block entity identifier to its {@link BlockEntityTranslator}.
*/
public static final SimpleMappedRegistry<BlockEntityType, BlockEntityTranslator> BLOCK_ENTITIES = SimpleMappedRegistry.create("org.geysermc.geyser.translator.level.block.entity.BlockEntity", BlockEntityRegistryLoader::new);
public static final SimpleMappedDeferredRegistry<BlockEntityType, BlockEntityTranslator> BLOCK_ENTITIES = SimpleMappedDeferredRegistry.create("org.geysermc.geyser.translator.level.block.entity.BlockEntity", BlockEntityRegistryLoader::new);
/**
* A map containing all entity types and their respective Geyser definitions
@ -135,55 +149,50 @@ public final class Registries {
* A mapped registry holding the {@link ParticleType} to a corresponding {@link ParticleMapping}, containing various pieces of
* data primarily for how Bedrock should handle the particle.
*/
public static final SimpleMappedRegistry<ParticleType, ParticleMapping> PARTICLES = SimpleMappedRegistry.create("mappings/particles.json", ParticleTypesRegistryLoader::new);
public static final SimpleMappedDeferredRegistry<ParticleType, ParticleMapping> PARTICLES = SimpleMappedDeferredRegistry.create("mappings/particles.json", ParticleTypesRegistryLoader::new);
/**
* A registry holding all the potion mixes.
*/
public static final VersionedRegistry<Set<PotionMixData>> POTION_MIXES = VersionedRegistry.create(PotionMixRegistryLoader::new);
public static final VersionedDeferredRegistry<Set<PotionMixData>> POTION_MIXES = VersionedDeferredRegistry.create(VersionedRegistry::create, PotionMixRegistryLoader::new);
/**
* A versioned registry holding all the recipes, with the net ID being the key, and {@link GeyserRecipe} as the value.
*/
public static final SimpleMappedRegistry<RecipeType, List<GeyserRecipe>> RECIPES = SimpleMappedRegistry.create("mappings/recipes.nbt", RecipeRegistryLoader::new);
public static final SimpleMappedDeferredRegistry<RecipeType, List<GeyserRecipe>> RECIPES = SimpleMappedDeferredRegistry.create("mappings/recipes.nbt", RecipeRegistryLoader::new);
/**
* A mapped registry holding {@link ResourcePack}'s with the pack uuid as keys.
*/
public static final DeferredRegistry<Map<String, ResourcePack>> RESOURCE_PACKS = DeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), SimpleMappedRegistry::create, RegistryLoaders.RESOURCE_PACKS);
public static final SimpleMappedDeferredRegistry<String, ResourcePack> RESOURCE_PACKS = SimpleMappedDeferredRegistry.create(GeyserImpl.getInstance().packDirectory(), RegistryLoaders.RESOURCE_PACKS);
/**
* A mapped registry holding sound identifiers to their corresponding {@link SoundMapping}.
*/
public static final SimpleMappedRegistry<String, SoundMapping> SOUNDS = SimpleMappedRegistry.create("mappings/sounds.json", SoundRegistryLoader::new);
public static final SimpleMappedDeferredRegistry<String, SoundMapping> SOUNDS = SimpleMappedDeferredRegistry.create("mappings/sounds.json", SoundRegistryLoader::new);
/**
* A mapped registry holding {@link LevelEvent}s to their corresponding {@link LevelEventTranslator}.
*/
public static final SimpleMappedRegistry<LevelEvent, LevelEventTranslator> SOUND_LEVEL_EVENTS = SimpleMappedRegistry.create("mappings/effects.json", SoundEventsRegistryLoader::new);
public static final SimpleMappedDeferredRegistry<LevelEvent, LevelEventTranslator> SOUND_LEVEL_EVENTS = SimpleMappedDeferredRegistry.create("mappings/effects.json", SoundEventsRegistryLoader::new);
/**
* A mapped registry holding {@link SoundTranslator}s to their corresponding {@link SoundInteractionTranslator}.
*/
public static final SimpleMappedRegistry<SoundTranslator, SoundInteractionTranslator<?>> SOUND_TRANSLATORS = SimpleMappedRegistry.create("org.geysermc.geyser.translator.sound.SoundTranslator", SoundTranslatorRegistryLoader::new);
public static final SimpleMappedDeferredRegistry<SoundTranslator, SoundInteractionTranslator<?>> SOUND_TRANSLATORS = SimpleMappedDeferredRegistry.create("org.geysermc.geyser.translator.sound.SoundTranslator", SoundTranslatorRegistryLoader::new);
public static void load() {
if (loaded) return;
loaded = true;
PROVIDERS.load();
// the following registries are registries that are more complicated than initializing as an empty collection.
// They generally have in common that they either depend on loading a resource file directly or indirectly
// (by using the Items or Blocks class, which loads all the blocks)
BEDROCK_ENTITY_IDENTIFIERS.load();
BEDROCK_PACKET_TRANSLATORS.load();
BIOMES_NBT.load();
BIOME_IDENTIFIERS.load();
BLOCK_ENTITIES.load();
ENTITY_DEFINITIONS.load();
BEDROCK_ENTITY_PROPERTIES.load();
JAVA_ENTITY_IDENTIFIERS.load();
JAVA_PACKET_TRANSLATORS.load();
JAVA_ITEMS.load();
JAVA_ITEM_IDENTIFIERS.load();
ITEMS.load();
PARTICLES.load();
// load potion mixes later
RECIPES.load();

Datei anzeigen

@ -27,7 +27,6 @@ package org.geysermc.geyser.registry;
import java.util.function.Consumer;
import org.geysermc.geyser.registry.loader.RegistryLoader;
import org.geysermc.geyser.registry.loader.RegistryLoaderHolder;
/**
* A wrapper around a value which is loaded based on the output from the provided
@ -63,9 +62,7 @@ import org.geysermc.geyser.registry.loader.RegistryLoaderHolder;
*
* @param <M> the value being held by the registry
*/
@SuppressWarnings("rawtypes")
public abstract class Registry<M> implements IRegistry<M> {
protected RegistryLoaderHolder loaderHolder;
protected M mappings;
/**
@ -78,17 +75,7 @@ public abstract class Registry<M> implements IRegistry<M> {
* @param <I> the input type
*/
protected <I> Registry(I input, RegistryLoader<I, M> registryLoader) {
this.loaderHolder = new RegistryLoaderHolder<>(input, registryLoader);
}
public void load() {
// don't load twice
if (this.mappings != null) return;
var holder = this.loaderHolder;
this.loaderHolder = null;
//noinspection unchecked
this.mappings = (M) holder.registryLoader().load(holder.input());
this.mappings = registryLoader.load(input);
}
/**

Datei anzeigen

@ -0,0 +1,119 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry;
import org.geysermc.geyser.registry.loader.RegistryLoader;
import java.util.function.Function;
import java.util.function.Supplier;
public class SimpleDeferredRegistry<V> extends DeferredRegistry<V, SimpleRegistry<V>> {
protected <I> SimpleDeferredRegistry(Function<RegistryLoader<I, V>, SimpleRegistry<V>> registryLoader, RegistryLoader<I, V> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> SimpleDeferredRegistry(Function<RegistryLoader<I, V>, SimpleRegistry<V>> registryLoader, Supplier<RegistryLoader<I, V>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> SimpleDeferredRegistry(I input, RegistryInitializer<V, SimpleRegistry<V>> registryInitializer, RegistryLoader<I, V> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
protected <I> SimpleDeferredRegistry(I input, RegistryInitializer<V, SimpleRegistry<V>> registryInitializer, Supplier<RegistryLoader<I, V>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> SimpleDeferredRegistry<V> create(Function<RegistryLoader<I, V>, SimpleRegistry<V>> registryLoader, RegistryLoader<I, V> deferredLoader) {
return new SimpleDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> SimpleDeferredRegistry<V> create(Function<RegistryLoader<I, V>, SimpleRegistry<V>> registryLoader, Supplier<RegistryLoader<I, V>> deferredLoader) {
return new SimpleDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> SimpleDeferredRegistry<V> create(I input, RegistryInitializer<V, SimpleRegistry<V>> registryInitializer, RegistryLoader<I, V> deferredLoader) {
return new SimpleDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> SimpleDeferredRegistry<V> create(I input, RegistryInitializer<V, SimpleRegistry<V>> registryInitializer, Supplier<RegistryLoader<I, V>> deferredLoader) {
return new SimpleDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> SimpleDeferredRegistry<V> create(I input, RegistryLoader<I, V> deferredLoader) {
return create(input, SimpleRegistry::create, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> SimpleDeferredRegistry<V> create(I input, Supplier<RegistryLoader<I, V>> deferredLoader) {
return create(input, SimpleRegistry::create, deferredLoader);
}
}

Datei anzeigen

@ -0,0 +1,120 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry;
import org.geysermc.geyser.registry.loader.RegistryLoader;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
public class SimpleMappedDeferredRegistry<K, V> extends AbstractMappedDeferredRegistry<K, V, Map<K, V>, SimpleMappedRegistry<K, V>> {
protected <I> SimpleMappedDeferredRegistry(Function<RegistryLoader<I, Map<K, V>>, SimpleMappedRegistry<K, V>> registryLoader, RegistryLoader<I, Map<K, V>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> SimpleMappedDeferredRegistry(Function<RegistryLoader<I, Map<K, V>>, SimpleMappedRegistry<K, V>> registryLoader, Supplier<RegistryLoader<I, Map<K, V>>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> SimpleMappedDeferredRegistry(I input, RegistryInitializer<Map<K, V>, SimpleMappedRegistry<K, V>> registryInitializer, RegistryLoader<I, Map<K, V>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
protected <I> SimpleMappedDeferredRegistry(I input, RegistryInitializer<Map<K, V>, SimpleMappedRegistry<K, V>> registryInitializer, Supplier<RegistryLoader<I, Map<K, V>>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, K, V> SimpleMappedDeferredRegistry<K, V> create(Function<RegistryLoader<I, Map<K, V>>, SimpleMappedRegistry<K, V>> registryLoader, RegistryLoader<I, Map<K, V>> deferredLoader) {
return new SimpleMappedDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, K, V> SimpleMappedDeferredRegistry<K, V> create(Function<RegistryLoader<I, Map<K, V>>, SimpleMappedRegistry<K, V>> registryLoader, Supplier<RegistryLoader<I, Map<K, V>>> deferredLoader) {
return new SimpleMappedDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, K, V> SimpleMappedDeferredRegistry<K, V> create(I input, DeferredRegistry.RegistryInitializer<Map<K, V>, SimpleMappedRegistry<K, V>> registryInitializer, RegistryLoader<I, Map<K, V>> deferredLoader) {
return new SimpleMappedDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, K, V> SimpleMappedDeferredRegistry<K, V> create(I input, DeferredRegistry.RegistryInitializer<Map<K, V>, SimpleMappedRegistry<K, V>> registryInitializer, Supplier<RegistryLoader<I, Map<K, V>>> deferredLoader) {
return new SimpleMappedDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, K, V> SimpleMappedDeferredRegistry<K, V> create(I input, RegistryLoader<I, Map<K, V>> deferredLoader) {
return create(input, SimpleMappedRegistry::create, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, K, V> SimpleMappedDeferredRegistry<K, V> create(I input, Supplier<RegistryLoader<I, Map<K, V>>> deferredLoader) {
return create(input, SimpleMappedRegistry::create, deferredLoader);
}
}

Datei anzeigen

@ -0,0 +1,114 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.geysermc.geyser.registry.loader.RegistryLoader;
import java.util.function.Function;
import java.util.function.Supplier;
public class VersionedDeferredRegistry<V> extends AbstractMappedDeferredRegistry<Integer, V, Int2ObjectMap<V>, VersionedRegistry<V>> {
protected <I> VersionedDeferredRegistry(Function<RegistryLoader<I, Int2ObjectMap<V>>, VersionedRegistry<V>> registryLoader, RegistryLoader<I, Int2ObjectMap<V>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> VersionedDeferredRegistry(Function<RegistryLoader<I, Int2ObjectMap<V>>, VersionedRegistry<V>> registryLoader, Supplier<RegistryLoader<I, Int2ObjectMap<V>>> deferredLoader) {
super(registryLoader, deferredLoader);
}
protected <I> VersionedDeferredRegistry(I input, RegistryInitializer<Int2ObjectMap<V>, VersionedRegistry<V>> registryInitializer, RegistryLoader<I, Int2ObjectMap<V>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
protected <I> VersionedDeferredRegistry(I input, RegistryInitializer<Int2ObjectMap<V>, VersionedRegistry<V>> registryInitializer, Supplier<RegistryLoader<I, Int2ObjectMap<V>>> deferredLoader) {
super(input, registryInitializer, deferredLoader);
}
/**
* Gets the closest value for the specified version. Only
* returns versions higher up than the specified if one
* does not exist for the given one. Useful in the event
* that you want to get a resource which is guaranteed for
* older versions, but not on newer ones.
*
* @param version the version
* @return the closest value for the specified version
* @throws IllegalArgumentException if no values exist at or above the given version
*/
@NonNull
public V forVersion(int version) {
return backingRegistry().forVersion(version);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> VersionedDeferredRegistry<V> create(Function<RegistryLoader<I, Int2ObjectMap<V>>, VersionedRegistry<V>> registryLoader, RegistryLoader<I, Int2ObjectMap<V>> deferredLoader) {
return new VersionedDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryLoader the registry loader
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> VersionedDeferredRegistry<V> create(Function<RegistryLoader<I, Int2ObjectMap<V>>, VersionedRegistry<V>> registryLoader, Supplier<RegistryLoader<I, Int2ObjectMap<V>>> deferredLoader) {
return new VersionedDeferredRegistry<>(registryLoader, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> VersionedDeferredRegistry<V> create(I input, RegistryInitializer<Int2ObjectMap<V>, VersionedRegistry<V>> registryInitializer, RegistryLoader<I, Int2ObjectMap<V>> deferredLoader) {
return new VersionedDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
/**
* Creates a new deferred registry.
*
* @param registryInitializer the registry initializer
* @param deferredLoader the deferred loader
* @param <I> the input type
* @return the new deferred registry
*/
public static <I, V> VersionedDeferredRegistry<V> create(I input, RegistryInitializer<Int2ObjectMap<V>, VersionedRegistry<V>> registryInitializer, Supplier<RegistryLoader<I, Int2ObjectMap<V>>> deferredLoader) {
return new VersionedDeferredRegistry<>(input, registryInitializer, deferredLoader);
}
}

Datei anzeigen

@ -1,33 +0,0 @@
/*
* Copyright (c) 2024 GeyserMC. http://geysermc.org
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* @author GeyserMC
* @link https://github.com/GeyserMC/Geyser
*/
package org.geysermc.geyser.registry.loader;
/**
* A holder of the constructor parameters to prevent them from automatically loading,
* and instead load them when the load method is called.
*/
public record RegistryLoaderHolder<I, M>(I input, RegistryLoader<I, M> registryLoader) {
}

Datei anzeigen

@ -61,12 +61,6 @@ public class GeyserMockContext {
try (var geyserImplMock = mockStatic(GeyserImpl.class)) {
geyserImplMock.when(GeyserImpl::getInstance).thenReturn(geyserImpl);
// Since Geyser isn't actually loaded, the Registries#init will not be called.
// This means that we manually load the registries we want to use
Registries.ENTITY_DEFINITIONS.load();
Registries.JAVA_ENTITY_IDENTIFIERS.load();
Registries.BEDROCK_ENTITY_PROPERTIES.load();
geyserContext.accept(context);
}
}