cleaned up a little more; renamed the redirection methods used by the class transformer to make naming collisions even less likely

This commit is contained in:
Florian Nücke 2014-03-04 13:32:05 +01:00
parent d65bd29886
commit 600b3b73f1
10 changed files with 75 additions and 50 deletions

View File

@ -5,6 +5,14 @@ import li.cil.oc.api.machine.Machine;
import li.cil.oc.api.machine.Owner; import li.cil.oc.api.machine.Owner;
public interface MachineAPI { public interface MachineAPI {
/**
* Register an architecture that can be used to create new machines.
* <p/>
* 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<? extends Architecture> architecture); void add(Class<? extends Architecture> architecture);
/** /**

View File

@ -10,6 +10,7 @@ import net.minecraft.tileentity.TileEntity
import org.objectweb.asm.tree._ import org.objectweb.asm.tree._
import org.objectweb.asm.{ClassWriter, ClassReader} import org.objectweb.asm.{ClassWriter, ClassReader}
import scala.collection.convert.WrapAsScala._ import scala.collection.convert.WrapAsScala._
import li.cil.oc.common.asm.template.SimpleComponentImpl
@TransformerExclusions(Array("li.cil.oc.common.asm")) @TransformerExclusions(Array("li.cil.oc.common.asm"))
class ClassTransformer extends IClassTransformer { class ClassTransformer extends IClassTransformer {
@ -99,18 +100,18 @@ class ClassTransformer extends IClassTransformer {
val areSameDeObf = methodNameDeObf + descDeObf == methodNameSrg + desc val areSameDeObf = methodNameDeObf + descDeObf == methodNameSrg + desc
areSamePlain || areSameDeObf areSamePlain || areSameDeObf
} }
if (classNode.methods.exists(method => method.name == methodName + "0" && mapper.mapMethodDesc(method.desc) == desc)) { if (classNode.methods.exists(method => method.name == methodName + SimpleComponentImpl.PostFix && mapper.mapMethodDesc(method.desc) == desc)) {
throw new InjectionFailedException(s"Delegator method name ${methodName}0 is already in use.") throw new InjectionFailedException(s"Delegator method name ${methodName + SimpleComponentImpl.PostFix} is already in use.")
} }
classNode.methods.find(filter) match { classNode.methods.find(filter) match {
case Some(method) => case Some(method) =>
log.fine(s"Found original implementation of $methodName, wrapping.") log.fine(s"Found original implementation of $methodName, wrapping.")
method.name = methodName + "0" method.name = methodName + SimpleComponentImpl.PostFix
case _ => case _ =>
log.fine(s"No original implementation of $methodName, will inject override.") 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 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 { template.methods.find(filter) match {

View File

@ -1,7 +1,10 @@
package li.cil.oc.common.asm; package li.cil.oc.common.asm;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.ITickHandler; import cpw.mods.fml.common.ITickHandler;
import cpw.mods.fml.common.TickType; import cpw.mods.fml.common.TickType;
import li.cil.oc.api.Network;
import net.minecraft.tileentity.TileEntity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet; import java.util.EnumSet;
@ -9,13 +12,26 @@ import java.util.EnumSet;
// This class is used for adding simple components to the component network. // 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. // It is triggered from a validate call, and executed in the next update tick.
public final class SimpleComponentTickHandler implements ITickHandler { public final class SimpleComponentTickHandler implements ITickHandler {
public static final ArrayList<Runnable> pendingOperations = new java.util.ArrayList<Runnable>(); public static final ArrayList<Runnable> pendingAdds = new java.util.ArrayList<Runnable>();
public static final SimpleComponentTickHandler Instance = new SimpleComponentTickHandler(); public static final SimpleComponentTickHandler Instance = new SimpleComponentTickHandler();
private 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 @Override
public String getLabel() { public String getLabel() {
return "OpenComputers SimpleComponent Ticker"; return "OpenComputers SimpleComponent Ticker";
@ -32,11 +48,11 @@ public final class SimpleComponentTickHandler implements ITickHandler {
@Override @Override
public void tickEnd(EnumSet<TickType> type, Object... tickData) { public void tickEnd(EnumSet<TickType> type, Object... tickData) {
synchronized (pendingOperations) { synchronized (pendingAdds) {
for (Runnable runnable : pendingOperations) { for (Runnable runnable : pendingAdds) {
runnable.run(); runnable.run();
} }
pendingOperations.clear(); pendingAdds.clear();
} }
} }
} }

View File

@ -4,18 +4,25 @@ import li.cil.oc.api.network.Environment;
import li.cil.oc.api.network.SimpleComponent; import li.cil.oc.api.network.SimpleComponent;
import net.minecraft.nbt.NBTTagCompound; 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 * This interface defines the names to which existing or placeholders for
// functionality, i.e. existing validate() etc. methods will be called as * existing methods will be moved. This allows transparent injection of our
// if we didn't inject our code. * functionality, i.e. existing validate() etc. methods will be called as
* if we didn't inject our code.
* <p/>
* Yes, the names are not "conventional", but that is by design, to avoid
* naming collisions.
*/
public interface SimpleComponentImpl extends Environment, SimpleComponent { 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);
} }

