From bfab896a2883b32234c93a9476b55e9ad39e6f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Tue, 29 Dec 2015 09:22:12 +0100 Subject: [PATCH] Added TIS-3D integration. --- build.gradle | 5 + build.properties | 1 + .../en_US/protocols/opencomputersAdapter.md | 7 ++ .../scala/li/cil/oc/integration/Mods.scala | 3 + .../cil/oc/integration/tis3d/ModTIS3D.scala | 12 ++ .../SerialInterfaceProviderAdapter.scala | 115 ++++++++++++++++++ 6 files changed, 143 insertions(+) create mode 100644 src/main/resources/assets/opencomputers/doc/en_US/protocols/opencomputersAdapter.md create mode 100644 src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala create mode 100644 src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala diff --git a/build.gradle b/build.gradle index 6e5763368..3697e93ad 100644 --- a/build.gradle +++ b/build.gradle @@ -71,6 +71,10 @@ if (JavaVersion.current().isJava8Compatible()) { } repositories { + maven { + name = "TIS-3D" + url = "http://maven.cil.li/" + } maven { name = "BluePower" url = "http://maven.bluepowermod.com/" @@ -184,6 +188,7 @@ dependencies { provided "com.bluepowermod:BluePower:${config.bluepower.version}:deobf" provided "com.gregoriust.gregtech:gregtech_${config.minecraft.version}:${config.gt.version}:dev" provided "igwmod:IGW-Mod-1.7.10:${config.igwmod.version}:userdev" + provided "li.cil.tis3d:TIS-3D:${config.tis3d.version}:dev" provided "mcp.mobius.waila:Waila:${config.waila.version}_${config.minecraft.version}:dev" provided "net.industrial-craft:industrialcraft-2:${config.ic2.version}:dev" provided "net.sengir.forestry:forestry_${config.minecraft.version}:${config.forestry.version}:dev" diff --git a/build.properties b/build.properties index 83ae204d5..8d4d274e8 100644 --- a/build.properties +++ b/build.properties @@ -39,6 +39,7 @@ rc.cf=2219/321 rc.version=1.7.10-9.4.0.0 redlogic.version=59.0.3 rotc.version=V5c +tis3d.version=MC1.7.10-0.7.0.50 tmech.version=75.0afb56c re.version=3.0.0.342 waila.version=1.5.8a diff --git a/src/main/resources/assets/opencomputers/doc/en_US/protocols/opencomputersAdapter.md b/src/main/resources/assets/opencomputers/doc/en_US/protocols/opencomputersAdapter.md new file mode 100644 index 000000000..b4ea5eff1 --- /dev/null +++ b/src/main/resources/assets/opencomputers/doc/en_US/protocols/opencomputersAdapter.md @@ -0,0 +1,7 @@ +# Adapter + +![Freeeedooooooom!](block:OpenComputers:adapter) + +The adapter's serial interface does not implement a hard-coded protocol. Instead, the protocol is defined by the software running on the computer controlling the adapter. Please refer to the component's API using an OpenComputers computer for specifics. + +The adapter's serial interface has a small internal buffer for values passed along in either direction. Note that by default the adapter's serial interface does not read from the serial port. Reading has to be enabled from the component's API. diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index b09fdb6e6..8fde28065 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -78,6 +78,7 @@ object Mods { val Thaumcraft = new SimpleMod(IDs.Thaumcraft) val ThermalExpansion = new SimpleMod(IDs.ThermalExpansion, providesPower = true) val TinkersConstruct = new SimpleMod(IDs.TinkersConstruct) + val TIS3D = new SimpleMod(IDs.TIS3D, version = "@[0.7,)") val TMechWorks = new SimpleMod(IDs.TMechWorks) val VersionChecker = new SimpleMod(IDs.VersionChecker) val Waila = new SimpleMod(IDs.Waila) @@ -123,6 +124,7 @@ object Mods { integration.thaumcraft.ModThaumcraft, integration.thermalexpansion.ModThermalExpansion, integration.tcon.ModTinkersConstruct, + integration.tis3d.ModTIS3D, integration.tmechworks.ModTMechworks, integration.vanilla.ModVanilla, integration.versionchecker.ModVersionChecker, @@ -214,6 +216,7 @@ object Mods { final val Thaumcraft = "Thaumcraft" final val ThermalExpansion = "ThermalExpansion" final val TinkersConstruct = "TConstruct" + final val TIS3D = "tis3d" final val TMechWorks = "TMechworks" final val VersionChecker = "VersionChecker" final val Waila = "Waila" diff --git a/src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala b/src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala new file mode 100644 index 000000000..ee83aef8c --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/tis3d/ModTIS3D.scala @@ -0,0 +1,12 @@ +package li.cil.oc.integration.tis3d + +import li.cil.oc.integration.ModProxy +import li.cil.oc.integration.Mods + +object ModTIS3D extends ModProxy { + override def getMod = Mods.TIS3D + + override def initialize(): Unit = { + SerialInterfaceProviderAdapter.init() + } +} diff --git a/src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala b/src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala new file mode 100644 index 000000000..8cd98a7ea --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/tis3d/SerialInterfaceProviderAdapter.scala @@ -0,0 +1,115 @@ +package li.cil.oc.integration.tis3d + +import li.cil.oc.Settings +import li.cil.oc.api +import li.cil.oc.api.internal.Adapter +import li.cil.oc.api.machine.Arguments +import li.cil.oc.api.machine.Callback +import li.cil.oc.api.machine.Context +import li.cil.oc.api.network.Environment +import li.cil.oc.api.network.Message +import li.cil.oc.api.network.Node +import li.cil.oc.api.network.Visibility +import li.cil.oc.util.ResultWrapper.result +import li.cil.tis3d.api.ManualAPI +import li.cil.tis3d.api.SerialAPI +import li.cil.tis3d.api.prefab.manual.ResourceContentProvider +import li.cil.tis3d.api.serial.SerialInterface +import li.cil.tis3d.api.serial.SerialInterfaceProvider +import li.cil.tis3d.api.serial.SerialProtocolDocumentationReference +import net.minecraft.util.EnumFacing +import net.minecraft.world.World + +import scala.collection.mutable + +object SerialInterfaceProviderAdapter extends SerialInterfaceProvider { + def init(): Unit = { + ManualAPI.addProvider(new ResourceContentProvider(Settings.resourceDomain, "doc/")) + SerialAPI.addProvider(this) + } + + override def getDocumentationReference = new SerialProtocolDocumentationReference("OpenComputers Adapter", "protocols/opencomputersAdapter.md") + + override def worksWith(world: World, x: Int, y: Int, z: Int, side: EnumFacing): Boolean = world.getTileEntity(x, y, z).isInstanceOf[Adapter] + + override def interfaceFor(world: World, x: Int, y: Int, z: Int, side: EnumFacing): SerialInterface = new SerialInterfaceAdapter(world.getTileEntity(x, y, z).asInstanceOf[Adapter]) + + override def isValid(world: World, x: Int, y: Int, z: Int, side: EnumFacing, serialInterface: SerialInterface): Boolean = serialInterface match { + case adapter: SerialInterfaceAdapter => adapter.tileEntity == world.getTileEntity(x, y, z) + case _ => false + } + + class SerialInterfaceAdapter(val tileEntity: Adapter) extends Environment with SerialInterface { + final val BufferCapacity = 128 + final val readBuffer = mutable.Queue.empty[Short] + final val writeBuffer = mutable.Queue.empty[Short] + var isReading = false + + // ----------------------------------------------------------------------- // + + val node = api.Network.newNode(this, Visibility.Network).withComponent("serial_port").create() + + override def onMessage(message: Message): Unit = {} + + override def onConnect(node: Node): Unit = {} + + override def onDisconnect(node: Node): Unit = {} + + // ----------------------------------------------------------------------- // + + @Callback + def setReading(context: Context, args: Arguments): Array[AnyRef] = { + isReading = args.checkBoolean(0) + null + } + + @Callback + def read(context: Context, args: Arguments): Array[AnyRef] = { + readBuffer.synchronized(if (readBuffer.nonEmpty) { + result(readBuffer.dequeue()) + } else { + null + }) + } + + @Callback + def write(context: Context, args: Arguments): Array[AnyRef] = { + writeBuffer.synchronized(if (writeBuffer.length < BufferCapacity) { + writeBuffer += args.checkInteger(0).toShort + result(true) + } else { + result(false, "buffer full") + }) + } + + // ----------------------------------------------------------------------- // + + override def canWrite: Boolean = readBuffer.synchronized(isReading && readBuffer.length < BufferCapacity) + + override def write(value: Short): Unit = readBuffer.synchronized(readBuffer += value) + + override def canRead: Boolean = { + ensureConnected() + writeBuffer.synchronized(writeBuffer.nonEmpty) + } + + override def peek(): Short = writeBuffer.synchronized(writeBuffer.front) + + override def skip(): Unit = writeBuffer.synchronized(writeBuffer.dequeue()) + + override def reset(): Unit = { + readBuffer.synchronized(writeBuffer.synchronized { + readBuffer.clear() + writeBuffer.clear() + node.remove() + }) + } + + private def ensureConnected(): Unit = { + if (tileEntity.node.network != node.network) { + tileEntity.node.connect(node) + } + } + } + +}