From 4780e86b964c19d752d225f22493af74b6da395b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 27 Feb 2016 19:24:21 +0100 Subject: [PATCH 1/2] Call Architecture.onSignal outside all locks. Closes #1672. --- .../li/cil/oc/server/machine/Machine.scala | 57 ++++++++++--------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/machine/Machine.scala b/src/main/scala/li/cil/oc/server/machine/Machine.scala index 0a8223196..3fbc61b46 100644 --- a/src/main/scala/li/cil/oc/server/machine/Machine.scala +++ b/src/main/scala/li/cil/oc/server/machine/Machine.scala @@ -298,35 +298,36 @@ class Machine(val host: MachineHost) extends prefab.ManagedEnvironment with mach } } - override def signal(name: String, args: AnyRef*) = state.synchronized(state.top match { - case Machine.State.Stopped | Machine.State.Stopping => false - case _ => signals.synchronized { - if (signals.size >= 256) false - else if (args == null) { - signals.enqueue(new Machine.Signal(name, Array.empty)) - if (architecture != null) architecture.onSignal() - true + override def signal(name: String, args: AnyRef*): Boolean = { + state.synchronized(state.top match { + case Machine.State.Stopped | Machine.State.Stopping => return false + case _ => signals.synchronized { + if (signals.size >= 256) return false + else if (args == null) { + signals.enqueue(new Machine.Signal(name, Array.empty)) + } + else { + signals.enqueue(new Machine.Signal(name, args.map { + case null | Unit | None => null + case arg: java.lang.Boolean => arg + case arg: java.lang.Character => Double.box(arg.toDouble) + case arg: java.lang.Long => arg + case arg: java.lang.Number => Double.box(arg.doubleValue) + case arg: java.lang.String => arg + case arg: Array[Byte] => arg + case arg: Map[_, _] if arg.isEmpty || arg.head._1.isInstanceOf[String] && arg.head._2.isInstanceOf[String] => arg + case arg: NBTTagCompound => arg + case arg => + OpenComputers.log.warn("Trying to push signal with an unsupported argument of type " + arg.getClass.getName) + null + }.toArray[AnyRef])) + } } - else { - signals.enqueue(new Machine.Signal(name, args.map { - case null | Unit | None => null - case arg: java.lang.Boolean => arg - case arg: java.lang.Character => Double.box(arg.toDouble) - case arg: java.lang.Long => arg - case arg: java.lang.Number => Double.box(arg.doubleValue) - case arg: java.lang.String => arg - case arg: Array[Byte] => arg - case arg: Map[_, _] if arg.isEmpty || arg.head._1.isInstanceOf[String] && arg.head._2.isInstanceOf[String] => arg - case arg: NBTTagCompound => arg - case arg => - OpenComputers.log.warn("Trying to push signal with an unsupported argument of type " + arg.getClass.getName) - null - }.toArray[AnyRef])) - if (architecture != null) architecture.onSignal() - true - } - } - }) + }) + + if (architecture != null) architecture.onSignal() + true + } override def popSignal(): Machine.Signal = signals.synchronized(if (signals.isEmpty) null else signals.dequeue().convert()) From 22495b9e50b3e7a03392471668326abd2a1d2634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Sat, 27 Feb 2016 19:30:59 +0100 Subject: [PATCH 2/2] Make adapter use new SidedBlock drivers. Updated some more JDoc. --- src/main/java/li/cil/oc/api/driver/MethodWhitelist.java | 2 +- src/main/java/li/cil/oc/api/driver/NamedBlock.java | 2 +- src/main/scala/li/cil/oc/common/tileentity/Adapter.scala | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java b/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java index 0bb8814c5..98fa173ae 100644 --- a/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java +++ b/src/main/java/li/cil/oc/api/driver/MethodWhitelist.java @@ -15,7 +15,7 @@ package li.cil.oc.api.driver; * suppress inventory functionality if your TileEntity implements IInventory. *

* To do so, implement this interface in the environment that you - * return from your driver's {@link Block#createEnvironment(net.minecraft.world.World, int, int, int)} + * return from your driver's {@link SidedBlock#createEnvironment(net.minecraft.world.World, int, int, int, net.minecraftforge.common.util.ForgeDirection)} * method, and provide the names of the allowed methods from {@link #whitelistedMethods()}. *

* Important: if multiple drivers apply to a single block that each diff --git a/src/main/java/li/cil/oc/api/driver/NamedBlock.java b/src/main/java/li/cil/oc/api/driver/NamedBlock.java index f604c7683..887b70279 100644 --- a/src/main/java/li/cil/oc/api/driver/NamedBlock.java +++ b/src/main/java/li/cil/oc/api/driver/NamedBlock.java @@ -7,7 +7,7 @@ package li.cil.oc.api.driver; *

* This was previously to be implemented on the driver itself, but that has been * deprecated. Implement it in the environment returned from the block driver's - * {@link Block#createEnvironment(net.minecraft.world.World, int, int, int)} + * {@link SidedBlock#createEnvironment(net.minecraft.world.World, int, int, int, net.minecraftforge.common.util.ForgeDirection)} * method instead. */ public interface NamedBlock { diff --git a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala index 09c3749ee..68d2d1bc5 100644 --- a/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala +++ b/src/main/scala/li/cil/oc/common/tileentity/Adapter.scala @@ -19,7 +19,7 @@ import scala.collection.mutable class Adapter extends traits.Environment with traits.ComponentInventory with Analyzable with internal.Adapter { val node = api.Network.newNode(this, Visibility.Network).create() - private val blocks = Array.fill[Option[(ManagedEnvironment, api.driver.Block)]](6)(None) + private val blocks = Array.fill[Option[(ManagedEnvironment, api.driver.SidedBlock)]](6)(None) private val updatingBlocks = mutable.ArrayBuffer.empty[ManagedEnvironment] @@ -55,7 +55,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with Ana // but the only 'downside' is that it can't be used to manipulate // inventories, which I actually consider a plus :P case _ => - Option(api.Driver.driverFor(world, x, y, z)) match { + Option(api.Driver.driverFor(world, x, y, z, d)) match { case Some(newDriver) => blocks(d.ordinal()) match { case Some((oldEnvironment, driver)) => if (newDriver != driver) { @@ -66,7 +66,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with Ana node.disconnect(oldEnvironment.node) // Then rebuild - if we have something. - val environment = newDriver.createEnvironment(world, x, y, z) + val environment = newDriver.createEnvironment(world, x, y, z, d) if (environment != null) { blocks(d.ordinal()) = Some((environment, newDriver)) if (environment.canUpdate) { @@ -78,7 +78,7 @@ class Adapter extends traits.Environment with traits.ComponentInventory with Ana } // else: the more things change, the more they stay the same. case _ => // A challenger appears. Maybe. - val environment = newDriver.createEnvironment(world, x, y, z) + val environment = newDriver.createEnvironment(world, x, y, z, d) if (environment != null) { blocks(d.ordinal()) = Some((environment, newDriver)) if (environment.canUpdate) {