View File

@ -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 // This way they are always guaranteed to be present, so we can simply call
// them through an interface, and need no runtime reflection. // them through an interface, and need no runtime reflection.
public void validate0() { public void validate_OpenComputers() {
super.validate(); super.validate();
} }
public void invalidate0() { public void invalidate_OpenComputers() {
super.invalidate(); super.invalidate();
} }
public void onChunkUnload0() { public void onChunkUnload_OpenComputers() {
super.onChunkUnload(); super.onChunkUnload();
} }
public void readFromNBT0(NBTTagCompound nbt) { public void readFromNBT_OpenComputers(NBTTagCompound nbt) {
super.readFromNBT(nbt); super.readFromNBT(nbt);
} }
public void writeToNBT0(NBTTagCompound nbt) { public void writeToNBT_OpenComputers(NBTTagCompound nbt) {
super.writeToNBT(nbt); super.writeToNBT(nbt);
} }
} }

View File

@ -40,21 +40,12 @@ public final class StaticSimpleEnvironment {
} }
public static void validate(final SimpleComponentImpl self) { public static void validate(final SimpleComponentImpl self) {
self.validate0(); self.validate_OpenComputers();
if (FMLCommonHandler.instance().getEffectiveSide().isServer()) { SimpleComponentTickHandler.schedule((TileEntity) self);
synchronized (SimpleComponentTickHandler.pendingOperations) {
SimpleComponentTickHandler.pendingOperations.add(new Runnable() {
@Override
public void run() {
Network.joinOrCreateNetwork((TileEntity) self);
}
});
}
}
} }
public static void invalidate(final SimpleComponentImpl self) { public static void invalidate(final SimpleComponentImpl self) {
self.invalidate0(); self.invalidate_OpenComputers();
final Node node = node(self); final Node node = node(self);
if (node != null) { if (node != null) {
node.remove(); node.remove();
@ -63,7 +54,7 @@ public final class StaticSimpleEnvironment {
} }
public static void onChunkUnload(final SimpleComponentImpl self) { public static void onChunkUnload(final SimpleComponentImpl self) {
self.onChunkUnload0(); self.onChunkUnload_OpenComputers();
final Node node = node(self); final Node node = node(self);
if (node != null) { if (node != null) {
node.remove(); node.remove();
@ -72,7 +63,7 @@ public final class StaticSimpleEnvironment {
} }
public static void readFromNBT(final SimpleComponentImpl self, NBTTagCompound nbt) { public static void readFromNBT(final SimpleComponentImpl self, NBTTagCompound nbt) {
self.readFromNBT0(nbt); self.readFromNBT_OpenComputers(nbt);
final Node node = node(self); final Node node = node(self);
if (node != null) { if (node != null) {
node.load(nbt.getCompoundTag("oc:node")); node.load(nbt.getCompoundTag("oc:node"));
@ -80,7 +71,7 @@ public final class StaticSimpleEnvironment {
} }
public static void writeToNBT(final SimpleComponentImpl self, NBTTagCompound nbt) { public static void writeToNBT(final SimpleComponentImpl self, NBTTagCompound nbt) {
self.writeToNBT0(nbt); self.writeToNBT_OpenComputers(nbt);
final Node node = node(self); final Node node = node(self);
if (node != null) { if (node != null) {
final NBTTagCompound nodeNbt = new NBTTagCompound(); final NBTTagCompound nodeNbt = new NBTTagCompound();

View File

@ -21,7 +21,7 @@ class CablePart(val original: Option[Node] = None) extends DelegatePart with TCu
override def delegate = Blocks.cable override def delegate = Blocks.cable
def getType = "oc:cable" def getType = Settings.namespace + "cable"
override def doesTick = false override def doesTick = false

View File

@ -3,20 +3,20 @@ package li.cil.oc.common.multipart
import codechicken.lib.vec.BlockCoord import codechicken.lib.vec.BlockCoord
import codechicken.multipart.MultiPartRegistry.{IPartConverter, IPartFactory} import codechicken.multipart.MultiPartRegistry.{IPartConverter, IPartFactory}
import codechicken.multipart.{TMultiPart, MultiPartRegistry} import codechicken.multipart.{TMultiPart, MultiPartRegistry}
import li.cil.oc.Blocks
import li.cil.oc.common.tileentity.Cable import li.cil.oc.common.tileentity.Cable
import li.cil.oc.{Settings, Blocks}
import net.minecraft.world.World import net.minecraft.world.World
import net.minecraftforge.common.MinecraftForge import net.minecraftforge.common.MinecraftForge
object MultiPart extends IPartFactory with IPartConverter { object MultiPart extends IPartFactory with IPartConverter {
def init() { def init() {
MultiPartRegistry.registerConverter(this) MultiPartRegistry.registerConverter(this)
MultiPartRegistry.registerParts(this, Array("oc:cable")) MultiPartRegistry.registerParts(this, Array(Settings.namespace + "cable"))
MinecraftForge.EVENT_BUS.register(EventHandler) MinecraftForge.EVENT_BUS.register(EventHandler)
} }
override def createPart(name: String, client: Boolean): TMultiPart = { override def createPart(name: String, client: Boolean): TMultiPart = {
if (name.equals("oc:cable")) if (name.equals(Settings.namespace + "cable"))
return new CablePart() return new CablePart()
null null
} }

View File

@ -52,7 +52,7 @@ class PacketHandler extends CommonPacketHandler {
if (!computer.isPaused) { if (!computer.isPaused) {
computer.start() computer.start()
computer.lastError match { computer.lastError match {
case message => player.sendChatToPlayer(ChatMessageComponent.createFromTranslationKey(message)) case message if message != null => player.sendChatToPlayer(ChatMessageComponent.createFromTranslationKey(message))
case _ => case _ =>
} }
} }

View File

@ -1,7 +1,7 @@
package li.cil.oc.server package li.cil.oc.server
import codechicken.multipart.TMultiPart 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 java.util
import li.cil.oc.api.Network import li.cil.oc.api.Network
import net.minecraft.tileentity.TileEntity import net.minecraft.tileentity.TileEntity
@ -10,12 +10,14 @@ import scala.collection.mutable
object TickHandler extends ITickHandler { object TickHandler extends ITickHandler {
val pendingAdds = mutable.Buffer.empty[() => Unit] val pendingAdds = mutable.Buffer.empty[() => Unit]
def schedule(tileEntity: TileEntity) = pendingAdds.synchronized { def schedule(tileEntity: TileEntity) =
if (FMLCommonHandler.instance.getEffectiveSide.isServer) pendingAdds.synchronized {
pendingAdds += (() => Network.joinOrCreateNetwork(tileEntity)) pendingAdds += (() => Network.joinOrCreateNetwork(tileEntity))
} }
@Optional.Method(modid = "ForgeMultipart") @Optional.Method(modid = "ForgeMultipart")
def schedule(part: TMultiPart) = pendingAdds.synchronized { def schedule(part: TMultiPart) =
if (FMLCommonHandler.instance.getEffectiveSide.isServer) pendingAdds.synchronized {
pendingAdds += (() => Network.joinOrCreateNetwork(part.tile)) pendingAdds += (() => Network.joinOrCreateNetwork(part.tile))
} }