Made architecture dynamically defined via the host, reads arch from installed CPU.

This commit is contained in:
Florian Nücke 2014-09-20 09:20:59 +02:00
parent 691fbfd0c9
commit c4989e44e7
18 changed files with 136 additions and 91 deletions

View File

@ -46,24 +46,7 @@ public final class Machine {
} }
/** /**
* Creates a new machine using the specified architecture. * Creates a new machine for the specified host.
* <p/>
* You are responsible for calling update and save / load functions on the
* machine for it to work correctly.
*
* @param host the owner object of the machine, providing context.
* @param architecture the architecture to use for running code on the machine.
* @return the newly created machine.
* @throws IllegalArgumentException if the specified architecture is invalid.
*/
public static li.cil.oc.api.machine.Machine create(MachineHost host, Class<? extends Architecture> architecture) {
if (instance != null)
return instance.create(host, architecture);
return null;
}
/**
* Creates a new machine using the default architecture (Lua).
* <p/> * <p/>
* You are responsible for calling update and save / load functions on the * You are responsible for calling update and save / load functions on the
* machine for it to work correctly. * machine for it to work correctly.
@ -73,7 +56,7 @@ public final class Machine {
*/ */
public static li.cil.oc.api.machine.Machine create(MachineHost host) { public static li.cil.oc.api.machine.Machine create(MachineHost host) {
if (instance != null) if (instance != null)
return instance.create(host, LuaArchitecture); return instance.create(host);
return null; return null;
} }

View File

@ -20,7 +20,7 @@ public interface MachineAPI {
* A list of all <em>registered</em> architectures. * A list of all <em>registered</em> architectures.
* <p/> * <p/>
* Note that registration is optional, although automatic when calling * Note that registration is optional, although automatic when calling
* {@link #create(li.cil.oc.api.machine.MachineHost, Class)} with a not yet * {@link #create(li.cil.oc.api.machine.MachineHost)} with a not yet
* registered architecture. What this means is that unless a mod providing * registered architecture. What this means is that unless a mod providing
* a custom architecture also registers it, you may not see it in this list * a custom architecture also registers it, you may not see it in this list
* until it also created a new machine using that architecture. * until it also created a new machine using that architecture.
@ -28,15 +28,14 @@ public interface MachineAPI {
Iterable<Class<? extends Architecture>> architectures(); Iterable<Class<? extends Architecture>> architectures();
/** /**
* Creates a new machine using the specified architecture. * Creates a new machine for the specified host.
* <p/> * <p/>
* You are responsible for calling update and save / load functions on the * You are responsible for calling update and save / load functions on the
* machine for it to work correctly. * machine for it to work correctly.
* *
* @param host the owner object of the machine, providing context. * @param host the owner object of the machine, providing context.
* @param architecture the architecture to use for running code on the machine.
* @return the newly created machine. * @return the newly created machine.
* @throws IllegalArgumentException if the specified architecture is invalid. * @throws IllegalArgumentException if the specified architecture is invalid.
*/ */
Machine create(MachineHost host, Class<? extends Architecture> architecture); Machine create(MachineHost host);
} }

View File

@ -29,7 +29,8 @@ public interface Processor extends Item {
* as computer cases, server racks and robots, it my not be true for third- * as computer cases, server racks and robots, it my not be true for third-
* party computers). * party computers).
* *
* @param stack the stack representing the CPU to get the architecture for.
* @return the type of this CPU's architecture. * @return the type of this CPU's architecture.
*/ */
Class<? extends Architecture> architecture(); Class<? extends Architecture> architecture(ItemStack stack);
} }

View File

@ -24,11 +24,28 @@ public interface Machine extends ManagedEnvironment, Context {
* <p/> * <p/>
* This is what actually evaluates code running on the machine, where the * This is what actually evaluates code running on the machine, where the
* machine class itself serves as a scheduler. * machine class itself serves as a scheduler.
* <p/>
* This may be <tt>null</tt>, for example when the hosting computer has
* no CPU installed.
* *
* @return the architecture of this machine. * @return the architecture of this machine.
*/ */
Architecture architecture(); Architecture architecture();
/**
* Get the address of the file system component from which to try to boot.
* <p/>
* The underlying architecture may choose to ignore this setting.
*/
String getBootAddress();
/**
* Set the address of the file system component from which to try to boot.
*
* @param value the new address to try to boot from.
*/
void setBootAddress(String value);
/** /**
* The list of components attached to this machine. * The list of components attached to this machine.
* <p/> * <p/>

View File

@ -34,6 +34,17 @@ public interface MachineHost extends Context {
*/ */
World world(); World world();
/**
* Get the architecture to use in the hosted machine.
* <p/>
* This can be a static architecture type, but will usually be based on the
* CPU installed in the host (for example, this is true for computer cases,
* servers, robots and tablets).
*
* @return the architecture of the installed CPU, or <tt>null</tt>.
*/
Class<? extends Architecture> cpuArchitecture();
/** /**
* The amount of memory (RAM) made available to the machine, in bytes. * The amount of memory (RAM) made available to the machine, in bytes.
* <p/> * <p/>

View File

@ -108,7 +108,7 @@ class RobotProxy extends RedstoneAware with SpecialBlock {
val bounds = getCollisionBoundingBoxFromPool(world, x, y, z) val bounds = getCollisionBoundingBoxFromPool(world, x, y, z)
world.getTileEntity(x, y, z) match { world.getTileEntity(x, y, z) match {
case proxy: tileentity.RobotProxy if proxy.robot.animationTicksLeft <= 0 && bounds.isVecInside(origin) => null case proxy: tileentity.RobotProxy if proxy.robot.animationTicksLeft <= 0 && bounds.isVecInside(origin) => null
case _ => super.collisionRayTrace(world, x, y, z, origin, direction) case _ => super.intersect(world, x, y, z, origin, direction)
} }
} }

View File

@ -7,12 +7,12 @@ import com.google.common.cache.{CacheBuilder, RemovalListener, RemovalNotificati
import cpw.mods.fml.common.eventhandler.SubscribeEvent import cpw.mods.fml.common.eventhandler.SubscribeEvent
import cpw.mods.fml.common.gameevent.TickEvent.{ClientTickEvent, ServerTickEvent} import cpw.mods.fml.common.gameevent.TickEvent.{ClientTickEvent, ServerTickEvent}
import cpw.mods.fml.relauncher.{Side, SideOnly} import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.api.Machine import li.cil.oc.api.{Driver, Machine}
import li.cil.oc.api.driver.EnvironmentHost import li.cil.oc.api.driver.{Processor, EnvironmentHost}
import li.cil.oc.api.machine.MachineHost import li.cil.oc.api.machine.{Architecture, MachineHost}
import li.cil.oc.api.network.{Connector, Message, Node} import li.cil.oc.api.network.{Connector, Message, Node}
import li.cil.oc.api.tileentity.Rotatable import li.cil.oc.api.tileentity.Rotatable
import li.cil.oc.common.GuiType import li.cil.oc.common.{Slot, GuiType}
import li.cil.oc.common.inventory.ComponentInventory import li.cil.oc.common.inventory.ComponentInventory
import li.cil.oc.util.ItemUtils.TabletData import li.cil.oc.util.ItemUtils.TabletData
import li.cil.oc.util.RotationHelper import li.cil.oc.util.RotationHelper
@ -184,6 +184,17 @@ class TabletWrapper(var stack: ItemStack, var holder: Entity) extends ComponentI
override def world = holder.worldObj override def world = holder.worldObj
override def cpuArchitecture: Class[_ <: Architecture] = {
for (i <- 0 until getSizeInventory if isComponentSlot(i)) Option(getStackInSlot(i)) match {
case Some(s) => Option(Driver.driverFor(s)) match {
case Some(driver: Processor) if driver.slot(s) == Slot.CPU => return driver.architecture(s)
case _ =>
}
case _ =>
}
null
}
override def installedMemory = items.foldLeft(0)((acc, itemOption) => acc + (itemOption match { override def installedMemory = items.foldLeft(0)((acc, itemOption) => acc + (itemOption match {
case Some(item) => Option(api.Driver.driverFor(item)) match { case Some(item) => Option(api.Driver.driverFor(item)) match {
case Some(driver: api.driver.Memory) => driver.amount(item) case Some(driver: api.driver.Memory) => driver.amount(item)

View File

@ -60,13 +60,7 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with
override def componentSlot(address: String) = components.indexWhere(_.exists(env => env.node != null && env.node.address == address)) override def componentSlot(address: String) = components.indexWhere(_.exists(env => env.node != null && env.node.address == address))
def hasCPU = items.exists { def hasCPU = cpuArchitecture != null
case Some(stack) => Option(Driver.driverFor(stack)) match {
case Some(driver) => driver.slot(stack) == Slot.CPU
case _ => false
}
case _ => false
}
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
@ -98,15 +92,23 @@ class Case(var tier: Int) extends traits.PowerAcceptor with traits.Computer with
override protected def onItemAdded(slot: Int, stack: ItemStack) { override protected def onItemAdded(slot: Int, stack: ItemStack) {
super.onItemAdded(slot, stack) super.onItemAdded(slot, stack)
if (InventorySlots.computer(tier)(slot).slot == Slot.Floppy) { if (isServer) {
common.Sound.playDiskInsert(this) if (InventorySlots.computer(tier)(slot).slot == Slot.Floppy) {
common.Sound.playDiskInsert(this)
}
} }
} }
override protected def onItemRemoved(slot: Int, stack: ItemStack) { override protected def onItemRemoved(slot: Int, stack: ItemStack) {
super.onItemRemoved(slot, stack) super.onItemRemoved(slot, stack)
if (InventorySlots.computer(tier)(slot).slot == Slot.Floppy) { if (isServer) {
common.Sound.playDiskEject(this) val slotType = InventorySlots.computer(tier)(slot).slot
if (slotType == Slot.Floppy) {
common.Sound.playDiskEject(this)
}
if (slotType == Slot.CPU) {
stop()
}
} }
} }

View File

@ -323,7 +323,7 @@ class Robot extends traits.Computer with traits.PowerInformation with tileentity
info.load(nbt) info.load(nbt)
updateInventorySize() updateInventorySize()
computer.architecture.recomputeMemory() Option(computer.architecture).foreach(_.recomputeMemory())
bot.load(nbt.getCompoundTag(Settings.namespace + "robot")) bot.load(nbt.getCompoundTag(Settings.namespace + "robot"))
if (nbt.hasKey(Settings.namespace + "owner")) { if (nbt.hasKey(Settings.namespace + "owner")) {

View File

@ -2,11 +2,13 @@ package li.cil.oc.common.tileentity.traits
import cpw.mods.fml.common.Optional import cpw.mods.fml.common.Optional
import cpw.mods.fml.relauncher.{Side, SideOnly} import cpw.mods.fml.relauncher.{Side, SideOnly}
import li.cil.oc.api.Machine import li.cil.oc.api.driver.Processor
import li.cil.oc.api.machine.MachineHost import li.cil.oc.api.machine.{Architecture, MachineHost}
import li.cil.oc.api.network.Node import li.cil.oc.api.network.Node
import li.cil.oc.api.tileentity.Analyzable import li.cil.oc.api.tileentity.Analyzable
import li.cil.oc.api.{Driver, Machine}
import li.cil.oc.client.Sound import li.cil.oc.client.Sound
import li.cil.oc.common.Slot
import li.cil.oc.common.tileentity.RobotProxy import li.cil.oc.common.tileentity.RobotProxy
import li.cil.oc.server.{driver, PacketSender => ServerPacketSender} import li.cil.oc.server.{driver, PacketSender => ServerPacketSender}
import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ExtendedNBT._
@ -68,6 +70,17 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def cpuArchitecture: Class[_ <: Architecture] = {
for (i <- 0 until getSizeInventory if isComponentSlot(i)) Option(getStackInSlot(i)) match {
case Some(s) => Option(Driver.driverFor(s)) match {
case Some(driver: Processor) if driver.slot(s) == Slot.CPU => return driver.architecture(s)
case _ =>
}
case _ =>
}
null
}
override def markAsChanged() = hasChanged = true override def markAsChanged() = hasChanged = true
override def installedComponents = components collect { override def installedComponents = components collect {
@ -176,7 +189,7 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B
override def markDirty() { override def markDirty() {
super.markDirty() super.markDirty()
if (isServer) { if (isServer) {
computer.architecture.recomputeMemory() Option(computer.architecture).foreach(_.recomputeMemory())
isOutputEnabled = hasRedstoneCard isOutputEnabled = hasRedstoneCard
isAbstractBusAvailable = hasAbstractBusCard isAbstractBusAvailable = hasAbstractBusCard
} }

View File

@ -1,7 +1,8 @@
package li.cil.oc.server.component package li.cil.oc.server.component
import li.cil.oc.Items import li.cil.oc.Items
import li.cil.oc.api.machine.MachineHost import li.cil.oc.api.driver.Processor
import li.cil.oc.api.machine.{Architecture, MachineHost}
import li.cil.oc.api.network.{Message, Node} import li.cil.oc.api.network.{Message, Node}
import li.cil.oc.api.{Driver, Machine, driver} import li.cil.oc.api.{Driver, Machine, driver}
import li.cil.oc.common.inventory.{ComponentInventory, ServerInventory} import li.cil.oc.common.inventory.{ComponentInventory, ServerInventory}
@ -40,6 +41,17 @@ class Server(val rack: tileentity.ServerRack, val number: Int) extends MachineHo
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def cpuArchitecture: Class[_ <: Architecture] = {
for (i <- 0 until inventory.getSizeInventory if inventory.isComponentSlot(i)) Option(inventory.getStackInSlot(i)) match {
case Some(s) => Option(Driver.driverFor(s)) match {
case Some(driver: Processor) if driver.slot(s) == Slot.CPU => return driver.architecture(s)
case _ =>
}
case _ =>
}
null
}
override def installedMemory = inventory.items.foldLeft(0)((sum, stack) => sum + (stack match { override def installedMemory = inventory.items.foldLeft(0)((sum, stack) => sum + (stack match {
case Some(item) => Option(Driver.driverFor(item)) match { case Some(item) => Option(Driver.driverFor(item)) match {
case Some(driver: driver.Memory) => driver.amount(item) case Some(driver: driver.Memory) => driver.amount(item)

View File

@ -25,5 +25,5 @@ object CPU extends Item with driver.Processor {
case _ => 0 case _ => 0
} }
override def architecture = Machine.LuaArchitecture override def architecture(stack: ItemStack) = Machine.LuaArchitecture
} }

View File

@ -25,5 +25,5 @@ object ComponentBus extends Item with driver.Processor {
case _ => 0 case _ => 0
} }
override def architecture = null override def architecture(stack: ItemStack) = null
} }

View File

@ -1,6 +1,5 @@
package li.cil.oc.server.machine package li.cil.oc.server.machine
import java.lang.reflect.Constructor
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import li.cil.oc.api.detail.MachineAPI import li.cil.oc.api.detail.MachineAPI
@ -24,7 +23,7 @@ import net.minecraftforge.common.util.Constants.NBT
import scala.Array.canBuildFrom import scala.Array.canBuildFrom
import scala.collection.mutable import scala.collection.mutable
class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]) extends ManagedComponent with machine.Machine with Runnable { class Machine(val host: MachineHost) extends ManagedComponent with machine.Machine with Runnable {
val node = Network.newNode(this, Visibility.Network). val node = Network.newNode(this, Visibility.Network).
withComponent("computer", Visibility.Neighbors). withComponent("computer", Visibility.Neighbors).
withConnector(Settings.get.bufferComputer). withConnector(Settings.get.bufferComputer).
@ -35,7 +34,9 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
fromMemory(Settings.get.tmpSize * 1024), "tmpfs")) fromMemory(Settings.get.tmpSize * 1024), "tmpfs"))
} else None } else None
val architecture = constructor.newInstance(this) var architecture: Architecture = _
private var bootAddress = ""
private[machine] val state = mutable.Stack(Machine.State.Stopped) private[machine] val state = mutable.Stack(Machine.State.Stopped)
@ -71,6 +72,10 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def getBootAddress = bootAddress
override def setBootAddress(value: String) = bootAddress = Option(value).map(_.take(36)).getOrElse("")
override def components = scala.collection.convert.WrapAsJava.mapAsJavaMap(_components) override def components = scala.collection.convert.WrapAsJava.mapAsJavaMap(_components)
def componentCount = _components.count { def componentCount = _components.count {
@ -115,12 +120,12 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
case Machine.State.Stopped => case Machine.State.Stopped =>
processAddedComponents() processAddedComponents()
verifyComponents() verifyComponents()
if (componentCount > host.maxComponents) { if (host.cpuArchitecture() == null) {
crash(host match { crash("gui.Error.NoCPU")
case t: tileentity.Case if !t.hasCPU => "gui.Error.NoCPU" false
case s: server.component.Server if !s.hasCPU => "gui.Error.NoCPU" }
case _ => "gui.Error.ComponentOverflow" else if (componentCount > host.maxComponents) {
}) crash("gui.Error.ComponentOverflow")
false false
} }
else if (host.maxComponents == 0) { else if (host.maxComponents == 0) {
@ -481,7 +486,7 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
if (node == this.node) { if (node == this.node) {
_components += this.node.address -> this.node.name _components += this.node.address -> this.node.name
tmp.foreach(fs => node.connect(fs.node)) tmp.foreach(fs => node.connect(fs.node))
architecture.onConnect() Option(architecture).foreach(_.onConnect())
} }
else { else {
node match { node match {
@ -531,7 +536,7 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
_components.synchronized(_components += component.address -> component.name) _components.synchronized(_components += component.address -> component.name)
// Skip the signal if we're not initialized yet, since we'd generate a // Skip the signal if we're not initialized yet, since we'd generate a
// duplicate in the startup script otherwise. // duplicate in the startup script otherwise.
if (architecture.isInitialized) { if (architecture != null && architecture.isInitialized) {
signal("component_added", component.address, component.name) signal("component_added", component.address, component.name)
} }
} }
@ -568,6 +573,8 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
super.load(nbt) super.load(nbt)
bootAddress = nbt.getString("bootAddress")
state.pushAll(nbt.getIntArray("state").reverse.map(Machine.State(_))) state.pushAll(nbt.getIntArray("state").reverse.map(Machine.State(_)))
nbt.getTagList("users", NBT.TAG_STRING).foreach((list, index) => _users += list.getStringTagAt(index)) nbt.getTagList("users", NBT.TAG_STRING).foreach((list, index) => _users += list.getStringTagAt(index))
if (nbt.hasKey("message")) { if (nbt.hasKey("message")) {
@ -626,10 +633,6 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
else { else {
// Clean up in case we got a weird state stack. // Clean up in case we got a weird state stack.
close() close()
// Architectures must check for "isRunning" themselves, to get a chance
// to load data their APIs stored that should persist across runs.
architecture.load(nbt)
} }
} }
@ -641,6 +644,10 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
super.save(nbt) super.save(nbt)
if (bootAddress != null) {
nbt.setString("bootAddress", bootAddress)
}
// Make sure the component list is up-to-date. // Make sure the component list is up-to-date.
processAddedComponents() processAddedComponents()
@ -702,6 +709,14 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
private def init(): Boolean = { private def init(): Boolean = {
// Recreate architecture if necessary.
val hostArchitecture = host.cpuArchitecture
if (architecture == null || architecture.getClass != hostArchitecture) {
if (hostArchitecture == null) return false
architecture = hostArchitecture.getConstructor(classOf[machine.Machine]).newInstance(this)
if (node.network != null) architecture.onConnect()
}
// Reset error state. // Reset error state.
message = None message = None
@ -729,7 +744,7 @@ class Machine(val host: MachineHost, constructor: Constructor[_ <: Architecture]
if (state.size == 0 || state.top != Machine.State.Stopped) { if (state.size == 0 || state.top != Machine.State.Stopped) {
state.clear() state.clear()
state.push(Machine.State.Stopped) state.push(Machine.State.Stopped)
architecture.close() Option(architecture).foreach(_.close())
signals.clear() signals.clear()
uptime = 0 uptime = 0
cpuTotal = 0 cpuTotal = 0
@ -866,10 +881,7 @@ object Machine extends MachineAPI {
override def architectures() = scala.collection.convert.WrapAsJava.asJavaIterable(checked) override def architectures() = scala.collection.convert.WrapAsJava.asJavaIterable(checked)
override def create(host: MachineHost, architecture: Class[_ <: Architecture]) = { override def create(host: MachineHost) = new Machine(host)
add(architecture)
new Machine(host, architecture.getConstructor(classOf[machine.Machine]))
}
/** Possible states of the computer, and in particular its executor. */ /** Possible states of the computer, and in particular its executor. */
private[machine] object State extends Enumeration { private[machine] object State extends Enumeration {

View File

@ -39,7 +39,7 @@ class ComputerAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
// Get/set address of boot device. // Get/set address of boot device.
lua.pushScalaFunction(lua => { lua.pushScalaFunction(lua => {
owner.bootAddress match { owner.machine.getBootAddress match {
case "" => lua.pushNil() case "" => lua.pushNil()
case address => lua.pushString(address) case address => lua.pushString(address)
} }
@ -48,8 +48,8 @@ class ComputerAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
lua.setField(-2, "getBootAddress") lua.setField(-2, "getBootAddress")
lua.pushScalaFunction(lua => { lua.pushScalaFunction(lua => {
if (lua.isNoneOrNil(1)) owner.bootAddress = "" if (lua.isNoneOrNil(1)) owner.machine.setBootAddress("")
else owner.bootAddress = lua.checkString(1).take(36) else owner.machine.setBootAddress(lua.checkString(1).take(36))
0 0
}) })
lua.setField(-2, "setBootAddress") lua.setField(-2, "setBootAddress")

View File

@ -19,8 +19,6 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
private[machine] val ramScale = if (LuaStateFactory.is64Bit) Settings.get.ramScaleFor64Bit else 1.0 private[machine] val ramScale = if (LuaStateFactory.is64Bit) Settings.get.ramScaleFor64Bit else 1.0
private[machine] var bootAddress = ""
private val persistence = new PersistenceAPI(this) private val persistence = new PersistenceAPI(this)
private val apis = Array( private val apis = Array(
@ -314,8 +312,6 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
private def state = machine.asInstanceOf[Machine].state private def state = machine.asInstanceOf[Machine].state
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
bootAddress = nbt.getString("bootAddress")
if (!machine.isRunning) return if (!machine.isRunning) return
// Unlimit memory use while unpersisting. // Unlimit memory use while unpersisting.
@ -363,10 +359,6 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu
} }
override def save(nbt: NBTTagCompound) { override def save(nbt: NBTTagCompound) {
if (bootAddress != null) {
nbt.setString("bootAddress", bootAddress)
}
// Unlimit memory while persisting. // Unlimit memory while persisting.
if (Settings.get.limitMemory) { if (Settings.get.limitMemory) {
lua.setTotalMemory(Integer.MAX_VALUE) lua.setTotalMemory(Integer.MAX_VALUE)

View File

@ -27,14 +27,14 @@ class ComputerAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
}) })
// Get/set address of boot device. // Get/set address of boot device.
computer.set("getBootAddress", (_: Varargs) => owner.bootAddress match { computer.set("getBootAddress", (_: Varargs) => owner.machine.getBootAddress match {
case "" => LuaValue.NIL case "" => LuaValue.NIL
case address => LuaValue.valueOf(address) case address => LuaValue.valueOf(address)
}) })
computer.set("setBootAddress", (args: Varargs) => { computer.set("setBootAddress", (args: Varargs) => {
if (args.isnoneornil(1)) owner.bootAddress = "" if (args.isnoneornil(1)) owner.machine.setBootAddress("")
else owner.bootAddress = args.checkjstring(1).take(36) else owner.machine.setBootAddress(args.checkjstring(1).take(36))
LuaValue.NIL LuaValue.NIL
}) })

View File

@ -25,8 +25,6 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture
private[machine] var memory = 0 private[machine] var memory = 0
private[machine] var bootAddress = ""
private val apis = Array( private val apis = Array(
new ComponentAPI(this), new ComponentAPI(this),
new ComputerAPI(this), new ComputerAPI(this),
@ -236,17 +234,11 @@ class LuaJLuaArchitecture(val machine: api.machine.Machine) extends Architecture
// ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- //
override def load(nbt: NBTTagCompound) { override def load(nbt: NBTTagCompound) {
bootAddress = nbt.getString("bootAddress")
if (machine.isRunning) { if (machine.isRunning) {
machine.stop() machine.stop()
machine.start() machine.start()
} }
} }
override def save(nbt: NBTTagCompound) { override def save(nbt: NBTTagCompound) {}
if (bootAddress != null) {
nbt.setString("bootAddress", bootAddress)
}
}
} }