Reworked redstone logic a little.

Moved computer signal generation to component (i.e. redstone cards) and only sending an internal message from blocks (e.g. computer cases).
Pulled wireless trait out of other component logic which allows creating it on its own, e.g. for tablets and drones.
This commit is contained in:
Florian Nücke 2015-01-15 12:59:22 +01:00
parent b13e72fd1b
commit 3dec0b24eb
13 changed files with 137 additions and 95 deletions

View File

@ -85,7 +85,7 @@ object EventHandler {
def scheduleWirelessRedstone(rs: server.component.RedstoneWireless) {
if (SideTracker.isServer) pending.synchronized {
pending += (() => if (!rs.owner.isInvalid) {
pending += (() => if (rs.node.network != null) {
util.WirelessRedstone.addReceiver(rs)
util.WirelessRedstone.updateOutput(rs)
})

View File

@ -7,8 +7,6 @@ import cpw.mods.fml.relauncher.SideOnly
import li.cil.oc.Settings
import li.cil.oc.common.GuiType
import li.cil.oc.common.tileentity
import li.cil.oc.integration.util.Wrench
import li.cil.oc.util.BlockPosition
import li.cil.oc.util.Color
import li.cil.oc.util.Rarity
import li.cil.oc.util.Tooltip

View File

@ -11,7 +11,11 @@ import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.util.ForgeDirection
class Redstone extends Environment with BundledRedstoneAware {
val instance = if (BundledRedstone.isAvailable) new component.Redstone[BundledRedstoneAware](this) with component.RedstoneBundled else new component.Redstone(this)
val instance =
if (BundledRedstone.isAvailable)
new component.Redstone.Bundled(this)
else
new component.Redstone.Vanilla(this)
val node = instance.node
if (node != null) {
node.setVisibility(Visibility.Network)

View File

@ -509,7 +509,7 @@ class ServerRack extends traits.PowerAcceptor with traits.Hub with traits.PowerB
override protected def onRedstoneInputChanged(side: ForgeDirection) {
super.onRedstoneInputChanged(side)
servers collect {
case Some(server) => server.machine.signal("redstone_changed", server.machine.node.address, Int.box(toLocal(side).ordinal()))
case Some(server) => server.machine.node.sendToNeighbors("redstone.changed", toLocal(side))
}
}

View File

@ -206,7 +206,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
override protected def onRedstoneInputChanged(side: ForgeDirection) {
super.onRedstoneInputChanged(side)
machine.signal("redstone_changed", machine.node.address, Int.box(toLocal(side).ordinal()))
machine.node.sendToNeighbors("redstone.changed", toLocal(side))
}
// ----------------------------------------------------------------------- //

View File

@ -32,7 +32,7 @@ object DriverBlockEnvironments extends driver.Block with EnvironmentAware {
else if (isOneOf(block.field_150939_a, "case1", "case2", "case3", "caseCreative", "microcontroller")) classOf[Machine]
else if (isOneOf(block.field_150939_a, "hologram1", "hologram2")) classOf[tileentity.Hologram]
else if (isOneOf(block.field_150939_a, "motionSensor")) classOf[tileentity.MotionSensor]
else if (isOneOf(block.field_150939_a, "redstone")) if (BundledRedstone.isAvailable) classOf[component.Redstone.Bundled] else classOf[component.Redstone.Simple]
else if (isOneOf(block.field_150939_a, "redstone")) if (BundledRedstone.isAvailable) classOf[component.Redstone.Bundled] else classOf[component.Redstone.Vanilla]
else if (isOneOf(block.field_150939_a, "screen1")) classOf[common.component.TextBuffer].asInstanceOf[Class[_ <: Environment]]
else if (isOneOf(block.field_150939_a, "screen2", "screen3")) classOf[common.component.Screen]
else if (isOneOf(block.field_150939_a, "robot")) classOf[component.robot.Robot].asInstanceOf[Class[_ <: Environment]]

View File

@ -19,16 +19,22 @@ import net.minecraft.item.ItemStack
object DriverRedstoneCard extends Item with HostAware with EnvironmentAware {
override def worksWith(stack: ItemStack) = isOneOf(stack, api.Items.get("redstoneCard1"), api.Items.get("redstoneCard2"))
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) =
override def createEnvironment(stack: ItemStack, host: EnvironmentHost) = {
val isAdvanced = tier(stack) == Tier.Two
val hasBundled = BundledRedstone.isAvailable && isAdvanced
val hasWireless = WirelessRedstone.isAvailable && isAdvanced
host match {
case redstone: BundledRedstoneAware if BundledRedstone.isAvailable && tier(stack) == Tier.Two =>
if (WirelessRedstone.isAvailable) new component.Redstone.BundledWireless(redstone)
case redstone: BundledRedstoneAware if hasBundled =>
if (hasWireless) new component.Redstone.BundledWireless(redstone)
else new component.Redstone.Bundled(redstone)
case redstone: RedstoneAware =>
if (tier(stack) == Tier.Two && WirelessRedstone.isAvailable) new component.Redstone.Wireless(redstone)
else new component.Redstone.Simple(redstone)
case _ => null
if (hasWireless) new component.Redstone.VanillaWireless(redstone)
else new component.Redstone.Vanilla(redstone)
case _ =>
if (hasWireless) new component.Redstone.Wireless(host)
else null
}
}
override def slot(stack: ItemStack) = Slot.Card
@ -38,15 +44,16 @@ object DriverRedstoneCard extends Item with HostAware with EnvironmentAware {
case _ => Tier.One
}
override def providedEnvironment(stack: ItemStack): Class[_ <: Environment] =
if (stack.getItemDamage == api.Items.get("redstoneCard1").createItemStack(1).getItemDamage)
classOf[component.Redstone[RedstoneAware]]
else if (BundledRedstone.isAvailable) {
if (WirelessRedstone.isAvailable) classOf[component.Redstone.BundledWireless]
override def providedEnvironment(stack: ItemStack): Class[_ <: Environment] = {
val isAdvanced = tier(stack) == Tier.Two
val hasBundled = BundledRedstone.isAvailable && isAdvanced
val hasWireless = WirelessRedstone.isAvailable && isAdvanced
if (hasBundled) {
if (hasWireless) classOf[component.Redstone.BundledWireless]
else classOf[component.Redstone.Bundled]
}
else {
if (WirelessRedstone.isAvailable) classOf[component.Redstone.Wireless]
else classOf[component.Redstone.Simple]
classOf[component.Redstone.Vanilla]
}
}
}

View File

@ -127,7 +127,6 @@ object ModOpenComputers extends ModProxy {
"keyboard",
"lanCard",
"redstoneCard1",
"redstoneCard2", // TODO Move back down to wireless section once wireless redstone can work on its own.
"screen1",
"angelUpgrade",
"craftingUpgrade",
@ -174,6 +173,7 @@ object ModOpenComputers extends ModProxy {
"leashUpgrade")
if (!WirelessRedstone.isAvailable) {
blacklistHost(classOf[internal.Drone], "redstoneCard2")
blacklistHost(classOf[internal.Tablet], "redstoneCard2")
}

View File

@ -2,6 +2,7 @@ package li.cil.oc.integration.wrsve
import li.cil.oc.integration.util.WirelessRedstone.WirelessRedstoneSystem
import li.cil.oc.server.component.RedstoneWireless
import li.cil.oc.util.BlockPosition
import net.minecraft.world.World
import scala.language.reflectiveCalls
@ -9,15 +10,15 @@ import scala.language.reflectiveCalls
object WirelessRedstoneSVE extends WirelessRedstoneSystem {
private val ether = try {
Option(Class.forName("net.slimevoid.wirelessredstone.ether.RedstoneEther").getMethod("getInstance").invoke(null).asInstanceOf[ {
def addTransmitter(world: World, x: Int, y: Int, z: Int, frequency: AnyRef)
def addTransmitter(world: World, x: Int, y: Int, z: Int, frequency: AnyRef): Unit
def remTransmitter(world: World, x: Int, y: Int, z: Int, frequency: AnyRef)
def remTransmitter(world: World, x: Int, y: Int, z: Int, frequency: AnyRef): Unit
def addReceiver(world: World, x: Int, y: Int, z: Int, frequency: AnyRef)
def addReceiver(world: World, x: Int, y: Int, z: Int, frequency: AnyRef): Unit
def remReceiver(world: World, x: Int, y: Int, z: Int, frequency: AnyRef)
def remReceiver(world: World, x: Int, y: Int, z: Int, frequency: AnyRef): Unit
def setTransmitterState(world: World, x: Int, y: Int, z: Int, frequency: AnyRef, state: Boolean)
def setTransmitterState(world: World, x: Int, y: Int, z: Int, frequency: AnyRef, state: Boolean): Unit
def getFreqState(world: World, frequency: AnyRef): Boolean
}])
@ -27,25 +28,25 @@ object WirelessRedstoneSVE extends WirelessRedstoneSystem {
}
def removeTransmitter(rs: RedstoneWireless) {
val te = rs.owner
ether.foreach(_.remTransmitter(te.world, te.x, te.y, te.z, rs.wirelessFrequency.toString))
val blockPos = BlockPosition(rs.redstone)
ether.foreach(_.remTransmitter(rs.redstone.world, blockPos.x, blockPos.y, blockPos.z, rs.wirelessFrequency.toString))
}
def addReceiver(rs: RedstoneWireless) {
val te = rs.owner
ether.foreach(_.addReceiver(te.world, te.x, te.y, te.z, rs.wirelessFrequency.toString))
val blockPos = BlockPosition(rs.redstone)
ether.foreach(_.addReceiver(rs.redstone.world, blockPos.x, blockPos.y, blockPos.z, rs.wirelessFrequency.toString))
}
def removeReceiver(rs: RedstoneWireless) {
val te = rs.owner
ether.foreach(_.remReceiver(te.world, te.x, te.y, te.z, rs.wirelessFrequency.toString))
val blockPos = BlockPosition(rs.redstone)
ether.foreach(_.remReceiver(rs.redstone.world, blockPos.x, blockPos.y, blockPos.z, rs.wirelessFrequency.toString))
}
def updateOutput(rs: RedstoneWireless) {
val te = rs.owner
ether.foreach(_.addTransmitter(te.world, te.x, te.y, te.z, rs.wirelessFrequency.toString))
ether.foreach(_.setTransmitterState(te.world, te.x, te.y, te.z, rs.wirelessFrequency.toString, rs.wirelessOutput))
val blockPos = BlockPosition(rs.redstone)
ether.foreach(_.addTransmitter(rs.redstone.world, blockPos.x, blockPos.y, blockPos.z, rs.wirelessFrequency.toString))
ether.foreach(_.setTransmitterState(rs.redstone.world, blockPos.x, blockPos.y, blockPos.z, rs.wirelessFrequency.toString, rs.wirelessOutput))
}
def getInput(rs: RedstoneWireless) = ether.fold(false)(_.getFreqState(rs.owner.world, rs.wirelessFrequency.toString))
def getInput(rs: RedstoneWireless) = ether.fold(false)(_.getFreqState(rs.redstone.world, rs.wirelessFrequency.toString))
}

View File

@ -1,62 +1,25 @@
package li.cil.oc.server.component
import li.cil.oc.api.Network
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import li.cil.oc.api.prefab
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
import li.cil.oc.common.tileentity.traits.RedstoneAware
import li.cil.oc.server.component
import net.minecraftforge.common.util.ForgeDirection
class Redstone[+Owner <: RedstoneAware](val owner: Owner) extends prefab.ManagedEnvironment {
override val node = Network.newNode(this, Visibility.Network).
withComponent("redstone", Visibility.Neighbors).
create()
// ----------------------------------------------------------------------- //
@Callback(direct = true, doc = """function(side:number):number -- Get the redstone input on the specified side.""")
def getInput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
result(owner.input(side))
}
@Callback(direct = true, doc = """function(side:number):number -- Get the redstone output on the specified side.""")
def getOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
result(owner.output(side))
}
@Callback(doc = """function(side:number, value:number):number -- Set the redstone output on the specified side.""")
def setOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val value = args.checkInteger(1)
owner.output(side, value)
context.pause(0.1)
result(owner.output(side))
}
// ----------------------------------------------------------------------- //
protected def checkSide(args: Arguments, index: Int) = {
val side = args.checkInteger(index)
if (side < 0 || side > 5)
throw new IllegalArgumentException("invalid side")
owner.toGlobal(ForgeDirection.getOrientation(side))
}
}
object Redstone {
class Simple(redstone: RedstoneAware) extends component.Redstone[RedstoneAware](redstone)
class Vanilla(val redstone: EnvironmentHost with RedstoneAware)
extends component.RedstoneVanilla
class Bundled(redstone: BundledRedstoneAware) extends component.Redstone[BundledRedstoneAware](redstone) with component.RedstoneBundled
class Bundled(val redstone: EnvironmentHost with BundledRedstoneAware)
extends component.RedstoneVanilla with component.RedstoneBundled
class Wireless(redstone: RedstoneAware) extends Simple(redstone) with component.RedstoneWireless
class Wireless(val redstone: EnvironmentHost)
extends component.RedstoneWireless
class BundledWireless(redstone: BundledRedstoneAware) extends Bundled(redstone) with component.RedstoneWireless
class VanillaWireless(val redstone: EnvironmentHost with RedstoneAware)
extends component.RedstoneVanilla with component.RedstoneWireless
class BundledWireless(val redstone: EnvironmentHost with BundledRedstoneAware)
extends component.RedstoneVanilla with component.RedstoneBundled with component.RedstoneWireless
}

View File

@ -1,23 +1,26 @@
package li.cil.oc.server.component
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
trait RedstoneBundled extends Redstone[BundledRedstoneAware] {
trait RedstoneBundled extends RedstoneVanilla {
override def redstone: EnvironmentHost with BundledRedstoneAware
@Callback(direct = true, doc = """function(side:number, color:number):number -- Get the bundled redstone input on the specified side and with the specified color.""")
def getBundledInput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val color = checkColor(args, 1)
result(owner.bundledInput(side, color))
result(redstone.bundledInput(side, color))
}
@Callback(direct = true, doc = """function(side:number, color:number):number -- Get the bundled redstone output on the specified side and with the specified color.""")
def getBundledOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val color = checkColor(args, 1)
result(owner.bundledOutput(side, color))
result(redstone.bundledOutput(side, color))
}
@Callback(doc = """function(side:number, color:number, value:number):number -- Set the bundled redstone output on the specified side and with the specified color.""")
@ -26,7 +29,7 @@ trait RedstoneBundled extends Redstone[BundledRedstoneAware] {
if (args.isTable(1)) {
val table = args.checkTable(1)
(0 to 15).map(color => (color, table.get(color))).foreach {
case (color, number: Number) => owner.bundledOutput(side, color, number.intValue())
case (color, number: Number) => redstone.bundledOutput(side, color, number.intValue())
case _ =>
}
context.pause(0.1)
@ -35,9 +38,9 @@ trait RedstoneBundled extends Redstone[BundledRedstoneAware] {
else {
val color = checkColor(args, 1)
val value = args.checkInteger(2)
owner.bundledOutput(side, color, value)
redstone.bundledOutput(side, color, value)
context.pause(0.1)
result(owner.bundledOutput(side, color))
result(redstone.bundledOutput(side, color))
}
}

View File

@ -0,0 +1,63 @@
package li.cil.oc.server.component
import li.cil.oc.api.Network
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import li.cil.oc.api.prefab
import li.cil.oc.common.tileentity.traits.BundledRedstoneAware
import li.cil.oc.common.tileentity.traits.RedstoneAware
import li.cil.oc.server.component
import net.minecraftforge.common.util.ForgeDirection
trait RedstoneVanilla extends prefab.ManagedEnvironment {
override val node = Network.newNode(this, Visibility.Network).
withComponent("redstone", Visibility.Neighbors).
create()
def redstone: EnvironmentHost with RedstoneAware
// ----------------------------------------------------------------------- //
@Callback(direct = true, doc = """function(side:number):number -- Get the redstone input on the specified side.""")
def getInput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
result(redstone.input(side))
}
@Callback(direct = true, doc = """function(side:number):number -- Get the redstone output on the specified side.""")
def getOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
result(redstone.output(side))
}
@Callback(doc = """function(side:number, value:number):number -- Set the redstone output on the specified side.""")
def setOutput(context: Context, args: Arguments): Array[AnyRef] = {
val side = checkSide(args, 0)
val value = args.checkInteger(1)
redstone.output(side, value)
context.pause(0.1)
result(redstone.output(side))
}
// ----------------------------------------------------------------------- //
override def onMessage(message: Message): Unit = {
super.onMessage(message)
if (message.name == "redstone.changed") message.data match {
case Array(side: ForgeDirection) => node.sendToReachable("computer.signal", "redstone_changed", Int.box(side.ordinal()))
case _ =>
}
}
// ----------------------------------------------------------------------- //
protected def checkSide(args: Arguments, index: Int) = {
val side = args.checkInteger(index)
if (side < 0 || side > 5)
throw new IllegalArgumentException("invalid side")
redstone.toGlobal(ForgeDirection.getOrientation(side))
}
}

View File

@ -4,12 +4,13 @@ import codechicken.lib.vec.Vector3
import codechicken.wirelessredstone.core.WirelessReceivingDevice
import codechicken.wirelessredstone.core.WirelessTransmittingDevice
import cpw.mods.fml.common.Optional
import li.cil.oc.api.driver.EnvironmentHost
import li.cil.oc.api.machine.Arguments
import li.cil.oc.api.machine.Callback
import li.cil.oc.api.machine.Context
import li.cil.oc.api.network._
import li.cil.oc.api.prefab
import li.cil.oc.common.EventHandler
import li.cil.oc.common.tileentity.traits.RedstoneAware
import li.cil.oc.integration.Mods
import li.cil.oc.integration.util
import net.minecraft.nbt.NBTTagCompound
@ -18,7 +19,9 @@ import net.minecraft.nbt.NBTTagCompound
new Optional.Interface(iface = "codechicken.wirelessredstone.core.WirelessReceivingDevice", modid = Mods.IDs.WirelessRedstoneCBE),
new Optional.Interface(iface = "codechicken.wirelessredstone.core.WirelessTransmittingDevice", modid = Mods.IDs.WirelessRedstoneCBE)
))
trait RedstoneWireless extends Redstone[RedstoneAware] with WirelessReceivingDevice with WirelessTransmittingDevice {
trait RedstoneWireless extends prefab.ManagedEnvironment with WirelessReceivingDevice with WirelessTransmittingDevice {
def redstone: EnvironmentHost
var wirelessFrequency = 0
var wirelessInput = false
@ -79,10 +82,10 @@ trait RedstoneWireless extends Redstone[RedstoneAware] with WirelessReceivingDev
}
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getPosition = Vector3.fromTileEntityCenter(owner)
override def getPosition = new Vector3(redstone.xPosition, redstone.yPosition, redstone.zPosition)
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getDimension = owner.world.provider.dimensionId
override def getDimension = redstone.world.provider.dimensionId
@Optional.Method(modid = Mods.IDs.WirelessRedstoneCBE)
override def getFreq = wirelessFrequency