Added scan method for abstract bus.

This commit is contained in:
Florian Nücke 2014-06-04 20:46:50 +02:00
parent d55343116a
commit 0e6963d3d9
3 changed files with 56 additions and 25 deletions

View File

@ -85,6 +85,7 @@ class Proxy {
api.Driver.add(driver.item.WirelessNetworkCard)
if (Mods.StargateTech2.isAvailable) {
api.Driver.add(driver.converter.BusPacketNetScanDevice)
api.Driver.add(driver.item.AbstractBusCard)
}
if (Mods.ComputerCraft15.isAvailable) {

View File

@ -21,7 +21,7 @@ class AbstractBus(val device: IBusDevice) extends component.ManagedComponent wit
protected var address = 0
protected var sendQueue: Option[QueuedPacket] = None
protected var sendQueue: Option[BusPacket[_]] = None
protected var owner: Option[Context] = None
@ -40,18 +40,11 @@ class AbstractBus(val device: IBusDevice) extends component.ManagedComponent wit
owner.foreach(_.signal("bus_message", Int.box(packet.getProtocolID), Int.box(packet.getSender), Int.box(packet.getTarget), data, metadata))
}
override def getNextPacketToSend = if (sendQueue.isDefined) {
val info = sendQueue.get
override def getNextPacketToSend = this.synchronized {
val packet = sendQueue.orNull
sendQueue = None
val packet = new BusPacketLIP(info.sender, info.target)
for ((key, value) <- info.data) {
packet.set(key, value)
}
packet.setMetadata(new BusPacketLIP.LIPMetadata("OpenComputers", node.address, null))
packet.finish()
packet
}
else null
override def isInterfaceEnabled = isEnabled
@ -78,17 +71,46 @@ class AbstractBus(val device: IBusDevice) extends component.ManagedComponent wit
}
@Callback(doc = """function(address:number, data:table):boolean -- Sends data across the abstract bus.""")
def send(context: Context, args: Arguments): Array[AnyRef] = {
def send(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
val target = args.checkInteger(0) & 0xFFFF
val data = args.checkTable(1)
if (node.tryChangeBuffer(-Settings.get.abstractBusPacketCost)) {
sendQueue = Some(new QueuedPacket(address.toShort, target.toShort, Map(data.toSeq.map(entry => (entry._1.toString, entry._2.toString)): _*)))
val packet = new BusPacketLIP(address.toShort, target.toShort)
var size = 0
def checkSize(add: Int) {
size += add
if (size > Settings.get.maxNetworkPacketSize) {
throw new IllegalArgumentException("packet too big (max " + Settings.get.maxNetworkPacketSize + ")")
}
}
for ((key, value) <- data) {
val keyAsString = key.toString
checkSize(keyAsString.length)
val valueAsString = value.toString
checkSize(valueAsString.length)
packet.set(keyAsString, valueAsString)
}
packet.setMetadata(new BusPacketLIP.LIPMetadata("OpenComputers", node.address, null))
packet.finish()
sendQueue = Some(packet)
busInterface.sendAllPackets()
result(true)
}
else result(Unit, "not enough energy")
}
@Callback(doc = """function(mask:number):table -- Scans the network for other devices.""")
def scan(context: Context, args: Arguments): Array[AnyRef] = this.synchronized {
val mask = (args.checkInteger(0) & 0xFFFF).toShort
if (node.tryChangeBuffer(-Settings.get.abstractBusPacketCost)) {
val packet = new BusPacketNetScan(mask)
sendQueue = Some(packet)
busInterface.sendAllPackets()
Array(packet.getDevices.toArray)
}
else Array(Unit, "not enough energy")
}
@Callback(direct = true, doc = """function():number -- The maximum packet size that can be sent over the bus.""")
def maxPacketSize(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.maxNetworkPacketSize)
@ -124,17 +146,4 @@ class AbstractBus(val device: IBusDevice) extends component.ManagedComponent wit
nbt.setBoolean("enabled", isEnabled)
nbt.setInteger("address", address)
}
protected class QueuedPacket(val sender: Short, val target: Short, val data: Map[String, String]) {
// Extra braces because we don't want/have to keep size as a field.
{
val size = data.foldLeft(0)((acc, arg) => {
acc + arg._1.length + arg._2.length
})
if (size > Settings.get.maxNetworkPacketSize) {
throw new IllegalArgumentException("packet too big (max " + Settings.get.maxNetworkPacketSize + ")")
}
}
}
}

View File

@ -0,0 +1,21 @@
package li.cil.oc.server.driver.converter
import java.util
import li.cil.oc.api
import scala.collection.convert.WrapAsScala._
import stargatetech2.api.bus.BusPacketNetScan
object BusPacketNetScanDevice extends api.driver.Converter {
override def convert(value: scala.Any, output: util.Map[AnyRef, AnyRef]) =
value match {
case device: BusPacketNetScan.Device =>
output += "address" -> Short.box(device.address)
output += "name" -> device.name
output += "description" -> device.description
output += "enabled" -> Boolean.box(device.enabled)
output += "x" -> Int.box(device.x)
output += "y" -> Int.box(device.y)
output += "z" -> Int.box(device.z)
case _ =>
}
}