From beb33d48197a742746b82f4a9a01254b35540c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 2 Aug 2014 13:34:53 +0200 Subject: [PATCH] Moved some more logic to save handler and removed old compatibility code from save/load logic in machines (they'd be reset by now anyway due to API changes). --- .../scala/li/cil/oc/common/SaveHandler.scala | 36 ++++++++++++++++++- .../machine/NativeLuaArchitecture.scala | 31 +++------------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/SaveHandler.scala b/src/main/scala/li/cil/oc/common/SaveHandler.scala index 840b7b1b7..c48b8aad6 100644 --- a/src/main/scala/li/cil/oc/common/SaveHandler.scala +++ b/src/main/scala/li/cil/oc/common/SaveHandler.scala @@ -4,8 +4,11 @@ import java.io import java.io.{File, FileFilter} import java.util.logging.Level +import li.cil.oc.api.driver.Container +import li.cil.oc.api.machine.Owner import li.cil.oc.{OpenComputers, Settings} -import net.minecraft.world.ChunkCoordIntPair +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.world.{ChunkCoordIntPair, World} import net.minecraftforge.common.DimensionManager import net.minecraftforge.event.ForgeSubscribe import net.minecraftforge.event.world.{ChunkDataEvent, WorldEvent} @@ -24,6 +27,37 @@ object SaveHandler { def statePath = new io.File(savePath, "state") + def scheduleSave(owner: Owner, nbt: NBTTagCompound, name: String, data: Array[Byte]) { + scheduleSave(owner.world, owner.x, owner.z, nbt, name, data) + } + + def scheduleSave(container: Container, nbt: NBTTagCompound, name: String, data: Array[Byte]) { + scheduleSave(container.world, math.round(container.xPosition - 0.5).toInt, math.round(container.zPosition - 0.5).toInt, nbt, name, data) + } + + def scheduleSave(world: World, x: Int, z: Int, nbt: NBTTagCompound, name: String, data: Array[Byte]) { + val dimension = world.provider.dimensionId + val chunk = new ChunkCoordIntPair(x >> 4, z >> 4) + + // We have to save the dimension and chunk coordinates, because they are + // not available on load / may have changed if the computer was moved. + nbt.setInteger("dimension", dimension) + nbt.setInteger("chunkX", chunk.chunkXPos) + nbt.setInteger("chunkZ", chunk.chunkZPos) + + scheduleSave(dimension, chunk, name, data) + } + + def load(nbt: NBTTagCompound, name: String): Array[Byte] = { + // Since we have no world yet, we rely on the dimension we were saved in. + // Same goes for the chunk. This also works around issues with computers + // being moved (e.g. Redstone in Motion). + val dimension = nbt.getInteger("dimension") + val chunk = new ChunkCoordIntPair(nbt.getInteger("chunkX"), nbt.getInteger("chunkZ")) + + load(dimension, chunk, name) + } + def scheduleSave(dimension: Int, chunk: ChunkCoordIntPair, name: String, data: Array[Byte]) = saveData.synchronized { if (chunk == null) throw new IllegalArgumentException("chunk is null") else { diff --git a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala index 6d3588993..5e9aae439 100644 --- a/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala +++ b/src/main/scala/li/cil/oc/server/component/machine/NativeLuaArchitecture.scala @@ -12,7 +12,6 @@ import li.cil.oc.util.ExtendedLuaState.extendLuaState import li.cil.oc.util.LuaStateFactory import li.cil.oc.{OpenComputers, Settings, api} import net.minecraft.nbt.NBTTagCompound -import net.minecraft.world.ChunkCoordIntPair class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architecture { private[machine] var lua: LuaState = null @@ -328,29 +327,14 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu // on. First, clear the stack, meaning the current kernel. lua.setTop(0) - // Since we have no world yet, we rely on the dimension we were saved in. - // Same goes for the chunk. This also works around issues with computers - // being moved (e.g. Redstone in Motion). - val dimension = nbt.getInteger("dimension") - val chunk = - if (nbt.hasKey("chunkX") && nbt.hasKey("chunkZ")) - new ChunkCoordIntPair(nbt.getInteger("chunkX"), nbt.getInteger("chunkZ")) - else - new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4) - val kernel = - if (nbt.hasKey("kernel")) nbt.getByteArray("kernel") - else SaveHandler.load(dimension, chunk, machine.node.address + "_kernel") - persistence.unpersist(kernel) + persistence.unpersist(SaveHandler.load(nbt, machine.node.address + "_kernel")) if (!lua.isThread(1)) { // This shouldn't really happen, but there's a chance it does if // the save was corrupt (maybe someone modified the Lua files). throw new LuaRuntimeException("Invalid kernel.") } if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) { - val stack = - if (nbt.hasKey("stack")) nbt.getByteArray("stack") - else SaveHandler.load(dimension, chunk, machine.node.address + "_stack") - persistence.unpersist(stack) + persistence.unpersist(SaveHandler.load(nbt, machine.node.address + "_stack")) if (!(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2))) { // Same as with the above, should not really happen normally, but // could for the same reasons. @@ -389,19 +373,12 @@ class NativeLuaArchitecture(val machine: api.machine.Machine) extends Architectu // Save the kernel state (which is always at stack index one). assert(lua.isThread(1)) - // We have to save the dimension and chunk coordinates, because they are - // not available on load / may have changed if the computer was moved. - val dimension = machine.owner.world.provider.dimensionId - val chunk = new ChunkCoordIntPair(machine.owner.x >> 4, machine.owner.z >> 4) - nbt.setInteger("dimension", dimension) - nbt.setInteger("chunkX", chunk.chunkXPos) - nbt.setInteger("chunkZ", chunk.chunkZPos) - SaveHandler.scheduleSave(dimension, chunk, machine.node.address + "_kernel", persistence.persist(1)) + SaveHandler.scheduleSave(machine.owner, nbt, machine.node.address + "_kernel", persistence.persist(1)) // While in a driver call we have one object on the global stack: either // the function to call the driver with, or the result of the call. if (state.contains(Machine.State.SynchronizedCall) || state.contains(Machine.State.SynchronizedReturn)) { assert(if (state.contains(Machine.State.SynchronizedCall)) lua.isFunction(2) else lua.isTable(2)) - SaveHandler.scheduleSave(dimension, chunk, machine.node.address + "_stack", persistence.persist(2)) + SaveHandler.scheduleSave(machine.owner, nbt, machine.node.address + "_stack", persistence.persist(2)) } nbt.setInteger("kernelMemory", math.ceil(kernelMemory / ramScale).toInt)