diff --git a/src/main/java/li/cil/oc/api/detail/MachineAPI.java b/src/main/java/li/cil/oc/api/detail/MachineAPI.java index 7a018aa68..e66d907a6 100644 --- a/src/main/java/li/cil/oc/api/detail/MachineAPI.java +++ b/src/main/java/li/cil/oc/api/detail/MachineAPI.java @@ -5,6 +5,14 @@ import li.cil.oc.api.machine.Machine; import li.cil.oc.api.machine.Owner; public interface MachineAPI { + /** + * Register an architecture that can be used to create new machines. + *

+ * Note that although registration is optional, it is strongly recommended + * to allow {@link #architectures()} to be useful. + * + * @param architecture the architecture to register. + */ void add(Class architecture); /** diff --git a/src/main/java/li/cil/oc/common/asm/ClassTransformer.scala b/src/main/java/li/cil/oc/common/asm/ClassTransformer.scala index 81384c9ca..5b2b1ed4d 100644 --- a/src/main/java/li/cil/oc/common/asm/ClassTransformer.scala +++ b/src/main/java/li/cil/oc/common/asm/ClassTransformer.scala @@ -10,6 +10,7 @@ import net.minecraft.tileentity.TileEntity import org.objectweb.asm.tree._ import org.objectweb.asm.{ClassWriter, ClassReader} import scala.collection.convert.WrapAsScala._ +import li.cil.oc.common.asm.template.SimpleComponentImpl @TransformerExclusions(Array("li.cil.oc.common.asm")) class ClassTransformer extends IClassTransformer { @@ -99,18 +100,18 @@ class ClassTransformer extends IClassTransformer { val areSameDeObf = methodNameDeObf + descDeObf == methodNameSrg + desc areSamePlain || areSameDeObf } - if (classNode.methods.exists(method => method.name == methodName + "0" && mapper.mapMethodDesc(method.desc) == desc)) { - throw new InjectionFailedException(s"Delegator method name ${methodName}0 is already in use.") + if (classNode.methods.exists(method => method.name == methodName + SimpleComponentImpl.PostFix && mapper.mapMethodDesc(method.desc) == desc)) { + throw new InjectionFailedException(s"Delegator method name ${methodName + SimpleComponentImpl.PostFix} is already in use.") } classNode.methods.find(filter) match { case Some(method) => log.fine(s"Found original implementation of $methodName, wrapping.") - method.name = methodName + "0" + method.name = methodName + SimpleComponentImpl.PostFix case _ => log.fine(s"No original implementation of $methodName, will inject override.") - template.methods.find(_.name == methodName + "0") match { + template.methods.find(_.name == methodName + SimpleComponentImpl.PostFix) match { case Some(method) => classNode.methods.add(method) - case _ => throw new AssertionError(s"Couldn't find ${methodName}0 in template implementation.") + case _ => throw new AssertionError(s"Couldn't find ${methodName + SimpleComponentImpl.PostFix} in template implementation.") } } template.methods.find(filter) match { diff --git a/src/main/java/li/cil/oc/common/asm/SimpleComponentTickHandler.java b/src/main/java/li/cil/oc/common/asm/SimpleComponentTickHandler.java index 6cde65ed1..c0e214dd8 100644 --- a/src/main/java/li/cil/oc/common/asm/SimpleComponentTickHandler.java +++ b/src/main/java/li/cil/oc/common/asm/SimpleComponentTickHandler.java @@ -1,7 +1,10 @@ package li.cil.oc.common.asm; +import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.TickType; +import li.cil.oc.api.Network; +import net.minecraft.tileentity.TileEntity; import java.util.ArrayList; import java.util.EnumSet; @@ -9,13 +12,26 @@ import java.util.EnumSet; // This class is used for adding simple components to the component network. // It is triggered from a validate call, and executed in the next update tick. public final class SimpleComponentTickHandler implements ITickHandler { - public static final ArrayList pendingOperations = new java.util.ArrayList(); + public static final ArrayList pendingAdds = new java.util.ArrayList(); public static final SimpleComponentTickHandler Instance = new SimpleComponentTickHandler(); private SimpleComponentTickHandler() { } + public static void schedule(final TileEntity tileEntity) { + if (FMLCommonHandler.instance().getEffectiveSide().isServer()) { + synchronized (pendingAdds) { + pendingAdds.add(new Runnable() { + @Override + public void run() { + Network.joinOrCreateNetwork(tileEntity); + } + }); + } + } + } + @Override public String getLabel() { return "OpenComputers SimpleComponent Ticker"; @@ -32,11 +48,11 @@ public final class SimpleComponentTickHandler implements ITickHandler { @Override public void tickEnd(EnumSet type, Object... tickData) { - synchronized (pendingOperations) { - for (Runnable runnable : pendingOperations) { + synchronized (pendingAdds) { + for (Runnable runnable : pendingAdds) { runnable.run(); } - pendingOperations.clear(); + pendingAdds.clear(); } } } diff --git a/src/main/java/li/cil/oc/common/asm/template/SimpleComponentImpl.java b/src/main/java/li/cil/oc/common/asm/template/SimpleComponentImpl.java index 770cb59cb..d7c95b376 100644 --- a/src/main/java/li/cil/oc/common/asm/template/SimpleComponentImpl.java +++ b/src/main/java/li/cil/oc/common/asm/template/SimpleComponentImpl.java @@ -4,18 +4,25 @@ import li.cil.oc.api.network.Environment; import li.cil.oc.api.network.SimpleComponent; import net.minecraft.nbt.NBTTagCompound; -// This interface defines the names to which existing or placeholders for -// existing methods will be moved. This allows transparent injection of our -// functionality, i.e. existing validate() etc. methods will be called as -// if we didn't inject our code. +/** + * This interface defines the names to which existing or placeholders for + * existing methods will be moved. This allows transparent injection of our + * functionality, i.e. existing validate() etc. methods will be called as + * if we didn't inject our code. + *

+ * Yes, the names are not "conventional", but that is by design, to avoid + * naming collisions. + */ public interface SimpleComponentImpl extends Environment, SimpleComponent { - void validate0(); + public static final String PostFix = "_OpenComputers"; - void invalidate0(); + void validate_OpenComputers(); - void onChunkUnload0(); + void invalidate_OpenComputers(); - void readFromNBT0(NBTTagCompound nbt); + void onChunkUnload_OpenComputers(); - void writeToNBT0(NBTTagCompound nbt); + void readFromNBT_OpenComputers(NBTTagCompound nbt); + + void writeToNBT_OpenComputers(NBTTagCompound nbt); } diff --git a/src/main/java/li/cil/oc/common/asm/template/SimpleEnvironment.java b/src/main/java/li/cil/oc/common/asm/template/SimpleEnvironment.java index dc9bc11d2..d47c9c28c 100644 --- a/src/main/java/li/cil/oc/common/asm/template/SimpleEnvironment.java +++ b/src/main/java/li/cil/oc/common/asm/template/SimpleEnvironment.java @@ -63,23 +63,23 @@ public abstract class SimpleEnvironment extends TileEntity implements SimpleComp // This way they are always guaranteed to be present, so we can simply call // them through an interface, and need no runtime reflection. - public void validate0() { + public void validate_OpenComputers() { super.validate(); } - public void invalidate0() { + public void invalidate_OpenComputers() { super.invalidate(); } - public void onChunkUnload0() { + public void onChunkUnload_OpenComputers() { super.onChunkUnload(); } - public void readFromNBT0(NBTTagCompound nbt) { + public void readFromNBT_OpenComputers(NBTTagCompound nbt) { super.readFromNBT(nbt); } - public void writeToNBT0(NBTTagCompound nbt) { + public void writeToNBT_OpenComputers(NBTTagCompound nbt) { super.writeToNBT(nbt); } } diff --git a/src/main/java/li/cil/oc/common/asm/template/StaticSimpleEnvironment.java b/src/main/java/li/cil/oc/common/asm/template/StaticSimpleEnvironment.java index 276489f0a..ac1ce67b7 100644 --- a/src/main/java/li/cil/oc/common/asm/template/StaticSimpleEnvironment.java +++ b/src/main/java/li/cil/oc/common/asm/template/StaticSimpleEnvironment.java @@ -40,21 +40,12 @@ public final class StaticSimpleEnvironment { } public static void validate(final SimpleComponentImpl self) { - self.validate0(); - if (FMLCommonHandler.instance().getEffectiveSide().isServer()) { - synchronized (SimpleComponentTickHandler.pendingOperations) { - SimpleComponentTickHandler.pendingOperations.add(new Runnable() { - @Override - public void run() { - Network.joinOrCreateNetwork((TileEntity) self); - } - }); - } - } + self.validate_OpenComputers(); + SimpleComponentTickHandler.schedule((TileEntity) self); } public static void invalidate(final SimpleComponentImpl self) { - self.invalidate0(); + self.invalidate_OpenComputers(); final Node node = node(self); if (node != null) { node.remove(); @@ -63,7 +54,7 @@ public final class StaticSimpleEnvironment { } public static void onChunkUnload(final SimpleComponentImpl self) { - self.onChunkUnload0(); + self.onChunkUnload_OpenComputers(); final Node node = node(self); if (node != null) { node.remove(); @@ -72,7 +63,7 @@ public final class StaticSimpleEnvironment { } public static void readFromNBT(final SimpleComponentImpl self, NBTTagCompound nbt) { - self.readFromNBT0(nbt); + self.readFromNBT_OpenComputers(nbt); final Node node = node(self); if (node != null) { node.load(nbt.getCompoundTag("oc:node")); @@ -80,7 +71,7 @@ public final class StaticSimpleEnvironment { } public static void writeToNBT(final SimpleComponentImpl self, NBTTagCompound nbt) { - self.writeToNBT0(nbt); + self.writeToNBT_OpenComputers(nbt); final Node node = node(self); if (node != null) { final NBTTagCompound nodeNbt = new NBTTagCompound(); diff --git a/src/main/java/li/cil/oc/common/multipart/CablePart.scala b/src/main/java/li/cil/oc/common/multipart/CablePart.scala index 1e53c08e0..f8ef065d1 100644 --- a/src/main/java/li/cil/oc/common/multipart/CablePart.scala +++ b/src/main/java/li/cil/oc/common/multipart/CablePart.scala @@ -21,7 +21,7 @@ class CablePart(val original: Option[Node] = None) extends DelegatePart with TCu override def delegate = Blocks.cable - def getType = "oc:cable" + def getType = Settings.namespace + "cable" override def doesTick = false diff --git a/src/main/java/li/cil/oc/common/multipart/MultiPart.scala b/src/main/java/li/cil/oc/common/multipart/MultiPart.scala index 9f78faeff..6c15c6dcb 100644 --- a/src/main/java/li/cil/oc/common/multipart/MultiPart.scala +++ b/src/main/java/li/cil/oc/common/multipart/MultiPart.scala @@ -3,20 +3,20 @@ package li.cil.oc.common.multipart import codechicken.lib.vec.BlockCoord import codechicken.multipart.MultiPartRegistry.{IPartConverter, IPartFactory} import codechicken.multipart.{TMultiPart, MultiPartRegistry} -import li.cil.oc.Blocks import li.cil.oc.common.tileentity.Cable +import li.cil.oc.{Settings, Blocks} import net.minecraft.world.World import net.minecraftforge.common.MinecraftForge object MultiPart extends IPartFactory with IPartConverter { def init() { MultiPartRegistry.registerConverter(this) - MultiPartRegistry.registerParts(this, Array("oc:cable")) + MultiPartRegistry.registerParts(this, Array(Settings.namespace + "cable")) MinecraftForge.EVENT_BUS.register(EventHandler) } override def createPart(name: String, client: Boolean): TMultiPart = { - if (name.equals("oc:cable")) + if (name.equals(Settings.namespace + "cable")) return new CablePart() null } diff --git a/src/main/java/li/cil/oc/server/PacketHandler.scala b/src/main/java/li/cil/oc/server/PacketHandler.scala index 88970e672..85b438747 100644 --- a/src/main/java/li/cil/oc/server/PacketHandler.scala +++ b/src/main/java/li/cil/oc/server/PacketHandler.scala @@ -52,7 +52,7 @@ class PacketHandler extends CommonPacketHandler { if (!computer.isPaused) { computer.start() computer.lastError match { - case message => player.sendChatToPlayer(ChatMessageComponent.createFromTranslationKey(message)) + case message if message != null => player.sendChatToPlayer(ChatMessageComponent.createFromTranslationKey(message)) case _ => } } diff --git a/src/main/java/li/cil/oc/server/TickHandler.scala b/src/main/java/li/cil/oc/server/TickHandler.scala index 2f3829304..492c94634 100644 --- a/src/main/java/li/cil/oc/server/TickHandler.scala +++ b/src/main/java/li/cil/oc/server/TickHandler.scala @@ -1,7 +1,7 @@ package li.cil.oc.server import codechicken.multipart.TMultiPart -import cpw.mods.fml.common.{Optional, TickType, ITickHandler} +import cpw.mods.fml.common.{FMLCommonHandler, Optional, TickType, ITickHandler} import java.util import li.cil.oc.api.Network import net.minecraft.tileentity.TileEntity @@ -10,14 +10,16 @@ import scala.collection.mutable object TickHandler extends ITickHandler { val pendingAdds = mutable.Buffer.empty[() => Unit] - def schedule(tileEntity: TileEntity) = pendingAdds.synchronized { - pendingAdds += (() => Network.joinOrCreateNetwork(tileEntity)) - } + def schedule(tileEntity: TileEntity) = + if (FMLCommonHandler.instance.getEffectiveSide.isServer) pendingAdds.synchronized { + pendingAdds += (() => Network.joinOrCreateNetwork(tileEntity)) + } @Optional.Method(modid = "ForgeMultipart") - def schedule(part: TMultiPart) = pendingAdds.synchronized { - pendingAdds += (() => Network.joinOrCreateNetwork(part.tile)) - } + def schedule(part: TMultiPart) = + if (FMLCommonHandler.instance.getEffectiveSide.isServer) pendingAdds.synchronized { + pendingAdds += (() => Network.joinOrCreateNetwork(part.tile)) + } override def getLabel = "OpenComputers Network Initialization Ticker"