From 3f491fa7cb16cb9d28abf0c5064200bf893c7fcc Mon Sep 17 00:00:00 2001 From: Christian Date: Mon, 30 Jul 2012 00:33:21 -0400 Subject: [PATCH] Add in events for the method pre/init/post annotations so we can add in extra data during the event phase --- .../cpw/mods/fml/common/FMLModContainer.java | 52 +++++++++++++------ .../cpw/mods/fml/common/LoadController.java | 19 +++---- common/cpw/mods/fml/common/Loader.java | 2 + common/cpw/mods/fml/common/LoaderState.java | 1 + common/cpw/mods/fml/common/Mod.java | 16 ++++-- .../{ => event}/FMLLoadCompleteEvent.java | 4 +- .../event/FMLPreInitializationEvent.java | 25 ++++++++- .../mods/fml/common/event/FMLStateEvent.java | 8 ++- .../src/cpw/mods/mockmod/MockMod.java | 18 +++++-- 9 files changed, 108 insertions(+), 37 deletions(-) rename common/cpw/mods/fml/common/{ => event}/FMLLoadCompleteEvent.java (79%) diff --git a/common/cpw/mods/fml/common/FMLModContainer.java b/common/cpw/mods/fml/common/FMLModContainer.java index fbc38753dd..3f574cb13f 100644 --- a/common/cpw/mods/fml/common/FMLModContainer.java +++ b/common/cpw/mods/fml/common/FMLModContainer.java @@ -17,6 +17,7 @@ import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -98,12 +99,12 @@ public class FMLModContainer implements ModContainer public void bindMetadata(MetadataCollection mc) { modMetadata = mc.getMetadataForId(getModId(), descriptor); - + if (descriptor.containsKey("usesMetadata")) { - overridesMetadata = !((Boolean)descriptor.get("usesMetadata")).booleanValue(); + overridesMetadata = !((Boolean)descriptor.get("usesMetadata")).booleanValue(); } - + if (overridesMetadata || !modMetadata.useDependencyInformation) { List requirements = Lists.newArrayList(); @@ -181,11 +182,11 @@ public class FMLModContainer implements ModContainer return false; } } - + private Multimap, Object> gatherAnnotations(Class clazz) throws Exception { Multimap,Object> anns = ArrayListMultimap.create(); - + for (Field f : clazz.getDeclaredFields()) { for (Annotation a : f.getAnnotations()) @@ -194,19 +195,36 @@ public class FMLModContainer implements ModContainer anns.put(a.annotationType(), f); } } - + for (Method m : clazz.getDeclaredMethods()) { for (Annotation a : m.getAnnotations()) { - if (m.getParameterTypes().length==0) + Class[] paramTypes; + if (a.annotationType() == Mod.PreInit.class) + { + paramTypes = Mod.PreInit.paramTypes; + } + else if (a.annotationType() == Mod.Init.class) + { + paramTypes = Mod.Init.paramTypes; + } + else if (a.annotationType() == Mod.PostInit.class) + { + paramTypes = Mod.PostInit.paramTypes; + } + else + { + continue; + } + if (Arrays.equals(m.getParameterTypes(), paramTypes)) { m.setAccessible(true); anns.put(a.annotationType(), m); } else { - FMLLog.severe("The mod type %s appears to have an invalid method annotation %s. This annotation can only apply to zero argument methods", getModId(), a.annotationType().getSimpleName()); + FMLLog.severe("The mod %s appears to have an invalid method annotation %s. This annotation can only apply to methods with argument types %s -it will not be called", getModId(), a.annotationType().getSimpleName(), Arrays.toString(paramTypes)); } } } @@ -221,13 +239,13 @@ public class FMLModContainer implements ModContainer Field f = (Field) o; f.set(modInstance, modInstance); } - + for (Object o : annotations.get(Metadata.class)) { Field f = (Field) o; f.set(modInstance, modMetadata); } - + for (Object o : annotations.get(Block.class)) { Field f = (Field) o; @@ -238,7 +256,7 @@ public class FMLModContainer implements ModContainer @Subscribe public void constructMod(FMLConstructionEvent event) { - try + try { ModClassLoader modClassLoader = event.getModClassLoader(); modClassLoader.addFile(source); @@ -253,7 +271,7 @@ public class FMLModContainer implements ModContainer Throwables.propagateIfPossible(e); } } - + @Subscribe public void preInitMod(FMLPreInitializationEvent event) { @@ -262,7 +280,7 @@ public class FMLModContainer implements ModContainer for (Object o : annotations.get(Mod.PreInit.class)) { Method m = (Method) o; - m.invoke(modInstance); + m.invoke(modInstance, event); } } catch (Throwable t) @@ -271,7 +289,7 @@ public class FMLModContainer implements ModContainer Throwables.propagateIfPossible(t); } } - + @Subscribe public void initMod(FMLInitializationEvent event) { @@ -280,7 +298,7 @@ public class FMLModContainer implements ModContainer for (Object o : annotations.get(Mod.Init.class)) { Method m = (Method) o; - m.invoke(modInstance); + m.invoke(modInstance, event); } } catch (Throwable t) @@ -289,7 +307,7 @@ public class FMLModContainer implements ModContainer Throwables.propagateIfPossible(t); } } - + @Subscribe public void postInitMod(FMLPostInitializationEvent event) { @@ -298,7 +316,7 @@ public class FMLModContainer implements ModContainer for (Object o : annotations.get(Mod.PostInit.class)) { Method m = (Method) o; - m.invoke(modInstance); + m.invoke(modInstance, event); } } catch (Throwable t) diff --git a/common/cpw/mods/fml/common/LoadController.java b/common/cpw/mods/fml/common/LoadController.java index 2ca8bc42de..e822512dd0 100644 --- a/common/cpw/mods/fml/common/LoadController.java +++ b/common/cpw/mods/fml/common/LoadController.java @@ -30,16 +30,16 @@ public class LoadController private Map modList; private List activeModList = Lists.newArrayList(); private String activeContainer; - + public LoadController(Loader loader) { this.loader = loader; this.modList = loader.getIndexedModList(); this.masterChannel = new EventBus("FMLMainChannel"); this.masterChannel.register(this); - + Builder eventBus = ImmutableMap.builder(); - + for (ModContainer mod : loader.getModList()) { EventBus bus = new EventBus(mod.getModId()); @@ -58,9 +58,9 @@ public class LoadController modStates.put(mod.getModId(), ModState.DISABLED); } } - + eventChannels = eventBus.build(); - + state = LoaderState.CONSTRUCTING; } @@ -70,13 +70,13 @@ public class LoadController { throw new LoaderException(); } - + if (state.hasEvent()) { masterChannel.post(state.getEvent(eventData)); } } - + public void transition(LoaderState desiredState) { LoaderState oldState = state; @@ -92,12 +92,12 @@ public class LoadController { FMLLog.log(Level.SEVERE, error.getValue(), "Caught exception from %s", error.getKey()); } - + // Throw embedding the first error (usually the only one) throw new LoaderException(errors.values().iterator().next()); } } - + public ModContainer activeContainer() { return activeContainer!=null ? modList.get(activeContainer) : null; @@ -108,6 +108,7 @@ public class LoadController for (Map.Entry entry : eventChannels.entrySet()) { activeContainer = entry.getKey(); + stateEvent.applyModContainer(activeContainer()); entry.getValue().post(stateEvent); activeContainer = null; if (!errors.containsKey(entry.getKey())) diff --git a/common/cpw/mods/fml/common/Loader.java b/common/cpw/mods/fml/common/Loader.java index a8586dbff8..f0b961457f 100644 --- a/common/cpw/mods/fml/common/Loader.java +++ b/common/cpw/mods/fml/common/Loader.java @@ -345,8 +345,10 @@ public class Loader sortModList(); mods = ImmutableList.copyOf(mods); modController = new LoadController(this); + // Mod controller state : CONSTRUCTION modController.distributeStateMessage(modClassLoader); modController.transition(LoaderState.PREINITIALIZATION); + // Mod controller state : PREINITIALIZATION modController.distributeStateMessage(); modController.transition(LoaderState.INITIALIZATION); } diff --git a/common/cpw/mods/fml/common/LoaderState.java b/common/cpw/mods/fml/common/LoaderState.java index 8e50853a28..9301ab9637 100644 --- a/common/cpw/mods/fml/common/LoaderState.java +++ b/common/cpw/mods/fml/common/LoaderState.java @@ -4,6 +4,7 @@ import com.google.common.base.Throwables; import cpw.mods.fml.common.event.FMLConstructionEvent; import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLLoadCompleteEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.event.FMLStateEvent; diff --git a/common/cpw/mods/fml/common/Mod.java b/common/cpw/mods/fml/common/Mod.java index 5d03b3d65b..237934e60a 100644 --- a/common/cpw/mods/fml/common/Mod.java +++ b/common/cpw/mods/fml/common/Mod.java @@ -18,6 +18,10 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; + import net.minecraft.src.ItemBlock; /** @@ -64,7 +68,9 @@ public @interface Mod */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - public @interface PreInit {} + public @interface PreInit { + static Class[] paramTypes = new Class[] { FMLPreInitializationEvent.class }; + } /** * Mark the designated method as being called at the "initialization" phase * @author cpw @@ -72,7 +78,9 @@ public @interface Mod */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - public @interface Init {} + public @interface Init { + static Class[] paramTypes = new Class[] { FMLInitializationEvent.class }; + } /** * Mark the designated method as being called at the "post-initialization" phase * @author cpw @@ -80,7 +88,9 @@ public @interface Mod */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - public @interface PostInit {} + public @interface PostInit { + static Class[] paramTypes = new Class[] { FMLPostInitializationEvent.class }; + } /** * Populate the annotated field with the mod instance. * @author cpw diff --git a/common/cpw/mods/fml/common/FMLLoadCompleteEvent.java b/common/cpw/mods/fml/common/event/FMLLoadCompleteEvent.java similarity index 79% rename from common/cpw/mods/fml/common/FMLLoadCompleteEvent.java rename to common/cpw/mods/fml/common/event/FMLLoadCompleteEvent.java index 0a50164c51..c615bfaefe 100644 --- a/common/cpw/mods/fml/common/FMLLoadCompleteEvent.java +++ b/common/cpw/mods/fml/common/event/FMLLoadCompleteEvent.java @@ -1,7 +1,7 @@ -package cpw.mods.fml.common; +package cpw.mods.fml.common.event; +import cpw.mods.fml.common.LoaderState; import cpw.mods.fml.common.LoaderState.ModState; -import cpw.mods.fml.common.event.FMLStateEvent; public class FMLLoadCompleteEvent extends FMLStateEvent { diff --git a/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java b/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java index 6e1556a4f7..17570ee7fd 100644 --- a/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java +++ b/common/cpw/mods/fml/common/event/FMLPreInitializationEvent.java @@ -1,20 +1,43 @@ package cpw.mods.fml.common.event; +import java.io.File; + import com.google.common.eventbus.EventBus; import cpw.mods.fml.common.LoaderState.ModState; +import cpw.mods.fml.common.ModContainer; +import cpw.mods.fml.common.ModMetadata; public class FMLPreInitializationEvent extends FMLStateEvent { + private ModMetadata modMetadata; + private File sourceFile; + public FMLPreInitializationEvent(Object... data) { super(data); } - + @Override public ModState getModState() { return ModState.PREINITIALIZED; } + @Override + public void applyModContainer(ModContainer activeContainer) + { + this.modMetadata = activeContainer.getMetadata(); + this.sourceFile = activeContainer.getSource(); + } + + public File getSourceFile() + { + return sourceFile; + } + + public ModMetadata getModMetadata() + { + return modMetadata; + } } diff --git a/common/cpw/mods/fml/common/event/FMLStateEvent.java b/common/cpw/mods/fml/common/event/FMLStateEvent.java index 65b27d4232..e178e11872 100644 --- a/common/cpw/mods/fml/common/event/FMLStateEvent.java +++ b/common/cpw/mods/fml/common/event/FMLStateEvent.java @@ -1,13 +1,19 @@ package cpw.mods.fml.common.event; import cpw.mods.fml.common.LoaderState.ModState; +import cpw.mods.fml.common.ModContainer; public abstract class FMLStateEvent extends FMLEvent { public FMLStateEvent(Object... data) { - + } public abstract ModState getModState(); + + public void applyModContainer(ModContainer activeContainer) + { + // NO OP + } } diff --git a/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java b/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java index f90a5ed0a3..a8164b7dab 100644 --- a/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java +++ b/eclipse/FML-MockMod/src/cpw/mods/mockmod/MockMod.java @@ -6,6 +6,9 @@ import cpw.mods.fml.common.Mod.Block; import cpw.mods.fml.common.Mod.Init; import cpw.mods.fml.common.Mod.Instance; import cpw.mods.fml.common.Mod.Metadata; +import cpw.mods.fml.common.Mod.PreInit; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.ModMetadata; @Mod(modid="MockMod", name="Mock Mod",version="1.2.3", dependencies="before:mod_testMod", useMetadata=true) @@ -23,15 +26,22 @@ public class MockMod @Instance public static MockMod myInstance; - + @Metadata private ModMetadata meta; - + @Block(name="MyBlock", itemTypeClass=TestItem.class) private MockBlock myBlock; - + + @PreInit + public void preinit(FMLPreInitializationEvent evt) + { + System.out.printf("Hello from mockmod preinit %s\n", evt.getSourceFile()); + evt.getModMetadata().description="Fishy fish head"; + evt.getModMetadata().autogenerated = false; + } @Init - public void init() + public void init(FMLInitializationEvent evt) { System.out.printf("Hello from mockmod init : %s %s\n", myInstance, meta); }