diff --git a/ui/kotlinx-coroutines-javafx/src/JavaFxConvert.kt b/ui/kotlinx-coroutines-javafx/src/JavaFxConvert.kt index 10c7e7be0d..9725c03f32 100644 --- a/ui/kotlinx-coroutines-javafx/src/JavaFxConvert.kt +++ b/ui/kotlinx-coroutines-javafx/src/JavaFxConvert.kt @@ -1,3 +1,7 @@ +/* + * Copyright 2016-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. + */ + package kotlinx.coroutines.javafx import javafx.beans.value.ChangeListener @@ -20,9 +24,16 @@ import kotlinx.coroutines.flow.flowOn * * Since this implementation uses [ObservableValue.addListener], even if this [ObservableValue] * supports lazy evaluation, eager computation will be enforced while the flow is being collected. + * + * All the calls to JavaFX API are performed in the JavaFX application thread. + * + * ### Operator fusion + * + * Adjacent applications of [flowOn], [buffer], [conflate], and [produceIn] to the result of `asFlow` are fused. + * [conflate] has no effect, as this flow is already conflated; one can use [buffer] to change that instead. */ @ExperimentalCoroutinesApi -public fun ObservableValue.asFlow(): Flow = callbackFlow { +public fun ObservableValue.asFlow(): Flow = callbackFlow { val listener = ChangeListener { _, _, newValue -> try { offer(newValue) diff --git a/ui/kotlinx-coroutines-javafx/test/JavaFxObservableAsFlowTest.kt b/ui/kotlinx-coroutines-javafx/test/JavaFxObservableAsFlowTest.kt index a39dedb551..6964050102 100644 --- a/ui/kotlinx-coroutines-javafx/test/JavaFxObservableAsFlowTest.kt +++ b/ui/kotlinx-coroutines-javafx/test/JavaFxObservableAsFlowTest.kt @@ -24,7 +24,7 @@ class JavaFxObservableAsFlowTest : TestBase() { } val integerProperty = SimpleIntegerProperty(0) - val n = 10000 * stressTestMultiplier + val n = 1000 val flow = integerProperty.asFlow().takeWhile { j -> j != n } newSingleThreadContext("setter").use { pool -> launch(pool) { diff --git a/ui/kotlinx-coroutines-javafx/test/JavaFxStressTest.kt b/ui/kotlinx-coroutines-javafx/test/JavaFxStressTest.kt index a572c0434c..fd7436214a 100644 --- a/ui/kotlinx-coroutines-javafx/test/JavaFxStressTest.kt +++ b/ui/kotlinx-coroutines-javafx/test/JavaFxStressTest.kt @@ -14,7 +14,7 @@ class JavaFxStressTest : TestBase() { } @Test - fun cancellationRaceStressTest() = runTest { + fun testCancellationRace() = runTest { if (!initPlatform()) { println("Skipping JavaFxTest in headless environment") return@runTest // ignore test in headless environments diff --git a/ui/kotlinx-coroutines-javafx/test/examples/FxAsFlow.kt b/ui/kotlinx-coroutines-javafx/test/examples/FxAsFlow.kt index bb0463bd79..3a3745c743 100644 --- a/ui/kotlinx-coroutines-javafx/test/examples/FxAsFlow.kt +++ b/ui/kotlinx-coroutines-javafx/test/examples/FxAsFlow.kt @@ -26,12 +26,12 @@ class FxAsFlowApp: Application(), CoroutineScope { override val coroutineContext: CoroutineContext get() = JavaFx + job - private val incrementBttn = Button("Increment") - private val incrementLabel = Label("") - private val textInput = TextField() - private val flippedTextLabel = Label() - private val spinner = Spinner() - private val spinnerChangesLabel = Label() + private val incrementBttn = Button("Increment") + private val incrementLabel = Label("") + private val textInput = TextField() + private val flippedTextLabel = Label() + private val spinner = Spinner() + private val spinnerChangesLabel = Label() public override fun start( primaryStage: Stage) { val gridPane = GridPane() @@ -61,7 +61,7 @@ class FxAsFlowApp: Application(), CoroutineScope { init { // Initializing the "Increment" button - val stringProperty = SimpleStringProperty("") + val stringProperty = SimpleStringProperty() var i = 0 incrementBttn.onAction = EventHandler { i += 1 @@ -76,7 +76,7 @@ class FxAsFlowApp: Application(), CoroutineScope { } incrementLabel.textProperty().bind(stringProperty) // Initializing the reversed text field - val stringProperty2 = SimpleStringProperty("") + val stringProperty2 = SimpleStringProperty() launch { textInput.textProperty().asFlow().collect { if (it != null) { @@ -88,7 +88,7 @@ class FxAsFlowApp: Application(), CoroutineScope { // Initializing the spinner spinner.valueFactory = SpinnerValueFactory.IntegerSpinnerValueFactory(0, 100) spinner.isEditable = true - val stringProperty3 = SimpleStringProperty("") + val stringProperty3 = SimpleStringProperty() launch { spinner.valueProperty().asFlow().collect { if (it != null) {