Bindings - NibiruOS/model GitHub Wiki
Binds are unidirectional mappings among values. Each time a value changes, the bind propagates the changes to the target value.
If the target value needs some conversion, you can apply a map operation, which receives a function that transforms the value. Bindings are strongly typed, so you need to apply type conversions as well.
The Bind class provides a DSL for creating such binds. The IterableBind class is a shortcut for binding iterables: it applies the mapped function to each element in the iterable.
The way in which binds are created is really simple: just observers are added for each step in the value transformation chain. If you change some value in some way that it does not triggers the observable notification, you can force the bind to be updated by calling notifyObservers()
on the source value.
You can also look at unit tests for more detailed examples.
Value<Integer> source = JavaValue.of(JavaType.INTEGER);
Value<String> target = JavaValue.of(JavaType.STRING);
Bind.on(source)
.map(Object::toString)
.to(target);
source.set(123);
assertEquals("123", target.get());
Value<Integer> source = JavaValue.of(123);
Value<String> target = JavaValue.of(JavaType.STRING);
Bind.on(source)
.map(Object::toString)
.to(target);
assertNull(target.get());
source.notifyObservers();
assertEquals("123", target.get());
Value<Iterable<Integer>> source = JavaValue.of(JavaType.ofIterable(Integer.class));
Value<Iterable<String>> target = JavaValue.of(new ArrayList<>());
IterableBind.on(source)
.map(Object::toString)
.to(target);
source.set(ImmutableList.of(1, 2, 3));
assertEquals(3, Iterables.size(target.get()));
assertEquals("1", Iterables.get(target.get(), 0));
assertEquals("2", Iterables.get(target.get(), 1));
assertEquals("3", Iterables.get(target.get(), 2));