diff --git a/client/src/main/kotlin/com/r3corda/client/fxutils/ObservableUtilities.kt b/client/src/main/kotlin/com/r3corda/client/fxutils/ObservableUtilities.kt new file mode 100644 index 0000000000..b8ac8ea960 --- /dev/null +++ b/client/src/main/kotlin/com/r3corda/client/fxutils/ObservableUtilities.kt @@ -0,0 +1,80 @@ +package com.r3corda.client.fxutils + +import com.r3corda.contracts.asset.Cash +import com.r3corda.core.contracts.StateAndRef +import javafx.beans.binding.Bindings +import javafx.beans.property.ReadOnlyObjectWrapper +import javafx.beans.property.SimpleObjectProperty +import javafx.beans.value.ObservableValue +import javafx.collections.ObservableList +import javafx.collections.transformation.FilteredList +import kotlinx.support.jdk8.collections.stream +import org.fxmisc.easybind.EasyBind +import java.util.function.Predicate +import java.util.stream.Collector + +fun ObservableValue.map(function: (A) -> B): ObservableValue = EasyBind.map(this, function) +fun ObservableList.map(function: (A) -> B): ObservableList = EasyBind.map(this, function) + +fun A.lift(): ObservableValue = ReadOnlyObjectWrapper(this) +fun ((A) -> R).lift( + arg0: ObservableValue +): ObservableValue = EasyBind.map(arg0, this) +fun ((A, B) -> R).lift( + arg0: ObservableValue, + arg1: ObservableValue +): ObservableValue = EasyBind.combine(arg0, arg1, this) +fun ((A, B, C) -> R).lift( + arg0: ObservableValue, + arg1: ObservableValue, + arg2: ObservableValue +): ObservableValue = EasyBind.combine(arg0, arg1, arg2, this) +fun ((A, B, C, D) -> R).lift( + arg0: ObservableValue, + arg1: ObservableValue, + arg2: ObservableValue, + arg3: ObservableValue +): ObservableValue = EasyBind.combine(arg0, arg1, arg2, arg3, this) + +fun ObservableValue.bind(function: (A) -> ObservableValue): ObservableValue = + // We cast here to enforce variance, flatMap should be covariant + @Suppress("UNCHECKED_CAST") + EasyBind.monadic(this).flatMap(function as (A) -> ObservableValue) + +fun ObservableList.filter(predicate: ObservableValue Boolean>): ObservableList { + // We cast here to enforce variance, FilteredList should be covariant + @Suppress("UNCHECKED_CAST") + return FilteredList(this as ObservableList).apply { + predicateProperty().bind(predicate.map { predicateFunction -> + Predicate { predicateFunction(it) } + }) + } +} + +fun ObservableList.fold(initial: B, folderFunction: (B, A) -> B): ObservableValue { + return Bindings.createObjectBinding({ + var current = initial + forEach { + current = folderFunction(current, it) + } + current + }, arrayOf(this)) +} + +fun ObservableList>.flatten(): ObservableList { + return FlattenedList(this) +} + +fun sum(a: Int, b: Int): Int = a + b + +fun main(args: Array) { + val a = SimpleObjectProperty(0) + val b = SimpleObjectProperty(0) + + ::sum.lift(a, b).addListener { observableValue, i0, i1 -> + println(i1) + } + + a.set(2) + b.set(4) +}