From 7e803cdb8ef5c73e15b6ea353e02e3a3a2f782f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 14 Jan 2014 16:43:53 +0100 Subject: [PATCH] fixes optional interface derp making the mod crash if stargatetech 2 isn't present. this is actually a hacky workaround because I have no clue why IBusDevice cannot be implemented by AbstractBusAware, after all the same pattern works for redstone and cc's peripheral interface... the mysteries of class loading. fixes #81 --- .../common/tileentity/AbstractBusAware.scala | 40 ++++++++++++------- .../tileentity/BundledRedstoneAware.scala | 7 ++-- li/cil/oc/common/tileentity/Computer.scala | 6 ++- .../oc/common/tileentity/RedstoneAware.scala | 7 ++-- li/cil/oc/util/mods/StargateTech2.scala | 11 +++++ mcmod.info | 2 +- 6 files changed, 48 insertions(+), 25 deletions(-) create mode 100644 li/cil/oc/util/mods/StargateTech2.scala diff --git a/li/cil/oc/common/tileentity/AbstractBusAware.scala b/li/cil/oc/common/tileentity/AbstractBusAware.scala index 88b490d2a..cea74b72d 100644 --- a/li/cil/oc/common/tileentity/AbstractBusAware.scala +++ b/li/cil/oc/common/tileentity/AbstractBusAware.scala @@ -4,14 +4,26 @@ import cpw.mods.fml.common.{Loader, Optional} import cpw.mods.fml.relauncher.{SideOnly, Side} import li.cil.oc.api.network.Node import li.cil.oc.server.{PacketSender => ServerPacketSender, component} +import li.cil.oc.util.mods.StargateTech2 import net.minecraft.item.ItemStack import net.minecraft.nbt.NBTTagCompound -import net.minecraftforge.common.MinecraftForge import stargatetech2.api.StargateTechAPI -import stargatetech2.api.bus.{BusEvent, IBusDevice} +import stargatetech2.api.bus.{IBusInterface, IBusDevice} -@Optional.Interface(iface = "stargatetech2.api.bus.IBusDevice", modid = "StargateTech2") -trait AbstractBusAware extends TileEntity with ComponentInventory with IBusDevice { +// IMPORTANT: for some reason that is beyond me we cannot implement the +// IBusDevice here directly, since we'll get an error if the interface is not +// provided (i.e. if SGT2 isn't installed), even if we tell FML to strip it. +// Assuming FML properly strips the interface (and it looks like it does, when +// inspecting it in the debugger, i.e. getInterfaces() doesn't contain it), it +// probably is something derping up in the class loader... the thing that +// confuses me the most, though, is that it apparently works for redstone and +// the CC interface, so... yeah. I'm out of ideas. +trait AbstractBusAware extends TileEntity with ComponentInventory { self: IBusDevice => + protected var _isAbstractBusAvailable: Boolean = _ + + protected lazy val fakeInterface = Array[AnyRef](StargateTechAPI.api.getFactory.getIBusInterface(this, null)) + + @Optional.Method(modid = "StargateTech2") def getInterfaces(side: Int) = if (isAbstractBusAvailable) { if (isServer) { @@ -19,14 +31,10 @@ trait AbstractBusAware extends TileEntity with ComponentInventory with IBusDevic case Some(abstractBus: component.AbstractBus) => abstractBus.busInterface } } - else fakeInterface + else fakeInterface.map(_.asInstanceOf[IBusInterface]) } else null - protected var _isAbstractBusAvailable = false - - private lazy val fakeInterface = Array(StargateTechAPI.api.getFactory.getIBusInterface(this, null)) - def getWorld = world def getXCoord = x @@ -84,22 +92,24 @@ trait AbstractBusAware extends TileEntity with ComponentInventory with IBusDevic removeAbstractBus() } + // IMPORTANT: all the Loader.isModLoaded checks are there to a void class + // not found errors! Also, don't try to move them further down in the logic + // (e.g. into StargateTech2) since that would not help avoid the error anymore. + protected def addAbstractBus() { - // Mod loaded check to avoid class not found errors. if (isServer && Loader.isModLoaded("StargateTech2")) { - MinecraftForge.EVENT_BUS.post(new BusEvent.AddToNetwork(world, x, y, z)) + StargateTech2.addDevice(world, x, y, z) } } protected def removeAbstractBus() { - // Mod loaded check to avoid class not found errors. if (isServer && Loader.isModLoaded("StargateTech2")) { - MinecraftForge.EVENT_BUS.post(new BusEvent.RemoveFromNetwork(world, x, y, z)) + StargateTech2.removeDevice(world, x, y, z) } } - protected def hasAbstractBusCard = components exists { + protected def hasAbstractBusCard = Loader.isModLoaded("StargateTech2") && (components exists { case Some(_: component.AbstractBus) => true case _ => false - } + }) } diff --git a/li/cil/oc/common/tileentity/BundledRedstoneAware.scala b/li/cil/oc/common/tileentity/BundledRedstoneAware.scala index f7f5424f0..646b743a0 100644 --- a/li/cil/oc/common/tileentity/BundledRedstoneAware.scala +++ b/li/cil/oc/common/tileentity/BundledRedstoneAware.scala @@ -1,6 +1,5 @@ package li.cil.oc.common.tileentity -import cpw.mods.fml.common.Optional.Interface import cpw.mods.fml.common.{Optional, Loader} import li.cil.oc.Settings import li.cil.oc.util.ExtendedNBT._ @@ -13,9 +12,9 @@ import powercrystals.minefactoryreloaded.api.rednet.IRedNetNetworkContainer import scala.Array @Optional.InterfaceList(Array( - new Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledEmitter", modid = "RedLogic"), - new Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledUpdatable", modid = "RedLogic"), - new Interface(iface = "mrtjp.projectred.api.IBundledTile", modid = "ProjRed|Transmission") + new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledEmitter", modid = "RedLogic"), + new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IBundledUpdatable", modid = "RedLogic"), + new Optional.Interface(iface = "mrtjp.projectred.api.IBundledTile", modid = "ProjRed|Transmission") )) trait BundledRedstoneAware extends RedstoneAware with IBundledEmitter with IBundledUpdatable with IBundledTile { diff --git a/li/cil/oc/common/tileentity/Computer.scala b/li/cil/oc/common/tileentity/Computer.scala index de4a8c4d7..5c887f254 100644 --- a/li/cil/oc/common/tileentity/Computer.scala +++ b/li/cil/oc/common/tileentity/Computer.scala @@ -1,5 +1,6 @@ package li.cil.oc.common.tileentity +import cpw.mods.fml.common.Optional import cpw.mods.fml.relauncher.{Side, SideOnly} import li.cil.oc.Settings import li.cil.oc.api.network._ @@ -10,8 +11,11 @@ import net.minecraft.nbt.{NBTTagString, NBTTagCompound} import net.minecraftforge.common.ForgeDirection import scala.Some import scala.collection.mutable +import stargatetech2.api.bus.IBusDevice -abstract class Computer(isRemote: Boolean) extends Environment with ComponentInventory with Rotatable with BundledRedstoneAware with AbstractBusAware with Analyzable with Context { +// See AbstractBusAware as to why we have to define the IBusDevice here. +@Optional.Interface(iface = "stargatetech2.api.bus.IBusDevice", modid = "StargateTech2") +abstract class Computer(isRemote: Boolean) extends Environment with ComponentInventory with Rotatable with BundledRedstoneAware with AbstractBusAware with IBusDevice with Analyzable with Context { protected val _computer = if (isRemote) null else new component.Computer(this) def computer = _computer diff --git a/li/cil/oc/common/tileentity/RedstoneAware.scala b/li/cil/oc/common/tileentity/RedstoneAware.scala index 4af0585ca..44e691aba 100644 --- a/li/cil/oc/common/tileentity/RedstoneAware.scala +++ b/li/cil/oc/common/tileentity/RedstoneAware.scala @@ -1,6 +1,5 @@ package li.cil.oc.common.tileentity -import cpw.mods.fml.common.Optional.Interface import cpw.mods.fml.common.{Loader, Optional} import cpw.mods.fml.relauncher.{SideOnly, Side} import li.cil.oc.Settings @@ -13,9 +12,9 @@ import net.minecraft.nbt.NBTTagCompound import net.minecraftforge.common.ForgeDirection @Optional.InterfaceList(Array( - new Interface(iface = "mods.immibis.redlogic.api.wiring.IConnectable", modid = "RedLogic"), - new Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneEmitter", modid = "RedLogic"), - new Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneUpdatable", modid = "RedLogic") + new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IConnectable", modid = "RedLogic"), + new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneEmitter", modid = "RedLogic"), + new Optional.Interface(iface = "mods.immibis.redlogic.api.wiring.IRedstoneUpdatable", modid = "RedLogic") )) trait RedstoneAware extends RotationAware with network.Environment with Persistable with IConnectable with IRedstoneEmitter with IRedstoneUpdatable { protected val _input = Array.fill(6)(-1) diff --git a/li/cil/oc/util/mods/StargateTech2.scala b/li/cil/oc/util/mods/StargateTech2.scala new file mode 100644 index 000000000..9069b5639 --- /dev/null +++ b/li/cil/oc/util/mods/StargateTech2.scala @@ -0,0 +1,11 @@ +package li.cil.oc.util.mods + +import net.minecraft.world.World +import net.minecraftforge.common.MinecraftForge +import stargatetech2.api.bus.BusEvent.{RemoveFromNetwork, AddToNetwork} + +object StargateTech2 { + def addDevice(world: World, x: Int, y: Int, z: Int) = MinecraftForge.EVENT_BUS.post(new AddToNetwork(world, x, y, z)) + + def removeDevice(world: World, x: Int, y: Int, z: Int) = MinecraftForge.EVENT_BUS.post(new RemoveFromNetwork(world, x, y, z)) +} diff --git a/mcmod.info b/mcmod.info index 1dfa3f861..d846ce8d2 100644 --- a/mcmod.info +++ b/mcmod.info @@ -4,7 +4,7 @@ "modid": "OpenComputers", "name": "OpenComputers", "description": "This mod adds modular computers and robots that can be programmed in Lua.", - "version": "1.1.2", + "version": "1.1.2a", "mcversion": "1.6.4", "url": "https://github.com/MightyPirates/OpenComputers/wiki", "authors": ["Florian 'Sangar' Nücke", "Johannes 'Lord Joda' Lohrer"],