mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 08:17:35 +00:00
Add in registry registration events, new subscription events you can use to make sure you're registering things at the "best" time.
This commit is contained in:
1 parent
1107088acb
commit
7a84376044
15 files changed
+266
-4
No files matched your search
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016.
|
||||
*
|
||||
* 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.fml.common.eventhandler.Event;
|
||||
|
||||
/**
|
||||
* Fired when the {@link net.minecraftforge.client.model.ModelLoader} is ready to receive registrations
|
||||
*/
|
||||
public class ModelRegistryEvent extends Event
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016.
|
||||
*
|
||||
* 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.event;
|
||||
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraftforge.fml.common.eventhandler.GenericEvent;
|
||||
import net.minecraftforge.fml.common.registry.IForgeRegistry;
|
||||
import net.minecraftforge.fml.common.registry.IForgeRegistryEntry;
|
||||
import net.minecraftforge.fml.common.registry.PersistentRegistryManager;
|
||||
|
||||
|
||||
/**
|
||||
* RegistryEvent supertype.
|
||||
*/
|
||||
public class RegistryEvent<T extends IForgeRegistryEntry<T>> extends GenericEvent<T>
|
||||
{
|
||||
RegistryEvent(Class<T> clazz) {
|
||||
super(clazz);
|
||||
}
|
||||
/**
|
||||
* Register new registries when you receive this event, through the {@link PersistentRegistryManager}
|
||||
*/
|
||||
public static class NewRegistry extends Event {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register your objects for the appropriate registry type when you receive this event.
|
||||
*
|
||||
* <code>event.getRegistry().register(...)</code>
|
||||
*
|
||||
* The registries will be visited in alphabetic order of their name, except blocks and items,
|
||||
* which will be visited FIRST and SECOND respectively.
|
||||
*
|
||||
* ObjectHolders will reload between Blocks and Items, and after all registries have been visited.
|
||||
* @param <T> The registry top level type
|
||||
*/
|
||||
public static class Register<T extends IForgeRegistryEntry<T>> extends RegistryEvent<T> {
|
||||
private final IForgeRegistry<T> registry;
|
||||
private final ResourceLocation location;
|
||||
|
||||
public Register(ResourceLocation location, IForgeRegistry<T> registry)
|
||||
{
|
||||
super(registry.getRegistrySuperType());
|
||||
this.location = location;
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
public IForgeRegistry<T> getRegistry()
|
||||
{
|
||||
return registry;
|
||||
}
|
||||
|
||||
public ResourceLocation getLocation()
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,9 @@ import net.minecraft.util.StringUtils;
|
||||
import net.minecraft.world.WorldSettings;
|
||||
import net.minecraft.world.storage.WorldSummary;
|
||||
import net.minecraft.world.storage.SaveFormatOld;
|
||||
import net.minecraftforge.client.event.ModelRegistryEvent;
|
||||
import net.minecraftforge.common.ForgeModContainer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraftforge.fml.common.DummyModContainer;
|
||||
import net.minecraftforge.fml.common.DuplicateModsFoundException;
|
||||
@@ -1038,4 +1040,10 @@ public class FMLClientHandler implements IFMLSidedHandler
|
||||
{
|
||||
this.client.renderGlobal.loadRenderers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireSidedRegistryEvents()
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new ModelRegistryEvent());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016.
|
||||
*
|
||||
* 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.common;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.fml.common.discovery.ASMDataTable;
|
||||
import net.minecraftforge.fml.common.discovery.asm.ModAnnotation;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Automatic eventbus subscriber - reads {@link net.minecraftforge.fml.common.Mod.EventBusSubscriber}
|
||||
* annotations and passes the class instances to the {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS}
|
||||
*/
|
||||
public class AutomaticEventSubscriber
|
||||
{
|
||||
private static final EnumSet<Side> DEFAULT = EnumSet.allOf(Side.class);
|
||||
public static void inject(ModContainer mod, ASMDataTable data, Side side)
|
||||
{
|
||||
FMLLog.fine("Attempting to inject @EventBusSubscriber classes into the eventbus for %s", mod.getModId());
|
||||
Set<ASMDataTable.ASMData> targets = data.getAnnotationsFor(mod).get(Mod.EventBusSubscriber.class.getName());
|
||||
ClassLoader mcl = Loader.instance().getModClassLoader();
|
||||
|
||||
for (ASMDataTable.ASMData targ : targets)
|
||||
{
|
||||
try
|
||||
{
|
||||
//noinspection unchecked
|
||||
List<ModAnnotation.EnumHolder> sidesEnum = (List<ModAnnotation.EnumHolder>)targ.getAnnotationInfo().get("value");
|
||||
EnumSet<Side> sides = DEFAULT;
|
||||
if (sidesEnum != null) {
|
||||
sides = EnumSet.noneOf(Side.class);
|
||||
for (ModAnnotation.EnumHolder h: sidesEnum) {
|
||||
sides.add(Side.valueOf(h.getValue()));
|
||||
}
|
||||
}
|
||||
if (sides == DEFAULT || sides.contains(side)) {
|
||||
FMLLog.fine("Found @EventBusSubscriber class %s", targ.getClassName());
|
||||
Class<?> subscriptionTarget = Class.forName(targ.getClassName(), true, mcl);
|
||||
MinecraftForge.EVENT_BUS.register(subscriptionTarget);
|
||||
FMLLog.fine("Injected @EventBusSubscriber class %s", targ.getClassName());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
FMLLog.log(Level.ERROR, e, "An error occurred trying to load an EventBusSubscriber %s for modid %s", targ.getClassName(), mod.getModId());
|
||||
throw new LoaderException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -746,4 +746,9 @@ public class FMLCommonHandler
|
||||
public void reloadRenderers() {
|
||||
sidedDelegate.reloadRenderers();
|
||||
}
|
||||
|
||||
public void fireSidedRegistryEvents()
|
||||
{
|
||||
sidedDelegate.fireSidedRegistryEvents();
|
||||
}
|
||||
}
|
||||
@@ -573,6 +573,8 @@ public class FMLModContainer implements ModContainer
|
||||
eventBus.post(new FMLFingerprintViolationEvent(source.isDirectory(), source, ImmutableSet.copyOf(this.sourceFingerprints), expectedFingerprint));
|
||||
}
|
||||
ProxyInjector.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide(), getLanguageAdapter());
|
||||
AutomaticEventSubscriber.inject(this, event.getASMHarvestedData(), FMLCommonHandler.instance().getSide());
|
||||
|
||||
processFieldAnnotations(event.getASMHarvestedData());
|
||||
}
|
||||
catch (Throwable e)
|
||||
|
||||
@@ -75,4 +75,6 @@ public interface IFMLSidedHandler
|
||||
String stripSpecialChars(String message);
|
||||
|
||||
void reloadRenderers();
|
||||
|
||||
void fireSidedRegistryEvents();
|
||||
}
|
||||
@@ -604,6 +604,8 @@ public class Loader
|
||||
ObjectHolderRegistry.INSTANCE.findObjectHolders(discoverer.getASMTable());
|
||||
ItemStackHolderInjector.INSTANCE.findHolders(discoverer.getASMTable());
|
||||
CapabilityManager.INSTANCE.injectCapabilities(discoverer.getASMTable());
|
||||
PersistentRegistryManager.fireRegistryEvents();
|
||||
FMLCommonHandler.instance().fireSidedRegistryEvents();
|
||||
modController.distributeStateMessage(LoaderState.PREINITIALIZATION, discoverer.getASMTable(), canonicalConfigDir);
|
||||
ObjectHolderRegistry.INSTANCE.applyObjectHolders();
|
||||
ItemStackHolderInjector.INSTANCE.inject();
|
||||
|
||||
@@ -39,6 +39,7 @@ import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLInterModComms.IMCEvent;
|
||||
import net.minecraftforge.fml.common.network.NetworkCheckHandler;
|
||||
import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
|
||||
/**
|
||||
* This defines a Mod to FML.
|
||||
@@ -305,4 +306,13 @@ public @interface Mod
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface InstanceFactory {
|
||||
}
|
||||
|
||||
/**
|
||||
* A class which will be subscribed to {@link net.minecraftforge.common.MinecraftForge.EVENT_BUS} at mod construction time.
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface EventBusSubscriber {
|
||||
Side[] value() default { Side.CLIENT, Side.SERVER };
|
||||
}
|
||||
}
|
||||
@@ -68,11 +68,9 @@ public class ASMEventHandler implements IEventListener
|
||||
if (isGeneric)
|
||||
{
|
||||
java.lang.reflect.Type type = method.getGenericParameterTypes()[0];
|
||||
System.currentTimeMillis();
|
||||
if (type instanceof ParameterizedType)
|
||||
{
|
||||
filter = ((ParameterizedType)type).getActualTypeArguments()[0];
|
||||
System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
@@ -36,6 +36,7 @@ import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.logging.log4j.Level;
|
||||
|
||||
@@ -830,6 +831,13 @@ public class FMLControlledNamespacedRegistry<I extends IForgeRegistryEntry<I>> e
|
||||
add(-1, key, value);
|
||||
}
|
||||
|
||||
public void registerAll(I... values)
|
||||
{
|
||||
for (I value: values)
|
||||
{
|
||||
register(value);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public boolean containsValue(I value)
|
||||
{
|
||||
@@ -908,4 +916,10 @@ public class FMLControlledNamespacedRegistry<I extends IForgeRegistryEntry<I>> e
|
||||
{
|
||||
return (T)slaves.get(slaveMapName);
|
||||
}
|
||||
|
||||
RegistryEvent.Register<I> buildRegistryRegisterEvent(ResourceLocation location)
|
||||
{
|
||||
return new RegistryEvent.Register<I>(location, this);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,8 @@ public interface IForgeRegistry<V extends IForgeRegistryEntry<V>> extends Iterab
|
||||
|
||||
void register(V value);
|
||||
|
||||
void registerAll(V... values);
|
||||
|
||||
boolean containsKey(ResourceLocation key);
|
||||
boolean containsValue(V value);
|
||||
|
||||
|
||||
@@ -89,7 +89,6 @@ public interface IForgeRegistryEntry<V>
|
||||
//Helper functions
|
||||
public final T setRegistryName(ResourceLocation name){ return setRegistryName(name.toString()); }
|
||||
public final T setRegistryName(String modID, String name){ return setRegistryName(modID + ":" + name); }
|
||||
|
||||
public final ResourceLocation getRegistryName()
|
||||
{
|
||||
if (delegate.name() != null) return delegate.name();
|
||||
|
||||
+33
-1
@@ -20,8 +20,9 @@
|
||||
package net.minecraftforge.fml.common.registry;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -33,6 +34,8 @@ import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockAir;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.RegistryEvent;
|
||||
import net.minecraftforge.fml.common.EnhancedRuntimeException;
|
||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.FMLLog;
|
||||
@@ -64,6 +67,35 @@ import com.google.common.collect.Sets.SetView;
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class PersistentRegistryManager
|
||||
{
|
||||
public static void fireRegistryEvents()
|
||||
{
|
||||
MinecraftForge.EVENT_BUS.post(new RegistryEvent.NewRegistry());
|
||||
|
||||
List<ResourceLocation> registryKeys = Lists.newArrayList(PersistentRegistry.ACTIVE.registries.keySet());
|
||||
Collections.sort(registryKeys, new Comparator<ResourceLocation>()
|
||||
{
|
||||
@Override
|
||||
public int compare(ResourceLocation o1, ResourceLocation o2)
|
||||
{
|
||||
return o1.toString().compareToIgnoreCase(o2.toString());
|
||||
}
|
||||
});
|
||||
fireRegistryEvent(PersistentRegistry.ACTIVE.registries, BLOCKS);
|
||||
ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any blocks
|
||||
fireRegistryEvent(PersistentRegistry.ACTIVE.registries, ITEMS);
|
||||
ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject any items
|
||||
for (ResourceLocation rl : registryKeys) {
|
||||
if (rl == BLOCKS || rl == ITEMS) continue;
|
||||
fireRegistryEvent(PersistentRegistry.ACTIVE.registries, rl);
|
||||
}
|
||||
ObjectHolderRegistry.INSTANCE.applyObjectHolders(); // inject everything else
|
||||
}
|
||||
private static void fireRegistryEvent(BiMap<ResourceLocation, FMLControlledNamespacedRegistry<?>> registries, ResourceLocation name)
|
||||
{
|
||||
final RegistryEvent.Register<?> event = registries.get(name).buildRegistryRegisterEvent(name);
|
||||
MinecraftForge.EVENT_BUS.post(event);
|
||||
}
|
||||
|
||||
enum PersistentRegistry
|
||||
{
|
||||
ACTIVE, VANILLA, FROZEN, STAGING;
|
||||
|
||||
@@ -332,6 +332,11 @@ public class FMLServerHandler implements IFMLSidedHandler
|
||||
@Override
|
||||
public void reloadRenderers() {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fireSidedRegistryEvents()
|
||||
{
|
||||
// NOOP
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user