Skip to content

Linkables

Linkables are a different way of responding to actions (triggers), input and property changes, based on a simplified form of reactive stream. There is a Linkable<T> generic type, plus primitive versions Linkable.Int and Linkable.Double. All support filter() and map() operations. At the end of the chain a consumer is passed to link() to handle the resulting value.

Built-in sources

Linkables are provided by the built in Input, Trigger and Property types. All links are cleared before init() / setup() is called, so in usual usage you do not need to care about disconnection.

Input

// Linkable of primitive doubles
Linkable.Double values();
// Linkable of subtypes of Value
<T extends Value> Linkable<T> valuesAs(Class<T> valueType);
// Linkable of any type converted from Value
<T> Linkable<T> valuesAs(Function<Value, T> converter);

Property

// Linkable of primitive doubles
Linkable.Double values();
// Linkable of subtypes of Value
<T extends Value> Linkable<T> valuesAs(Class<T> valueType);
// Linkable of any type converted from Value
<T> Linkable<T> valuesAs(Function<Value, T> converter);

Property also has direct link(...) and linkAs(...) methods where mapping and/or filtering is not required.

Trigger

// receives a rising count on each trigger
// wraps to zero at Integer.MAX_VALUE unless maxIndex() set
Linkable.Int on();

Trigger also has a link(Runnable action) method.

Examples

A simple component to uppercase all received input.

@In(1) Input in;
@Out(1) Output out;

public void init() {
    in.valuesAs(Value::toString)
      .map(String::toUpperCase)
      .link(out::send);
}

A component reacting to audio clock and level property.

@T(1) Trigger beat;
@P(1) Property level;
@Out(1) Output note;
@Out(2) Output gain;

public void init() {
  beat.maxIndex(16);
  beat.on()
      .filter(i -> i % 4 == 0)
      .link(i -> note.send(randomOf("a3", "d3", "e3"));
  level.values()
      .map(d -> d * d * d * d)
      .link(gain::send);
}