001    package cpw.mods.fml.common.event;
002    
003    import java.util.List;
004    
005    import net.minecraft.item.ItemStack;
006    import net.minecraft.nbt.NBTTagCompound;
007    
008    import com.google.common.base.Function;
009    import com.google.common.base.Functions;
010    import com.google.common.base.Predicate;
011    import com.google.common.base.Predicates;
012    import com.google.common.collect.ArrayListMultimap;
013    import com.google.common.collect.FluentIterable;
014    import com.google.common.collect.ImmutableList;
015    import com.google.common.collect.ImmutableListMultimap;
016    import com.google.common.collect.Maps;
017    import com.google.common.collect.Multimaps;
018    
019    import cpw.mods.fml.common.FMLCommonHandler;
020    import cpw.mods.fml.common.Loader;
021    import cpw.mods.fml.common.LoaderState;
022    import cpw.mods.fml.common.ModContainer;
023    import cpw.mods.fml.common.Mod.Init;
024    import cpw.mods.fml.common.Mod.PostInit;
025    
026    /**
027     * Simple intermod communications to receive simple messages directed at you
028     * from other mods
029     *
030     * @author cpw
031     *
032     */
033    public class FMLInterModComms {
034        private static final ImmutableList<IMCMessage> emptyIMCList = ImmutableList.<IMCMessage>of();
035        private static ArrayListMultimap<String, IMCMessage> modMessages = ArrayListMultimap.create();
036    
037        /**
038         * Subscribe to this event to receive your messages (they are sent between
039         * {@link Init} and {@link PostInit})
040         *
041         * @author cpw
042         *
043         */
044        public static class IMCEvent extends FMLEvent {
045            @Override
046            public void applyModContainer(ModContainer activeContainer)
047            {
048                currentList = ImmutableList.copyOf(modMessages.removeAll(activeContainer.getModId()));
049            }
050    
051            private ImmutableList<IMCMessage> currentList;
052    
053            public ImmutableList<IMCMessage> getMessages()
054            {
055                return currentList;
056            }
057        }
058    
059        /**
060         * You will receive an instance of this for each message sent
061         *
062         * @author cpw
063         *
064         */
065        public static final class IMCMessage {
066            /**
067             * This is the modid of the mod that sent you the message
068             */
069            private String sender;
070            /**
071             * This field, and {@link #value} are both at the mod's discretion
072             */
073            public final String key;
074            /**
075             * This field, and {@link #key} are both at the mod's discretion
076             */
077            private Object value;
078    
079            private IMCMessage(String key, Object value)
080            {
081                this.key = key;
082                this.value = value;
083            }
084    
085            @Override
086            public String toString()
087            {
088                return sender;
089            }
090    
091            public String getSender()
092            {
093                return this.sender;
094            }
095    
096            void setSender(ModContainer activeModContainer)
097            {
098                this.sender = activeModContainer.getModId();
099            }
100    
101            public String getStringValue()
102            {
103                return (String) value;
104            }
105    
106            public NBTTagCompound getNBTValue()
107            {
108                return (NBTTagCompound) value;
109            }
110    
111            public ItemStack getItemStackValue()
112            {
113                return (ItemStack) value;
114            }
115        }
116    
117        public static boolean sendMessage(String modId, String key, NBTTagCompound value)
118        {
119            return enqueueStartupMessage(modId, new IMCMessage(key, value));
120        }
121        public static boolean sendMessage(String modId, String key, ItemStack value)
122        {
123            return enqueueStartupMessage(modId, new IMCMessage(key, value));
124        }
125        public static boolean sendMessage(String modId, String key, String value)
126        {
127            return enqueueStartupMessage(modId, new IMCMessage(key, value));
128        }
129    
130        public static void sendRuntimeMessage(Object sourceMod, String modId, String key, NBTTagCompound value)
131        {
132            enqueueMessage(sourceMod, modId, new IMCMessage(key, value));
133        }
134    
135        public static void sendRuntimeMessage(Object sourceMod, String modId, String key, ItemStack value)
136        {
137            enqueueMessage(sourceMod, modId, new IMCMessage(key, value));
138        }
139    
140        public static void sendRuntimeMessage(Object sourceMod, String modId, String key, String value)
141        {
142            enqueueMessage(sourceMod, modId, new IMCMessage(key, value));
143        }
144    
145        private static boolean enqueueStartupMessage(String modTarget, IMCMessage message)
146        {
147            if (Loader.instance().activeModContainer() == null)
148            {
149                return false;
150            }
151            enqueueMessage(Loader.instance().activeModContainer(), modTarget, message);
152            return Loader.isModLoaded(modTarget) && !Loader.instance().hasReachedState(LoaderState.POSTINITIALIZATION);
153    
154        }
155        private static void enqueueMessage(Object sourceMod, String modTarget, IMCMessage message)
156        {
157            ModContainer mc = FMLCommonHandler.instance().findContainerFor(sourceMod);
158            if (mc != null && Loader.isModLoaded(modTarget))
159            {
160                message.setSender(mc);
161                modMessages.put(modTarget, message);
162            }
163        }
164    
165        public static ImmutableList<IMCMessage> fetchRuntimeMessages(Object forMod)
166        {
167            ModContainer mc = FMLCommonHandler.instance().findContainerFor(forMod);
168            if (mc != null)
169            {
170                return ImmutableList.copyOf(modMessages.removeAll(mc));
171            }
172            else
173            {
174                return emptyIMCList;
175            }
176        }
177    }