added type converter api. doesn't do anything yet, only allows registering converters.

This commit is contained in:
Florian Nücke 2014-03-10 17:51:10 +01:00
parent ce9fccde7a
commit afcc04c90c
5 changed files with 85 additions and 3 deletions

View File

@ -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.
* <p/>
* 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.
* <p/>
* This must be called in the init phase, <em>not</em> the pre- or post-init
* phases.
*
@ -33,6 +38,9 @@ public final class Driver {
/**
* Registers a new item driver.
* <p/>
* Item components can inserted into a computers component slots. They have
* to specify their type, to determine into which slots they can fit.
* <p/>
* This must be called in the init phase, <em>not</em> 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.
* <p/>
* Type converters are used to automatically convert values returned from
* callbacks to a "simple" format that can be pushed to any architecture.
* <p/>
* This must be called in the init phase, <em>not</em> 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() {

View File

@ -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.
* <p/>
* This must be called in the init phase, <em>not</em> the pre- or post-init
* phases.
*
* @param driver the driver for a block component.
*/
@ -20,8 +24,24 @@ public interface DriverAPI {
* <p/>
* Item components can inserted into a computers component slots. They have
* to specify their type, to determine into which slots they can fit.
* <p/>
* This must be called in the init phase, <em>not</em> the pre- or post-init
* phases.
*
* @param driver the driver for an item component.
*/
void add(Item driver);
/**
* Registers a new type converter.
* <p/>
* Type converters are used to automatically convert values returned from
* callbacks to a "simple" format that can be pushed to any architecture.
* <p/>
* This must be called in the init phase, <em>not</em> the pre- or post-init
* phases.
*
* @param converter the converter to register.
*/
void add(Converter converter);
}

View File

@ -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.
* <p/>
* Note that converters operating on the same object type may override each
* other when using the same keys in the resulting <tt>Map</tt>. 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.
* <p/>
* This is primarily enforced to avoid cycles in conversion steps. If the
* returned map contains any unsupported values, they will not be retained.
* <p/>
* 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 <tt>name</tt>, add a key <tt>name</tt> 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);
}

View File

@ -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;

View File

@ -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: _*))