extracted router into parent trait and implementing that in the server rack

This commit is contained in:
Florian Nücke 2014-01-16 14:39:51 +01:00
parent b07c3e202f
commit e94dd03df5
5 changed files with 116 additions and 90 deletions

View File

@ -98,7 +98,7 @@ abstract class Computer(isRemote: Boolean) extends Environment with ComponentInv
// the network. We skip the update this round to allow other tile entities
// to join the network, too, avoiding issues of missing nodes (e.g. in the
// GPU which would otherwise loose track of its screen).
if (node != null && node.network != null) {
if (addedToNetwork) {
computer.update()
if (hasChanged) {

View File

@ -0,0 +1,69 @@
package li.cil.oc.common.tileentity
import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.api.network.{Node, Message, Visibility, SidedEnvironment}
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.{api, Settings}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.ForgeDirection
trait Hub extends Environment with SidedEnvironment {
protected val plugs = ForgeDirection.VALID_DIRECTIONS.map(side => new Plug(side))
// ----------------------------------------------------------------------- //
def node = null
@SideOnly(Side.CLIENT)
def canConnect(side: ForgeDirection) = true
def sidedNode(side: ForgeDirection) = plugs(side.ordinal()).node
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
nbt.getTagList(Settings.namespace + "plugs").iterator[NBTTagCompound].zip(plugs).foreach {
case (plugNbt, plug) => plug.node.load(plugNbt)
}
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
nbt.setNewTagList(Settings.namespace + "plugs", plugs.map(plug => {
val plugNbt = new NBTTagCompound()
plug.node.save(plugNbt)
plugNbt
}))
}
// ----------------------------------------------------------------------- //
protected class Plug(val side: ForgeDirection) extends api.network.Environment {
val node = api.Network.newNode(this, Visibility.Network).create()
def onMessage(message: Message) {
if (isPrimary) {
onPlugMessage(this, message)
}
}
def onConnect(node: Node) = onPlugConnect(this, node)
def onDisconnect(node: Node) = onPlugDisconnect(this, node)
def isPrimary = plugs(plugs.indexWhere(_.node.network == node.network)) == this
def plugsInOtherNetworks = plugs.filter(_.node.network != node.network)
}
protected def onPlugConnect(plug: Plug, node: Node) {}
protected def onPlugDisconnect(plug: Plug, node: Node) {}
protected def onPlugMessage(plug: Plug, message: Message) {
if (message.name == "network.message") {
plug.plugsInOtherNetworks.foreach(_.node.sendToReachable(message.name, message.data: _*))
}
}
}

View File

@ -2,10 +2,10 @@ package li.cil.oc.common.tileentity
import cpw.mods.fml.common.Optional
import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.api.network.{Node, Analyzable, Visibility}
import li.cil.oc.api.network.{Node, Analyzable}
import li.cil.oc.server.{PacketSender => ServerPacketSender, driver, component}
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.{Items, Settings, api}
import li.cil.oc.{Items, Settings}
import net.minecraft.entity.player.EntityPlayer
import net.minecraft.item.ItemStack
import net.minecraft.nbt.NBTTagCompound
@ -14,11 +14,11 @@ import stargatetech2.api.bus.IBusDevice
// See AbstractBusAware as to why we have to define the IBusDevice here.
@Optional.Interface(iface = "stargatetech2.api.bus.IBusDevice", modid = "StargateTech2")
class Rack extends Environment with Inventory with Rotatable with BundledRedstoneAware with AbstractBusAware with IBusDevice with Analyzable {
val node = api.Network.newNode(this, Visibility.None).create()
class Rack extends Hub with Inventory with Rotatable with BundledRedstoneAware with AbstractBusAware with IBusDevice with Analyzable {
val servers = Array.fill(getSizeInventory)(None: Option[component.Server])
val sides = Array.fill(servers.length)(ForgeDirection.UNKNOWN)
// For client side, where we don't create the component.
private val _isRunning = new Array[Boolean](getSizeInventory)
@ -29,6 +29,10 @@ class Rack extends Environment with Inventory with Rotatable with BundledRedston
// ----------------------------------------------------------------------- //
override def canConnect(side: ForgeDirection) = side != facing
// ----------------------------------------------------------------------- //
def isRunning(number: Int) =
if (isServer) servers(number).fold(false)(_.machine.isRunning)
else _isRunning(number)
@ -69,6 +73,19 @@ class Rack extends Environment with Inventory with Rotatable with BundledRedston
case _ => false
}
def reconnectServer(number: Int, server: component.Server) {
val serverSide = sides(number)
val serverNode = server.machine.node
for (side <- ForgeDirection.VALID_DIRECTIONS) {
if (serverSide == side || serverSide == ForgeDirection.UNKNOWN) {
sidedNode(side).connect(serverNode)
}
else {
sidedNode(side).disconnect(serverNode)
}
}
}
// ----------------------------------------------------------------------- //
def getSizeInventory = 4
@ -97,7 +114,7 @@ class Rack extends Environment with Inventory with Rotatable with BundledRedston
override def updateEntity() {
if (isServer) {
if (node != null && node.network != null) {
if (addedToNetwork) {
servers collect {
case Some(server) => server.machine.update()
}
@ -170,11 +187,15 @@ class Rack extends Environment with Inventory with Rotatable with BundledRedston
// ----------------------------------------------------------------------- //
override def onConnect(node: Node) {
super.onConnect(node)
if (node == this.node) {
servers collect {
case Some(server) => node.connect(server.machine.node)
override protected def onPlugConnect(plug: Plug, node: Node) {
if (node == plug.node) {
for (number <- 0 until servers.length) {
val serverSide = sides(number)
servers(number) match {
case Some(server) if serverSide == plug.side || serverSide == ForgeDirection.UNKNOWN =>
plug.node.connect(server.machine.node)
case _ =>
}
}
}
}
@ -184,7 +205,7 @@ class Rack extends Environment with Inventory with Rotatable with BundledRedston
if (isServer) {
val server = new component.Server(this, slot)
servers(slot) = Some(server)
node.connect(server.machine.node)
reconnectServer(slot, server)
}
}

View File

@ -1,27 +1,13 @@
package li.cil.oc.common.tileentity
import cpw.mods.fml.common.{Loader, Optional}
import cpw.mods.fml.relauncher.{Side, SideOnly}
import dan200.computer.api.{ILuaContext, IComputerAccess, IPeripheral}
import li.cil.oc.api.network.{Node, Message, Visibility}
import li.cil.oc.util.ExtendedNBT._
import li.cil.oc.{Blocks, Settings, api}
import net.minecraft.nbt.NBTTagCompound
import net.minecraftforge.common.ForgeDirection
import li.cil.oc.Blocks
import li.cil.oc.api.network.Message
import scala.collection.mutable
@Optional.Interface(iface = "dan200.computer.api.IPeripheral", modid = "ComputerCraft")
class Router extends TileEntity with api.network.SidedEnvironment with IPeripheral with PassiveNode {
private val plugs = ForgeDirection.VALID_DIRECTIONS.map(side => new Plug(side))
// ----------------------------------------------------------------------- //
@SideOnly(Side.CLIENT)
def canConnect(side: ForgeDirection) = true
def sidedNode(side: ForgeDirection) = plugs(side.ordinal()).node
// ----------------------------------------------------------------------- //
class Router extends Hub with IPeripheral with PassiveNode {
override def canUpdate = false
@ -30,38 +16,6 @@ class Router extends TileEntity with api.network.SidedEnvironment with IPeripher
worldObj.scheduleBlockUpdateFromLoad(xCoord, yCoord, zCoord, Blocks.router.parent.blockID, 0, 0)
}
override def invalidate() {
super.invalidate()
for (plug <- plugs if plug.node != null) {
plug.node.remove()
}
}
override def onChunkUnload() {
super.onChunkUnload()
for (plug <- plugs if plug.node != null) {
plug.node.remove()
}
}
// ----------------------------------------------------------------------- //
override def readFromNBT(nbt: NBTTagCompound) {
super.readFromNBT(nbt)
nbt.getTagList(Settings.namespace + "plugs").iterator[NBTTagCompound].zip(plugs).foreach {
case (plugNbt, plug) => plug.node.load(plugNbt)
}
}
override def writeToNBT(nbt: NBTTagCompound) {
super.writeToNBT(nbt)
nbt.setNewTagList(Settings.namespace + "plugs", plugs.map(plug => {
val plugNbt = new NBTTagCompound()
plug.node.save(plugNbt)
plugNbt
}))
}
// ----------------------------------------------------------------------- //
// Peripheral
@ -124,8 +78,6 @@ class Router extends TileEntity with api.network.SidedEnvironment with IPeripher
port
}
// ----------------------------------------------------------------------- //
private def queueMessage(port: Int, answerPort: Int, args: Seq[AnyRef]) {
for (computer <- computers.map(_.asInstanceOf[IComputerAccess])) {
if (openPorts(computer).contains(port))
@ -136,31 +88,16 @@ class Router extends TileEntity with api.network.SidedEnvironment with IPeripher
}
}
private class Plug(val side: ForgeDirection) extends api.network.Environment {
val node = api.Network.newNode(this, Visibility.Network).create()
def onMessage(message: Message) {
if (isPrimary && message.name == "network.message") {
plugsInOtherNetworks.foreach(_.node.sendToReachable(message.name, message.data: _*))
if (Loader.isModLoaded("ComputerCraft")) {
message.data match {
case Array(port: Integer, answerPort: java.lang.Double, args@_*) =>
queueMessage(port, answerPort.toInt, args)
case Array(port: Integer, args@_*) =>
queueMessage(port, -1, args)
case _ =>
}
}
override protected def onPlugMessage(plug: Plug, message: Message) {
super.onPlugMessage(plug, message)
if (message.name == "network.message" && Loader.isModLoaded("ComputerCraft")) {
message.data match {
case Array(port: Integer, answerPort: java.lang.Double, args@_*) =>
queueMessage(port, answerPort.toInt, args)
case Array(port: Integer, args@_*) =>
queueMessage(port, -1, args)
case _ =>
}
}
def onDisconnect(node: Node) {}
def onConnect(node: Node) {}
private def isPrimary = plugs(plugs.indexWhere(_.node.network == node.network)) == this
private def plugsInOtherNetworks = plugs.filter(_.node.network != node.network)
}
}

View File

@ -718,8 +718,7 @@ class Machine(val owner: Machine.Owner) extends ManagedComponent with Context wi
state.push(Machine.State.Yielded)
state.push(Machine.State.Paused)
case Machine.State.Stopping => // Nothing to do, we'll die anyway.
case _ => throw new AssertionError(
"Invalid state in executor post-processing.")
case _ => throw new AssertionError("Invalid state in executor post-processing.")
}
assert(state.top != Machine.State.Running)
}