Simple InterMod comms. Send a message using FMLInterModComms.sendMessage(). Receive messages through an @IMCCallback
This commit is contained in:
parent
39d6ef64c2
commit
a72f6b1eff
8 changed files with 154 additions and 22 deletions
|
@ -46,7 +46,9 @@ import cpw.mods.fml.common.Mod.Metadata;
|
|||
import cpw.mods.fml.common.discovery.ASMDataTable;
|
||||
import cpw.mods.fml.common.discovery.ASMDataTable.ASMData;
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLEvent;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms.IMCEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartedEvent;
|
||||
|
@ -76,15 +78,16 @@ public class FMLModContainer implements ModContainer
|
|||
private DefaultArtifactVersion processedVersion;
|
||||
private boolean isNetworkMod;
|
||||
|
||||
private static final BiMap<Class<? extends FMLStateEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLStateEvent>, Class<? extends Annotation>>builder()
|
||||
private static final BiMap<Class<? extends FMLEvent>, Class<? extends Annotation>> modAnnotationTypes = ImmutableBiMap.<Class<? extends FMLEvent>, Class<? extends Annotation>>builder()
|
||||
.put(FMLPreInitializationEvent.class, Mod.PreInit.class)
|
||||
.put(FMLInitializationEvent.class, Mod.Init.class)
|
||||
.put(FMLPostInitializationEvent.class, Mod.PostInit.class)
|
||||
.put(FMLServerStartingEvent.class, Mod.ServerStarting.class)
|
||||
.put(FMLServerStartedEvent.class, Mod.ServerStarted.class)
|
||||
.put(FMLServerStoppingEvent.class, Mod.ServerStopping.class)
|
||||
.put(IMCEvent.class,Mod.IMCCallback.class)
|
||||
.build();
|
||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLStateEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||
private static final BiMap<Class<? extends Annotation>, Class<? extends FMLEvent>> modTypeAnnotations = modAnnotationTypes.inverse();
|
||||
private String annotationDependencies;
|
||||
private VersionRange minecraftAccepted;
|
||||
|
||||
|
@ -422,7 +425,7 @@ public class FMLModContainer implements ModContainer
|
|||
}
|
||||
|
||||
@Subscribe
|
||||
public void handleModStateEvent(FMLStateEvent event)
|
||||
public void handleModStateEvent(FMLEvent event)
|
||||
{
|
||||
Class<? extends Annotation> annotation = modAnnotationTypes.get(event.getClass());
|
||||
if (annotation == null)
|
||||
|
|
|
@ -19,6 +19,7 @@ import com.google.common.eventbus.EventBus;
|
|||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.event.FMLEvent;
|
||||
import cpw.mods.fml.common.event.FMLLoadEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLStateEvent;
|
||||
|
@ -124,7 +125,7 @@ public class LoadController
|
|||
}
|
||||
|
||||
@Subscribe
|
||||
public void propogateStateMessage(FMLStateEvent stateEvent)
|
||||
public void propogateStateMessage(FMLEvent stateEvent)
|
||||
{
|
||||
if (stateEvent instanceof FMLPreInitializationEvent)
|
||||
{
|
||||
|
@ -135,17 +136,20 @@ public class LoadController
|
|||
activeContainer = mc;
|
||||
String modId = mc.getModId();
|
||||
stateEvent.applyModContainer(activeContainer());
|
||||
FMLLog.finer("Posting state event %s to mod %s", stateEvent.getEventType(), modId);
|
||||
FMLLog.finer("Sending event %s to mod %s", stateEvent.getEventType(), modId);
|
||||
eventChannels.get(modId).post(stateEvent);
|
||||
FMLLog.finer("State event %s delivered to mod %s", stateEvent.getEventType(), modId);
|
||||
FMLLog.finer("Sent event %s to mod %s", stateEvent.getEventType(), modId);
|
||||
activeContainer = null;
|
||||
if (!errors.containsKey(modId))
|
||||
if (stateEvent instanceof FMLStateEvent)
|
||||
{
|
||||
modStates.put(modId, stateEvent.getModState());
|
||||
}
|
||||
else
|
||||
{
|
||||
modStates.put(modId, ModState.ERRORED);
|
||||
if (!errors.containsKey(modId))
|
||||
{
|
||||
modStates.put(modId, ((FMLStateEvent)stateEvent).getModState());
|
||||
}
|
||||
else
|
||||
{
|
||||
modStates.put(modId, ModState.ERRORED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -229,4 +233,8 @@ public class LoadController
|
|||
{
|
||||
return this.state == state;
|
||||
}
|
||||
|
||||
boolean hasReachedState(LoaderState state) {
|
||||
return this.state.ordinal()>=state.ordinal() && this.state!=LoaderState.ERRORED;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import com.google.common.collect.TreeMultimap;
|
|||
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.discovery.ModDiscoverer;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms;
|
||||
import cpw.mods.fml.common.event.FMLLoadEvent;
|
||||
import cpw.mods.fml.common.functions.ModIdFunction;
|
||||
import cpw.mods.fml.common.modloader.BaseModProxy;
|
||||
|
@ -645,6 +646,7 @@ public class Loader
|
|||
// Mod controller should be in the initialization state here
|
||||
modController.distributeStateMessage(LoaderState.INITIALIZATION);
|
||||
modController.transition(LoaderState.POSTINITIALIZATION);
|
||||
modController.distributeStateMessage(FMLInterModComms.IMCEvent.class);
|
||||
modController.distributeStateMessage(LoaderState.POSTINITIALIZATION);
|
||||
modController.transition(LoaderState.AVAILABLE);
|
||||
modController.distributeStateMessage(LoaderState.AVAILABLE);
|
||||
|
@ -727,4 +729,8 @@ public class Loader
|
|||
{
|
||||
return minecraft;
|
||||
}
|
||||
|
||||
public boolean hasReachedState(LoaderState state) {
|
||||
return modController.hasReachedState(state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package cpw.mods.fml.common;
|
|||
import com.google.common.base.Throwables;
|
||||
|
||||
import cpw.mods.fml.common.event.FMLConstructionEvent;
|
||||
import cpw.mods.fml.common.event.FMLEvent;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLLoadCompleteEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
|
@ -59,7 +60,7 @@ public enum LoaderState
|
|||
{
|
||||
return eventClass != null;
|
||||
}
|
||||
|
||||
|
||||
public FMLStateEvent getEvent(Object... eventData)
|
||||
{
|
||||
try
|
||||
|
@ -87,7 +88,7 @@ public enum LoaderState
|
|||
AVAILABLE("Available"),
|
||||
DISABLED("Disabled"),
|
||||
ERRORED("Errored");
|
||||
|
||||
|
||||
private String label;
|
||||
|
||||
private ModState(String label)
|
||||
|
|
|
@ -18,6 +18,9 @@ import java.lang.annotation.Retention;
|
|||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import cpw.mods.fml.common.event.FMLInterModComms;
|
||||
import cpw.mods.fml.common.event.FMLInterModComms.IMCMessage;
|
||||
|
||||
import net.minecraft.src.ItemBlock;
|
||||
|
||||
/**
|
||||
|
@ -99,7 +102,7 @@ public @interface Mod
|
|||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStarting {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "post-initialization" phase
|
||||
* Mark the designated method as being called at the "server-started" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
|
@ -107,13 +110,22 @@ public @interface Mod
|
|||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStarted {}
|
||||
/**
|
||||
* Mark the designated method as being called at the "post-initialization" phase
|
||||
* Mark the designated method as being called at the "server-stopping" phase
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface ServerStopping {}
|
||||
/**
|
||||
* Mark the designated method as the receiver for {@link FMLInterModComms} messages
|
||||
* Called between {@link Init} and {@link PostInit}
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface IMCCallback {}
|
||||
/**
|
||||
* Populate the annotated field with the mod instance.
|
||||
* @author cpw
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
package cpw.mods.fml.common.event;
|
||||
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
|
||||
public class FMLEvent
|
||||
{
|
||||
public final String getEventType()
|
||||
{
|
||||
return getClass().getSimpleName();
|
||||
}
|
||||
|
||||
public void applyModContainer(ModContainer activeContainer) {
|
||||
// NO OP
|
||||
}
|
||||
}
|
||||
|
|
102
fml/common/cpw/mods/fml/common/event/FMLInterModComms.java
Normal file
102
fml/common/cpw/mods/fml/common/event/FMLInterModComms.java
Normal file
|
@ -0,0 +1,102 @@
|
|||
package cpw.mods.fml.common.event;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ArrayListMultimap;
|
||||
import com.google.common.collect.FluentIterable;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableListMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.LoaderState;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.Mod.Init;
|
||||
import cpw.mods.fml.common.Mod.PostInit;
|
||||
|
||||
|
||||
/**
|
||||
* Simple intermod communications to receive simple messages directed at you from
|
||||
* other mods
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public class FMLInterModComms {
|
||||
private static ArrayListMultimap<String, IMCMessage> modMessages = ArrayListMultimap.create();
|
||||
/**
|
||||
* Subscribe to this event to receive your messages (they are sent between {@link Init} and {@link PostInit})
|
||||
*
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static class IMCEvent extends FMLEvent {
|
||||
private IMCEvent(List<IMCMessage> messages)
|
||||
{
|
||||
this.messages = Multimaps.index(messages, new Function<IMCMessage, String>() {
|
||||
public String apply(IMCMessage msg) { return msg.sender; };
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyModContainer(ModContainer activeContainer) {
|
||||
currentList = messages.get(activeContainer.getModId());
|
||||
}
|
||||
|
||||
private final ImmutableListMultimap<String, IMCMessage> messages;
|
||||
|
||||
private ImmutableList<IMCMessage> currentList;
|
||||
|
||||
public ImmutableList<IMCMessage> getMessages()
|
||||
{
|
||||
return currentList;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* You will receive an instance of this for each message sent
|
||||
* @author cpw
|
||||
*
|
||||
*/
|
||||
public static final class IMCMessage {
|
||||
/**
|
||||
* This is the modid of the mod that sent you the message
|
||||
*/
|
||||
public final String sender;
|
||||
|
||||
/**
|
||||
* This field, and {@link #value} are both at the mod's discretion
|
||||
*/
|
||||
public final String key;
|
||||
/**
|
||||
* This field, and {@link #key} are both at the mod's discretion
|
||||
*/
|
||||
public final String value;
|
||||
|
||||
private IMCMessage(String sender, String key, String value)
|
||||
{
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
this.sender = sender;
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return sender;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean sendMessage(String modId, String key, String value)
|
||||
{
|
||||
if (Loader.instance().activeModContainer()==null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
modMessages.put(modId, new IMCMessage(Loader.instance().activeModContainer().getModId(), key, value));
|
||||
return Loader.isModLoaded(modId) && !Loader.instance().hasReachedState(LoaderState.POSTINITIALIZATION);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package cpw.mods.fml.common.event;
|
|||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.LoaderState.ModState;
|
||||
import cpw.mods.fml.common.ModContainer;
|
||||
import cpw.mods.fml.common.Side;
|
||||
|
||||
public abstract class FMLStateEvent extends FMLEvent
|
||||
|
@ -14,11 +13,6 @@ public abstract class FMLStateEvent extends FMLEvent
|
|||
|
||||
public abstract ModState getModState();
|
||||
|
||||
public void applyModContainer(ModContainer activeContainer)
|
||||
{
|
||||
// NO OP
|
||||
}
|
||||
|
||||
public Side getSide()
|
||||
{
|
||||
return FMLCommonHandler.instance().getSide();
|
||||
|
|
Loading…
Reference in a new issue