From 507b882f47949ef32db1e5297ab535d03f2fac2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 23 Feb 2015 17:45:29 +0100 Subject: [PATCH] Backported change to robot movement / execution logic so that it runs in a tick handler instead of the tile entity's update method. May help with issue #808 or break things horribly (not that I've seen any indication of the latter in the tests I did). --- .../scala/li/cil/oc/common/EventHandler.scala | 14 ++++++++++ .../li/cil/oc/common/tileentity/Robot.scala | 13 ++++++++++ .../common/tileentity/traits/Computer.scala | 26 ++++++++++++------- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/main/scala/li/cil/oc/common/EventHandler.scala b/src/main/scala/li/cil/oc/common/EventHandler.scala index bad067260..3be2e4b54 100644 --- a/src/main/scala/li/cil/oc/common/EventHandler.scala +++ b/src/main/scala/li/cil/oc/common/EventHandler.scala @@ -15,6 +15,7 @@ import li.cil.oc.api.detail.ItemInfo import li.cil.oc.client.renderer.PetRenderer import li.cil.oc.client.{PacketSender => ClientPacketSender} import li.cil.oc.common.item.data.MicrocontrollerData +import li.cil.oc.common.tileentity.Robot import li.cil.oc.common.tileentity.traits.power import li.cil.oc.integration.Mods import li.cil.oc.integration.util @@ -40,6 +41,12 @@ object EventHandler { var totalWorldTicks = 0L + private val runningRobots = mutable.Set.empty[Robot] + + def onRobotStart(robot: Robot): Unit = runningRobots += robot + + def onRobotStopped(robot: Robot): Unit = runningRobots -= robot + def schedule(tileEntity: TileEntity) { if (SideTracker.isServer) pending.synchronized { pending += (() => Network.joinOrCreateNetwork(tileEntity)) @@ -108,6 +115,13 @@ object EventHandler { case t: Throwable => OpenComputers.log.warn("Error in scheduled tick action.", t) } }) + + val invalid = mutable.ArrayBuffer.empty[Robot] + runningRobots.foreach(robot => { + if (robot.isInvalid) invalid += robot + else robot.machine.update() + }) + runningRobots --= invalid } @SubscribeEvent diff --git a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala index f5ce170df..845b50831 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Robot.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Robot.scala @@ -13,6 +13,7 @@ import li.cil.oc.api.event.RobotMoveEvent import li.cil.oc.api.internal import li.cil.oc.api.network._ import li.cil.oc.client.gui +import li.cil.oc.common.EventHandler import li.cil.oc.common.Slot import li.cil.oc.common.Tier import li.cil.oc.common.inventory.InventorySelection @@ -402,6 +403,16 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand } } + // The robot's machine is updated in a tick handler, to avoid delayed tile + // entity creation when moving, which would screw over all the things... + override protected def updateComputer(): Unit = {} + + override protected def onRunningChanged(): Unit = { + super.onRunningChanged() + if (isRunning) EventHandler.onRobotStart(this) + else EventHandler.onRobotStopped(this) + } + override protected def initialize() { if (isServer) { // Ensure we have a node address, because the proxy needs this to initialize @@ -419,6 +430,7 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand case _ => } } + else EventHandler.onRobotStopped(this) } // ----------------------------------------------------------------------- // @@ -452,6 +464,7 @@ class Robot extends traits.Computer with traits.PowerInformation with IFluidHand // robot's proxy instance. _isOutputEnabled = hasRedstoneCard _isAbstractBusAvailable = hasAbstractBusCard + if (isRunning) EventHandler.onRobotStart(this) } // Side check for Waila (and other mods that may call this client side). diff --git a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala index 65f34d1a6..954634278 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/traits/Computer.scala @@ -98,19 +98,18 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B // ----------------------------------------------------------------------- // - override def updateEntity() { + override def updateEntity(): Unit = { + // If we're not yet in a network we might have just been loaded from disk, + // meaning there may be other tile entities that also have not re-joined + // 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 (isServer && isConnected) { - // If we're not yet in a network we might have just been loaded from disk, - // meaning there may be other tile entities that also have not re-joined - // 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). - machine.update() + updateComputer() if (_isRunning != machine.isRunning) { _isRunning = machine.isRunning - markDirty() - ServerPacketSender.sendComputerState(this) + onRunningChanged() } updateComponents() @@ -119,6 +118,15 @@ trait Computer extends Environment with ComponentInventory with Rotatable with B super.updateEntity() } + protected def updateComputer(): Unit = { + machine.update() + } + + protected def onRunningChanged(): Unit = { + markDirty() + ServerPacketSender.sendComputerState(this) + } + // ----------------------------------------------------------------------- // override def readFromNBTForServer(nbt: NBTTagCompound) {