From afcc04c90caa7ae616b58fbd45cd39e8d603677e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Mon, 10 Mar 2014 17:51:10 +0100 Subject: [PATCH] added type converter api. doesn't do anything yet, only allows registering converters. --- src/main/java/li/cil/oc/api/Driver.java | 23 ++++++++++++++ .../java/li/cil/oc/api/detail/DriverAPI.java | 20 ++++++++++++ .../java/li/cil/oc/api/driver/Converter.java | 31 +++++++++++++++++++ src/main/java/li/cil/oc/api/package-info.java | 2 +- .../li/cil/oc/server/driver/Registry.scala | 12 +++++-- 5 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/main/java/li/cil/oc/api/driver/Converter.java diff --git a/src/main/java/li/cil/oc/api/Driver.java b/src/main/java/li/cil/oc/api/Driver.java index bc83dca16..64e88ebfa 100644 --- a/src/main/java/li/cil/oc/api/Driver.java +++ b/src/main/java/li/cil/oc/api/Driver.java @@ -2,6 +2,7 @@ package li.cil.oc.api; import li.cil.oc.api.detail.DriverAPI; import li.cil.oc.api.driver.Block; +import li.cil.oc.api.driver.Converter; import li.cil.oc.api.driver.Item; /** @@ -21,6 +22,10 @@ public final class Driver { /** * Registers a new block driver. *

+ * Whenever the neighboring blocks of an Adapter block change, it checks if + * there exists a driver for the changed block, and if it is configured to + * interface that block type connects it to the component network. + *

* This must be called in the init phase, not the pre- or post-init * phases. * @@ -33,6 +38,9 @@ public final class Driver { /** * Registers a new item driver. *

+ * Item components can inserted into a computers component slots. They have + * to specify their type, to determine into which slots they can fit. + *

* This must be called in the init phase, not the pre- or post-init * phases. * @@ -42,6 +50,21 @@ public final class Driver { if (instance != null) instance.add(driver); } + /** + * Registers a new type converter. + *

+ * Type converters are used to automatically convert values returned from + * callbacks to a "simple" format that can be pushed to any architecture. + *

+ * This must be called in the init phase, not the pre- or post-init + * phases. + * + * @param converter the converter to register. + */ + public static void add(final Converter converter) { + if (instance != null) instance.add(converter); + } + // ----------------------------------------------------------------------- // private Driver() { diff --git a/src/main/java/li/cil/oc/api/detail/DriverAPI.java b/src/main/java/li/cil/oc/api/detail/DriverAPI.java index 24fb99667..3d4549c7b 100644 --- a/src/main/java/li/cil/oc/api/detail/DriverAPI.java +++ b/src/main/java/li/cil/oc/api/detail/DriverAPI.java @@ -1,6 +1,7 @@ package li.cil.oc.api.detail; import li.cil.oc.api.driver.Block; +import li.cil.oc.api.driver.Converter; import li.cil.oc.api.driver.Item; public interface DriverAPI { @@ -10,6 +11,9 @@ public interface DriverAPI { * Whenever the neighboring blocks of an Adapter block change, it checks if * there exists a driver for the changed block, and if it is configured to * interface that block type connects it to the component network. + *

+ * This must be called in the init phase, not the pre- or post-init + * phases. * * @param driver the driver for a block component. */ @@ -20,8 +24,24 @@ public interface DriverAPI { *

* Item components can inserted into a computers component slots. They have * to specify their type, to determine into which slots they can fit. + *

+ * This must be called in the init phase, not the pre- or post-init + * phases. * * @param driver the driver for an item component. */ void add(Item driver); + + /** + * Registers a new type converter. + *

+ * Type converters are used to automatically convert values returned from + * callbacks to a "simple" format that can be pushed to any architecture. + *

+ * This must be called in the init phase, not the pre- or post-init + * phases. + * + * @param converter the converter to register. + */ + void add(Converter converter); } diff --git a/src/main/java/li/cil/oc/api/driver/Converter.java b/src/main/java/li/cil/oc/api/driver/Converter.java new file mode 100644 index 000000000..823b26c50 --- /dev/null +++ b/src/main/java/li/cil/oc/api/driver/Converter.java @@ -0,0 +1,31 @@ +package li.cil.oc.api.driver; + +import java.util.Map; + +/** + * A converter is a callback that can be used to transparently convert Java + * types to something that can be pushed to a machine's architecture. + *

+ * Note that converters operating on the same object type may override each + * other when using the same keys in the resulting Map. The order in + * which converters are called depends on the order they were registered in. + */ +public interface Converter { + /** + * Converts a type to a Map that only contains valid values, i.e. values + * that can be directly pushed to an architecture, without further + * conversion steps. + *

+ * This is primarily enforced to avoid cycles in conversion steps. If the + * returned map contains any unsupported values, they will not be retained. + *

+ * The conversion result should be placed into the the passed map, i.e. the + * map will represent the original object. For example, if the value had a + * field name, add a key name to the map with the value + * of that field. + * + * @param value the value to convert. + * @param output the map conversion results are accumulated into. + */ + void convert(final Object value, Map output); +} diff --git a/src/main/java/li/cil/oc/api/package-info.java b/src/main/java/li/cil/oc/api/package-info.java index 1063c816a..2b86ad759 100644 --- a/src/main/java/li/cil/oc/api/package-info.java +++ b/src/main/java/li/cil/oc/api/package-info.java @@ -37,5 +37,5 @@ @cpw.mods.fml.common.API( owner = "OpenComputers|Core", provides = "OpenComputersAPI", - apiVersion = "1.4.6") + apiVersion = "1.4.7") package li.cil.oc.api; \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/server/driver/Registry.scala b/src/main/scala/li/cil/oc/server/driver/Registry.scala index 82fb3630f..fddee6665 100644 --- a/src/main/scala/li/cil/oc/server/driver/Registry.scala +++ b/src/main/scala/li/cil/oc/server/driver/Registry.scala @@ -5,6 +5,7 @@ import net.minecraft.item.ItemStack import net.minecraft.world.World import scala.Some import scala.collection.mutable.ArrayBuffer +import li.cil.oc.api.driver.Converter /** * This class keeps track of registered drivers and provides installation logic @@ -21,9 +22,11 @@ import scala.collection.mutable.ArrayBuffer * the computer, but may also provide context-free functions. */ private[oc] object Registry extends api.detail.DriverAPI { - private val blocks = ArrayBuffer.empty[api.driver.Block] + val blocks = ArrayBuffer.empty[api.driver.Block] - private val items = ArrayBuffer.empty[api.driver.Item] + val items = ArrayBuffer.empty[api.driver.Item] + + val converters = ArrayBuffer.empty[api.driver.Converter] /** Used to keep track of whether we're past the init phase. */ var locked = false @@ -38,6 +41,11 @@ private[oc] object Registry extends api.detail.DriverAPI { if (!blocks.contains(driver)) items += driver } + override def add(converter: Converter) { + if (locked) throw new IllegalStateException("Please register all converters in the init phase.") + if (!converters.contains(converter)) converters += converter + } + def blockDriverFor(world: World, x: Int, y: Int, z: Int) = blocks.filter(_.worksWith(world, x, y, z)) match { case drivers if !drivers.isEmpty => Some(new CompoundBlockDriver(drivers: _*))