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;
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);
/**

View File

@ -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 {

View File

@ -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<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();
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<TickType> type, Object... tickData) {
synchronized (pendingOperations) {
for (Runnable runnable : pendingOperations) {
synchronized (pendingAdds) {
for (Runnable runnable : pendingAdds) {
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 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.
* <p/>
* 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);
}

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
// 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);
}
}

View File

@ -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();

View File

@ -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

View File

@ -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
}

View File

@ -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 _ =>
}
}

View File

@ -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"