@Subscribe public void handleModStateEvent(FMLEvent event) { if (!eventMethods.containsKey(event.getClass())) { return; } try { for (Method m : eventMethods.get(event.getClass())) { m.invoke(modInstance, event); } } catch (Throwable t) { controller.errorOccurred(this, t); } }
@Subscribe public void propogateStateMessage(FMLEvent stateEvent) { if (stateEvent instanceof FMLPreInitializationEvent) { modObjectList = buildModObjectList(); } ProgressBar bar = ProgressManager.push(stateEvent.description(), activeModList.size(), true); for (ModContainer mc : activeModList) { bar.step(mc.getName()); sendEventToModContainer(stateEvent, mc); } ProgressManager.pop(bar); }
private void sendEventToModContainer(FMLEvent stateEvent, ModContainer mc) { String modId = mc.getModId(); Collection<String> requirements = Collections2.transform(mc.getRequirements(),new ArtifactVersionNameFunction()); for (ArtifactVersion av : mc.getDependencies()) { if (av.getLabel()!= null && requirements.contains(av.getLabel()) && modStates.containsEntry(av.getLabel(),ModState.ERRORED)) { FMLLog.log(modId, Level.ERROR, "Skipping event %s and marking errored mod %s since required dependency %s has errored", stateEvent.getEventType(), modId, av.getLabel()); modStates.put(modId, ModState.ERRORED); return; } } activeContainer = mc; stateEvent.applyModContainer(activeContainer()); ThreadContext.put("mod", modId); FMLLog.log(modId, Level.TRACE, "Sending event %s to mod %s", stateEvent.getEventType(), modId); eventChannels.get(modId).post(stateEvent); FMLLog.log(modId, Level.TRACE, "Sent event %s to mod %s", stateEvent.getEventType(), modId); ThreadContext.remove("mod"); activeContainer = null; if (stateEvent instanceof FMLStateEvent) { if (!errors.containsKey(modId)) { modStates.put(modId, ((FMLStateEvent)stateEvent).getModState()); } else { modStates.put(modId, ModState.ERRORED); } } }
@SuppressWarnings("unchecked") private Method gatherAnnotations(Class<?> clazz) throws Exception { Method factoryMethod = null; for (Method m : clazz.getDeclaredMethods()) { for (Annotation a : m.getAnnotations()) { if (a.annotationType().equals(Mod.EventHandler.class)) { if (m.getParameterTypes().length == 1 && FMLEvent.class.isAssignableFrom(m.getParameterTypes()[0])) { m.setAccessible(true); eventMethods.put((Class<? extends FMLEvent>)m.getParameterTypes()[0], m); } else { FMLLog.log(getModId(), Level.ERROR, "The mod %s appears to have an invalid event annotation %s. This annotation can only apply to methods with recognized event arguments - it will not be called", getModId(), a.annotationType().getSimpleName()); } } else if (a.annotationType().equals(Mod.InstanceFactory.class)) { if (Modifier.isStatic(m.getModifiers()) && m.getParameterTypes().length == 0 && factoryMethod == null) { m.setAccessible(true); factoryMethod = m; } else if (!(Modifier.isStatic(m.getModifiers()) && m.getParameterTypes().length == 0)) { FMLLog.log(getModId(), Level.ERROR, "The InstanceFactory annotation can only apply to a static method, taking zero arguments - it will be ignored on %s(%s)", m.getName(), Arrays.asList(m.getParameterTypes())); } else if (factoryMethod != null) { FMLLog.log(getModId(), Level.ERROR, "The InstanceFactory annotation can only be used once, the application to %s(%s) will be ignored", m.getName(), Arrays.asList(m.getParameterTypes())); } } } } return factoryMethod; }
@SuppressWarnings("unchecked") private static void addModEventHandlerMethods(FMLModContainer modContainer) { ListMultimap<Class<? extends FMLEvent>, Method> methodMap = getModEventMap(modContainer); for(Method method : METHODS) { Class<? extends FMLEvent> paramClass = (Class<? extends FMLEvent>) method.getParameterTypes()[0]; methodMap.put(paramClass, method); } }
@SuppressWarnings("unchecked") private static ListMultimap<Class<? extends FMLEvent>, Method> getModEventMap(FMLModContainer modContainer) { try { return (ListMultimap<Class<? extends FMLEvent>, Method>) FIELD.get(modContainer); } catch(Exception e) { e.printStackTrace(); //Should not ever happen throw new RuntimeException("CAUGHT ERROR WHEN TRYING TO RETRIEVE FMLMODCONTAINER EVENT METHODS MAP"); } }
private static List<Method> getMethods() { List<Method> foundMethods = new ArrayList<>(); for(Method method : InfinityMod.class.getDeclaredMethods()) { for(Annotation a : method.getAnnotations()) { if(a.annotationType().equals(Mod.EventHandler.class)) { if(method.getParameterTypes().length == 1 && FMLEvent.class.isAssignableFrom(method.getParameterTypes()[0])) { method.setAccessible(true); foundMethods.add(method); } } } } return ImmutableList.copyOf(foundMethods); }