Add new DeferredRegistry helper, and change RegistryObject to update when overrides are registered.
This commit is contained in:
parent
9183c2fa0d
commit
281ef5a152
8 changed files with 214 additions and 67 deletions
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.client.event;
|
||||
|
||||
import net.minecraftforge.eventbus.api.Event;
|
||||
|
|
|
@ -29,10 +29,7 @@ import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
|||
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import net.minecraftforge.server.command.ConfigCommand;
|
||||
import net.minecraftforge.server.command.EnumArgument;
|
||||
import net.minecraftforge.server.command.ForgeArguments;
|
||||
import net.minecraftforge.server.command.ForgeCommand;
|
||||
import net.minecraftforge.server.command.ModIdArgument;
|
||||
import net.minecraftforge.versions.forge.ForgeVersion;
|
||||
import net.minecraftforge.versions.mcp.MCPVersion;
|
||||
|
||||
|
@ -40,8 +37,6 @@ import org.apache.commons.lang3.tuple.Pair;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.command.arguments.ArgumentSerializer;
|
||||
import net.minecraft.command.arguments.ArgumentTypes;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.item.crafting.IRecipe;
|
||||
import net.minecraft.item.crafting.IRecipeSerializer;
|
||||
|
@ -68,7 +63,6 @@ import net.minecraftforge.common.data.ForgeRecipeProvider;
|
|||
import net.minecraftforge.common.model.animation.CapabilityAnimation;
|
||||
import net.minecraftforge.energy.CapabilityEnergy;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.fml.event.lifecycle.GatherDataEvent;
|
||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
import net.minecraftforge.items.CapabilityItemHandler;
|
||||
|
@ -134,7 +128,13 @@ public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook
|
|||
VersionChecker.startVersionCheck();
|
||||
}
|
||||
|
||||
ForgeArguments.register();
|
||||
/*
|
||||
* We can't actually add any of these, because vanilla clients will choke on unknown argument types
|
||||
* So our custom arguments will not validate client-side, but they do still work
|
||||
ArgumentTypes.register("forge:enum", EnumArgument.class, new EnumArgument.Serializer());
|
||||
ArgumentTypes.register("forge:modid", ModIdArgument.class, new ArgumentSerializer<>(ModIdArgument::modIdArgument));
|
||||
ArgumentTypes.register("forge:structure_type", StructureArgument.class, new ArgumentSerializer<>(StructureArgument::structure));
|
||||
*/
|
||||
}
|
||||
|
||||
public void serverStarting(FMLServerStartingEvent evt)
|
||||
|
|
|
@ -21,7 +21,8 @@ package net.minecraftforge.fml;
|
|||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.registries.IForgeRegistry;
|
||||
import net.minecraftforge.registries.ForgeRegistryEntry;
|
||||
import net.minecraftforge.registries.IForgeRegistryEntry;
|
||||
import net.minecraftforge.registries.ObjectHolderRegistry;
|
||||
import net.minecraftforge.registries.RegistryManager;
|
||||
|
||||
import java.util.Objects;
|
||||
|
@ -32,69 +33,76 @@ import java.util.function.Predicate;
|
|||
import java.util.function.Supplier;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
||||
{
|
||||
private final String name;
|
||||
private final IForgeRegistry<?> owningRegistry;
|
||||
private T value;
|
||||
private boolean searched;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public static <T extends ForgeRegistryEntry<T>, U extends T> RegistryObject<U> of(final String name, Supplier<Class<? super T>> registryType) {
|
||||
public final class RegistryObject<T extends IForgeRegistryEntry<? super T>>
|
||||
{
|
||||
private final ResourceLocation name;
|
||||
@Nullable
|
||||
private T value;
|
||||
|
||||
public static <T extends IForgeRegistryEntry<T>, U extends T> RegistryObject<U> of(final String name, Supplier<Class<? super T>> registryType) {
|
||||
return new RegistryObject<>(name, registryType);
|
||||
}
|
||||
|
||||
public static <T extends IForgeRegistryEntry<T>, U extends T> RegistryObject<U> of(final String name, IForgeRegistry<T> registry) {
|
||||
return new RegistryObject<>(name, registry);
|
||||
}
|
||||
|
||||
private static RegistryObject<?> EMPTY = new RegistryObject<>();
|
||||
|
||||
private static <T extends ForgeRegistryEntry<? super T>> RegistryObject<T> empty() {
|
||||
private static <T extends IForgeRegistryEntry<? super T>> RegistryObject<T> empty() {
|
||||
@SuppressWarnings("unchecked")
|
||||
RegistryObject<T> t = (RegistryObject<T>) EMPTY;
|
||||
return t;
|
||||
}
|
||||
|
||||
private RegistryObject() {
|
||||
this.searched = true;
|
||||
this.name = "";
|
||||
this.owningRegistry = null;
|
||||
this.name = null;
|
||||
}
|
||||
|
||||
private <V extends ForgeRegistryEntry<V>> RegistryObject(String name, Supplier<Class<? super V>> registryType)
|
||||
private <V extends IForgeRegistryEntry<V>> RegistryObject(String name, Supplier<Class<? super V>> registryType)
|
||||
{
|
||||
this.name = name;
|
||||
IForgeRegistry<V> registry;
|
||||
try {
|
||||
registry = RegistryManager.ACTIVE.<V>getRegistry(registryType.get());
|
||||
} catch (Throwable t) {
|
||||
registry = null;
|
||||
}
|
||||
this.owningRegistry = registry;
|
||||
this(name, RegistryManager.ACTIVE.<V>getRegistry(registryType.get()));
|
||||
}
|
||||
|
||||
private T getValue()
|
||||
@SuppressWarnings("unchecked")
|
||||
private <V extends IForgeRegistryEntry<V>> RegistryObject(String name, IForgeRegistry<V> registry)
|
||||
{
|
||||
if (registry == null)
|
||||
throw new IllegalArgumentException("Invalid registry argument, must not be null");
|
||||
this.name = new ResourceLocation(name);
|
||||
ObjectHolderRegistry.addHandler(pred ->
|
||||
{
|
||||
if (pred.test(registry.getRegistryName()))
|
||||
this.value = registry.containsKey(this.name) ? (T)registry.getValue(this.name) : null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Directly retrieves the wrapped Registry Object. This value will automatically be updated when the backing registry is updated.
|
||||
*/
|
||||
@Nullable
|
||||
public T get()
|
||||
{
|
||||
if (!searched) {
|
||||
if (this.owningRegistry != null) {
|
||||
//noinspection unchecked
|
||||
this.value = (T)this.owningRegistry.getValue(new ResourceLocation(this.name));
|
||||
}
|
||||
searched = true;
|
||||
}
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
return this.name.toString();
|
||||
}
|
||||
|
||||
public Stream<T> stream() {
|
||||
return isPresent() ? Stream.of(getValue()) : Stream.of();
|
||||
return isPresent() ? Stream.of(get()) : Stream.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return {@code true} if there is a mod object present, otherwise {@code false}.
|
||||
*
|
||||
* @return {@code true} if there is a mod object present, otherwise {@code false}
|
||||
*/
|
||||
public boolean isPresent() {
|
||||
return getValue() != null;
|
||||
return get() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,8 +114,8 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
* null
|
||||
*/
|
||||
public void ifPresent(Consumer<? super T> consumer) {
|
||||
if (getValue() != null)
|
||||
consumer.accept(getValue());
|
||||
if (get() != null)
|
||||
consumer.accept(get());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -126,7 +134,7 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
if (!isPresent())
|
||||
return this;
|
||||
else
|
||||
return predicate.test(getValue()) ? this : empty();
|
||||
return predicate.test(get()) ? this : empty();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -149,7 +157,7 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
if (!isPresent())
|
||||
return Optional.empty();
|
||||
else {
|
||||
return Optional.ofNullable(mapper.apply(getValue()));
|
||||
return Optional.ofNullable(mapper.apply(get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +183,7 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
if (!isPresent())
|
||||
return Optional.empty();
|
||||
else {
|
||||
return Objects.requireNonNull(mapper.apply(getValue()));
|
||||
return Objects.requireNonNull(mapper.apply(get()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,7 +195,7 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
* @return the mod object, if present, otherwise {@code other}
|
||||
*/
|
||||
public T orElse(T other) {
|
||||
return getValue() != null ? getValue() : other;
|
||||
return get() != null ? get() : other;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,7 +209,7 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
* null
|
||||
*/
|
||||
public T orElseGet(Supplier<? extends T> other) {
|
||||
return getValue() != null ? getValue() : other.get();
|
||||
return get() != null ? get() : other.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,8 +229,8 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
* {@code exceptionSupplier} is null
|
||||
*/
|
||||
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
|
||||
if (getValue() != null) {
|
||||
return getValue();
|
||||
if (get() != null) {
|
||||
return get();
|
||||
} else {
|
||||
throw exceptionSupplier.get();
|
||||
}
|
||||
|
@ -233,7 +241,7 @@ public final class RegistryObject<T extends ForgeRegistryEntry<? super T>>
|
|||
{
|
||||
if (this == obj) return true;
|
||||
if (obj instanceof RegistryObject) {
|
||||
return Objects.equals(((RegistryObject)obj).name, name);
|
||||
return Objects.equals(((RegistryObject<?>)obj).name, name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.fml.network;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2019.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.registries;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.RegistryObject;
|
||||
|
||||
/**
|
||||
* Utility class to help with managing registry entries.
|
||||
* Maintains a list of all suppliers for entries and registers them during the proper Register event.
|
||||
* Suppliers should return NEW instances every time.
|
||||
*
|
||||
*Example Usage:
|
||||
*<pre>
|
||||
* private static final DeferredRegister<Item> ITEMS = new DeferredRegister<>(ForgeRegistries.ITEMS, MODID);
|
||||
* private static final DeferredRegister<Block> BLOCKS = new DeferredRegister<>(ForgeRegistries.BLOCKS, MODID);
|
||||
*
|
||||
* public static final RegistryObject<Block> ROCK_BLOCK = BLOCKS.register("rock", () -> new Block(Block.Properties.create(Material.ROCK)));
|
||||
* public static final RegistryObject<Item> ROCK_ITEM = ITEMS.register("rock", () -> new BlockItem(ROCK_BLOCK.get(), new Item.Properties().group(ItemGroup.MISC)));
|
||||
*
|
||||
* public ExampleMod() {
|
||||
* ITEMS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
* BLOCKS.register(FMLJavaModLoadingContext.get().getModEventBus());
|
||||
* }
|
||||
*</pre>
|
||||
*
|
||||
* @param <T> The base registry type, must be a concrete base class, do not use subclasses or wild cards.
|
||||
*/
|
||||
public class DeferredRegister<T extends IForgeRegistryEntry<T>>
|
||||
{
|
||||
private final IForgeRegistry<T> type;
|
||||
private final String modid;
|
||||
private List<Supplier<? extends T>> entries = new ArrayList<>();
|
||||
|
||||
public DeferredRegister(IForgeRegistry<T> reg, String modid)
|
||||
{
|
||||
this.type = reg;
|
||||
this.modid = modid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new supplier to the list of entries to be registered, and returns a RegistryObject that will be populated with the created entry automatically.
|
||||
*
|
||||
* @param name The new entry's name, it will automatically have the modid prefixed.
|
||||
* @param sup A factory for the new entry, it should return a new instance every time it is called.
|
||||
* @return A RegistryObject that will be updated with when the entries in the registry change.
|
||||
*/
|
||||
public <I extends T> RegistryObject<I> register(final String name, final Supplier<I> sup)
|
||||
{
|
||||
final ResourceLocation key = new ResourceLocation(modid, name);
|
||||
entries.add(() -> sup.get().setRegistryName(key));
|
||||
return RegistryObject.of(key.toString(), this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds our event handler to the specified event bus, this MUST be called in order for this class to function.
|
||||
* See the example usage.
|
||||
*
|
||||
* @param bus The Mod Specific event bus.
|
||||
*/
|
||||
public void register(IEventBus bus)
|
||||
{
|
||||
bus.addListener(this::addEntries);
|
||||
}
|
||||
|
||||
private void addEntries(RegistryEvent.Register<?> event)
|
||||
{
|
||||
if (event.getGenericType() == this.type.getRegistrySuperType())
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
IForgeRegistry<T> reg = (IForgeRegistry<T>)event.getRegistry();
|
||||
entries.stream().map(Supplier::get).forEach(reg::register);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package net.minecraftforge.registries;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
@ -85,7 +84,7 @@ public class RegistryManager
|
|||
{
|
||||
return this.registries.inverse().get(reg);
|
||||
}
|
||||
|
||||
|
||||
public <V extends IForgeRegistryEntry<V>> ResourceLocation updateLegacyName(ResourceLocation legacyName)
|
||||
{
|
||||
while (getRegistry(legacyName) == null)
|
||||
|
@ -142,7 +141,7 @@ public class RegistryManager
|
|||
addLegacyName(legacyName, name);
|
||||
return getRegistry(name);
|
||||
}
|
||||
|
||||
|
||||
private void addLegacyName(ResourceLocation legacyName, ResourceLocation name)
|
||||
{
|
||||
if (this.legacyNames.containsKey(legacyName))
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
package net.minecraftforge.server.command;
|
||||
|
||||
public class ForgeArguments
|
||||
{
|
||||
public static void register()
|
||||
{
|
||||
/*
|
||||
* We can't actually add any of these, because vanilla clients will choke on unknown argument types
|
||||
* So our custom arguments will not validate client-side, but they do still work
|
||||
ArgumentTypes.register("forge:enum", EnumArgument.class, new EnumArgument.Serializer());
|
||||
ArgumentTypes.register("forge:modid", ModIdArgument.class, new ArgumentSerializer<>(ModIdArgument::modIdArgument));
|
||||
ArgumentTypes.register("forge:structure_type", StructureArgument.class, new ArgumentSerializer<>(StructureArgument::structure));
|
||||
*/
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue