mirror of
https://github.com/MightyPirates/OpenComputers.git
synced 2025-09-17 19:25:20 -04:00
Added eeprom.getData/setData for mutable persistent bios storage, replaces get/setBootAddress.
get/setData is wrapped by the default Lua bios into functions with these names to avoid breaking programs using them.
This commit is contained in:
parent
9e92ee508c
commit
2ac78463a1
@ -36,20 +36,6 @@ public interface Machine extends ManagedEnvironment, Context {
|
||||
*/
|
||||
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.
|
||||
* <p/>
|
||||
|
@ -146,6 +146,9 @@ opencomputers {
|
||||
# The maximum size of the byte array that can be stored on EEPROMs.
|
||||
eepromSize: 4096
|
||||
|
||||
# The maximum size of the byte array that can be stored on EEPROMs.
|
||||
eepromDataSize: 256
|
||||
|
||||
# The number of components the different CPU tiers support. This list
|
||||
# must contain exactly three entries, or it will be ignored.
|
||||
cpuComponentCount: [
|
||||
|
@ -1,11 +1,22 @@
|
||||
local component_invoke = component.invoke
|
||||
function boot_invoke(address, method, ...)
|
||||
local result = table.pack(pcall(component.invoke, address, method, ...))
|
||||
local result = table.pack(pcall(component_invoke, address, method, ...))
|
||||
if not result[1] then
|
||||
return nil, result[2]
|
||||
else
|
||||
return table.unpack(result, 2, result.n)
|
||||
end
|
||||
end
|
||||
|
||||
-- backwards compatibility, may remove later
|
||||
local eeprom = component.list("eeprom")()
|
||||
computer.getBootAddress = function()
|
||||
return boot_invoke(eeprom, "getData")
|
||||
end
|
||||
computer.setBootAddress = function(address)
|
||||
return boot_invoke(eeprom, "setData", address)
|
||||
end
|
||||
|
||||
do
|
||||
local screen = component.list("screen")()
|
||||
local gpu = component.list("gpu")()
|
||||
@ -27,7 +38,7 @@ local function tryLoadFrom(address)
|
||||
buffer = buffer .. (data or "")
|
||||
until not data
|
||||
boot_invoke(address, "close", handle)
|
||||
return load(buffer, "=init", "t", sandbox)
|
||||
return load(buffer, "=init")
|
||||
end
|
||||
local init, reason
|
||||
if computer.getBootAddress() then
|
||||
|
@ -58,6 +58,7 @@ class Settings(val config: Config) {
|
||||
val timeout = config.getDouble("computer.timeout") max 0
|
||||
val startupDelay = config.getDouble("computer.startupDelay") max 0.05
|
||||
val eepromSize = config.getInt("computer.eepromSize") max 0
|
||||
val eepromDataSize = config.getInt("computer.eepromDataSize") max 0
|
||||
val cpuComponentSupport = Array(config.getIntList("computer.cpuComponentCount"): _*) match {
|
||||
case Array(tier1, tier2, tier3) =>
|
||||
Array(tier1: Int, tier2: Int, tier3: Int)
|
||||
|
@ -16,18 +16,20 @@ class EEPROM extends prefab.ManagedEnvironment {
|
||||
withConnector().
|
||||
create()
|
||||
|
||||
var data = Array.empty[Byte]
|
||||
var codeData = Array.empty[Byte]
|
||||
|
||||
var volatileData = Array.empty[Byte]
|
||||
|
||||
var readonly = false
|
||||
|
||||
var label = "EEPROM"
|
||||
|
||||
def checksum = Hashing.crc32().hashBytes(data).toString
|
||||
def checksum = Hashing.crc32().hashBytes(codeData).toString
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
@Callback(direct = true, doc = """function():string -- Get the currently stored byte array.""")
|
||||
def get(context: Context, args: Arguments): Array[AnyRef] = result(data)
|
||||
def get(context: Context, args: Arguments): Array[AnyRef] = result(codeData)
|
||||
|
||||
@Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""")
|
||||
def set(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
@ -37,9 +39,9 @@ class EEPROM extends prefab.ManagedEnvironment {
|
||||
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
||||
return result(Unit, "not enough energy")
|
||||
}
|
||||
val newData = args.checkByteArray(0)
|
||||
val newData = args.optByteArray(0, Array.empty)
|
||||
if (newData.length > Settings.get.eepromSize) throw new IllegalArgumentException("not enough space")
|
||||
data = newData
|
||||
codeData = newData
|
||||
context.pause(2) // deliberately slow to discourage use as normal storage medium
|
||||
null
|
||||
}
|
||||
@ -72,21 +74,41 @@ class EEPROM extends prefab.ManagedEnvironment {
|
||||
else result(Unit, "incorrect checksum")
|
||||
}
|
||||
|
||||
@Callback(direct = true, doc = """function():string -- Get the storage capacity of this EEPROM.""")
|
||||
def getDataSize(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.eepromDataSize)
|
||||
|
||||
@Callback(direct = true, doc = """function():string -- Get the currently stored byte array.""")
|
||||
def getData(context: Context, args: Arguments): Array[AnyRef] = result(volatileData)
|
||||
|
||||
@Callback(doc = """function(data:string) -- Overwrite the currently stored byte array.""")
|
||||
def setData(context: Context, args: Arguments): Array[AnyRef] = {
|
||||
if (!node.tryChangeBuffer(-Settings.get.eepromWriteCost)) {
|
||||
return result(Unit, "not enough energy")
|
||||
}
|
||||
val newData = args.optByteArray(0, Array.empty)
|
||||
if (newData.length > Settings.get.eepromDataSize) throw new IllegalArgumentException("not enough space")
|
||||
volatileData = newData
|
||||
context.pause(1) // deliberately slow to discourage use as normal storage medium
|
||||
null
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------- //
|
||||
|
||||
override def load(nbt: NBTTagCompound) {
|
||||
super.load(nbt)
|
||||
data = nbt.getByteArray(Settings.namespace + "eeprom")
|
||||
codeData = nbt.getByteArray(Settings.namespace + "eeprom")
|
||||
if (nbt.hasKey(Settings.namespace + "label")) {
|
||||
label = nbt.getString(Settings.namespace + "label")
|
||||
}
|
||||
readonly = nbt.getBoolean(Settings.namespace + "readonly")
|
||||
volatileData = nbt.getByteArray(Settings.namespace + "userdata")
|
||||
}
|
||||
|
||||
override def save(nbt: NBTTagCompound) {
|
||||
super.save(nbt)
|
||||
nbt.setByteArray(Settings.namespace + "eeprom", data)
|
||||
nbt.setByteArray(Settings.namespace + "eeprom", codeData)
|
||||
nbt.setString(Settings.namespace + "label", label)
|
||||
nbt.setBoolean(Settings.namespace + "readonly", readonly)
|
||||
nbt.setByteArray(Settings.namespace + "userdata", volatileData)
|
||||
}
|
||||
}
|
||||
|
@ -57,8 +57,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
|
||||
var architecture: Architecture = _
|
||||
|
||||
private var bootAddress = ""
|
||||
|
||||
private[machine] val state = mutable.Stack(Machine.State.Stopped)
|
||||
|
||||
private val _components = mutable.Map.empty[String, String]
|
||||
@ -142,10 +140,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
hasMemory = Option(architecture).fold(false)(_.recomputeMemory(components))
|
||||
}
|
||||
|
||||
override def getBootAddress = bootAddress
|
||||
|
||||
override def setBootAddress(value: String) = bootAddress = Option(value).fold("")(_.take(36))
|
||||
|
||||
override def components = scala.collection.convert.WrapAsJava.mapAsJavaMap(_components)
|
||||
|
||||
def componentCount = (_components.foldLeft(0.0)((acc, entry) => entry match {
|
||||
@ -649,8 +643,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
|
||||
super.load(nbt)
|
||||
|
||||
bootAddress = nbt.getString("bootAddress")
|
||||
|
||||
state.pushAll(nbt.getIntArray("state").reverse.map(Machine.State(_)))
|
||||
nbt.getTagList("users", NBT.TAG_STRING).foreach((tag: NBTTagString) => _users += tag.func_150285_a_())
|
||||
if (nbt.hasKey("message")) {
|
||||
@ -718,10 +710,6 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach
|
||||
|
||||
super.save(nbt)
|
||||
|
||||
if (bootAddress != null) {
|
||||
nbt.setString("bootAddress", bootAddress)
|
||||
}
|
||||
|
||||
// Make sure the component list is up-to-date.
|
||||
processAddedComponents()
|
||||
|
||||
|
@ -37,23 +37,6 @@ class ComputerAPI(owner: NativeLuaArchitecture) extends NativeLuaAPI(owner) {
|
||||
})
|
||||
lua.setField(-2, "address")
|
||||
|
||||
// Get/set address of boot device.
|
||||
lua.pushScalaFunction(lua => {
|
||||
owner.machine.getBootAddress match {
|
||||
case "" => lua.pushNil()
|
||||
case address => lua.pushString(address)
|
||||
}
|
||||
1
|
||||
})
|
||||
lua.setField(-2, "getBootAddress")
|
||||
|
||||
lua.pushScalaFunction(lua => {
|
||||
if (lua.isNoneOrNil(1)) owner.machine.setBootAddress("")
|
||||
else owner.machine.setBootAddress(lua.checkString(1).take(36))
|
||||
0
|
||||
})
|
||||
lua.setField(-2, "setBootAddress")
|
||||
|
||||
lua.pushScalaFunction(lua => {
|
||||
// This is *very* unlikely, but still: avoid this getting larger than
|
||||
// what we report as the total memory.
|
||||
|
@ -27,18 +27,6 @@ class ComputerAPI(owner: LuaJLuaArchitecture) extends LuaJAPI(owner) {
|
||||
case _ => LuaValue.NIL
|
||||
})
|
||||
|
||||
// Get/set address of boot device.
|
||||
computer.set("getBootAddress", (_: Varargs) => owner.machine.getBootAddress match {
|
||||
case "" => LuaValue.NIL
|
||||
case address => LuaValue.valueOf(address)
|
||||
})
|
||||
|
||||
computer.set("setBootAddress", (args: Varargs) => {
|
||||
if (args.isnoneornil(1)) owner.machine.setBootAddress("")
|
||||
else owner.machine.setBootAddress(args.checkjstring(1).take(36))
|
||||
LuaValue.NIL
|
||||
})
|
||||
|
||||
computer.set("freeMemory", (_: Varargs) => LuaValue.valueOf(owner.memory / 2))
|
||||
|
||||
computer.set("totalMemory", (_: Varargs) => LuaValue.valueOf(owner.memory))
|
||||
|
Loading…
x
Reference in New Issue
Block a user