Implementation.class

## Purpose

A required component of a custom circuit implementation folder which completely determines the behavior of the circuit using compiled Java code.

## Getting started

First, define a public class Implementation in the default Java package (no package specified). Give it a no-argument public constructor. Then, make sure to implement...

## tick() and value*k*() methods [Required]

The meat of the implementation. "tick" is responsible for reading input values to the circuit, and each "value*k"* method is repsonsible for returning an output from the circuit. The mappings of indices here [zero at the left, increasing to the right in tick()] correspond to faces using the default Argument Mappings.

**public void tick(T0 input0, T1 input1, ...):**

Given arguments of valid Java primitive types (listed below) representing the input values flowing to this circuit, set the state of member variables of this object to deliver appropriate outputs through the "value*k*()" methods. Every circuit must have at least one input.

**public T0 value0()**

**public T1 value1()**

...

Returns the respective (indexed) outputs (in valid Java primitive types) of this circuit. These methods must rely on the state of the object after invoking the tick method. Every circuit must have at least one output.

## Java Primitives and Bus Widths

To interface between the data carried through Buses in the mod and native Java types, the following bus widths are assumed for Java primitive types unless overridden by specification of an *int[] inputWidths()* or *int[] outputWidths()* method:

* **boolean <-> 1-bit (digital redstone) "bus"**
* **byte <-> 8-bit bus**
* **short <-> 16-bit bus**
* **int <-> 32-bit bus**
* **long <-> 64-bit bus**

If you want your circuit to have a configurable bit-width, it is recommended to use the Java **long** type and specify input/output bit width overrides.

## Bus Width Overrides [Optional]

**int[] inputWidths()**:

In the same order as the arguments to the tick() method [index zero = leftmost argument], specify an override to the circuit's accepted input bus widths.

**int[] outputWidths()**:

In the same order as the return values of the value*k*() methods [index zero corresponds to the return value of value0()], specify an override to the circuit's accepted output bus widths.

## config() method [Optional]

To specify a circuit with configuration options (such as a bit width, the length of a delay, an index into a bus, etc.), you must specify

**public String config(int opt0, int opt1, ...)**

Given the configuration options for this circuit, set appropriate member variables of this object to reflect the configuration. If the configuration is valid, return a non-null *configuration string.* Otherwise, return null.

The configuration string is what appears in the parentheses to the right of a circuit's name when hovered in the inventory. Try to keep the format to an ordered list of options, possibly with "name=" sequences for clarifying the roles of various arguments. For example, "foo=1, bar=6" and just "1, 6" are configuration strings consistent with the style of the strings in the default circuits of the mod.

## isSequential() [Required - Sequential Circuits]

**Signature:** public boolean isSequential()

If specified, and the method returns "true", the circuit will be designated as a sequential circuit. Otherwise, the circuit is assumed to be combinational.

Combinational circuits in the mod may be subject to certain aggressive optimizations to reduce overall server lag. If your circuit is not a combinational circuit, make sure to properly override this to ensure correct behavior!

A "true" return value from this method also signals to the mod that the default circuit tester is not sufficient to test the circuit. You will need to manually specify your own Tests.class.

## Serialization [Required - Sequential + Non-Primitive Member Variables]

If a circuit is sequential, its internal state will need to be saved/loaded to/from NBT on world save/load. By default, all recognized Java primitive member variables will be serialized with the circuit state, but if you create member variables of other types, their values will not be serialized by default. If you have this problem, you must define the following two methods:

**public byte[] serialize():**

Writes the state of the object out to a byte array.

**public boolean deserialize(byte[] in):**

Given the serialized representation of an object of the same class, set the member variables of this object to match the serialized representation. Return true if deserialization was successful, otherwise, return false.