Skip to content

Commit 41a611e

Browse files
authored
Merge pull request #290 from LachlanMcKee/issue-289-add-rxjava3-support
[#289] Added interop-rx3 for Rxjava3 support
2 parents e636b6b + 5ba880f commit 41a611e

File tree

13 files changed

+452
-11
lines changed

13 files changed

+452
-11
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Pending changes
44

5-
5+
- [#289](https://github.com/bumble-tech/appyx/issues/289)**Added**: Introduced `interop-rx3` for RxJava 3 support. This has identical functionality to `interop-rx2`.
66

77
---
88

documentation/releases/downloads.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,9 @@ dependencies {
3838

3939
```groovy
4040
dependencies {
41-
// Optional support for RxJava 2
41+
// Optional support for RxJava 2/3
4242
implementation "com.bumble.appyx:interop-rx2:$version"
43+
implementation "com.bumble.appyx:interop-rx3:$version"
4344
4445
// Optional interoperability layer between Appyx and badoo/RIBs
4546
// You have to add https://jitpack.io repository to use it because badoo/RIBs is hosted there

gradle/libs.versions.toml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ ribs = "0.36.1"
1313
mvicore = "1.2.6"
1414
coroutines = "1.6.4"
1515
kotlin = "1.7.10"
16-
rxjava2 = "2.2.21"
17-
rxandroid = "2.1.1"
1816
junit5 = "5.8.2"
1917
detekt = "1.21.0"
2018
dependencyAnalysis = "1.13.1"
@@ -57,11 +55,13 @@ ribs-base-test = { module = "com.github.badoo.RIBs:rib-base-test", version.ref =
5755
ribs-base-test-activity = { module = "com.github.badoo.RIBs:rib-base-test-activity", version.ref = "ribs" }
5856
ribs-base-test-rx2 = { module = "com.github.badoo.RIBs:rib-base-test-rx2", version.ref = "ribs" }
5957
ribs-compose = { module = "com.github.badoo.RIBs:rib-compose", version.ref = "ribs" }
60-
ribs-rx = { module = "com.github.badoo.RIBs:rib-rx2", version.ref = "ribs" }
6158

62-
rxjava2 = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjava2" }
63-
rxandroid = { module = "io.reactivex.rxjava2:rxandroid", version.ref = "rxandroid" }
64-
rxrelay = "com.jakewharton.rxrelay2:rxrelay:2.1.1"
59+
rxjava2 = "io.reactivex.rxjava2:rxjava:2.2.21"
60+
rxjava3 = "io.reactivex.rxjava3:rxjava:3.1.5"
61+
rxandroid2 = "io.reactivex.rxjava2:rxandroid:2.1.1"
62+
rxandroid3 = "io.reactivex.rxjava3:rxandroid:3.0.2"
63+
rxrelay2 = "com.jakewharton.rxrelay2:rxrelay:2.1.1"
64+
rxrelay3 = "com.jakewharton.rxrelay3:rxrelay:3.0.1"
6565

6666
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
6767
junit-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit5" }

libraries/interop-rx2/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ android {
2626
dependencies {
2727
api(project(":libraries:core"))
2828
api(libs.rxjava2)
29-
api(libs.rxrelay)
29+
api(libs.rxrelay2)
3030

3131
implementation(libs.kotlin.coroutines.rx2)
3232
implementation(libs.androidx.lifecycle.java8)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
plugins {
2+
id("com.android.library")
3+
id("kotlin-android")
4+
id("appyx-publish-android")
5+
id("appyx-lint")
6+
id("appyx-detekt")
7+
}
8+
9+
android {
10+
namespace = "com.bumble.appyx.interop.rx3"
11+
compileSdk = libs.versions.androidCompileSdk.get().toInt()
12+
13+
defaultConfig {
14+
minSdk = libs.versions.androidMinSdk.get().toInt()
15+
targetSdk = libs.versions.androidTargetSdk.get().toInt()
16+
17+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
18+
}
19+
testOptions {
20+
unitTests.all {
21+
it.useJUnitPlatform()
22+
}
23+
}
24+
}
25+
26+
dependencies {
27+
api(project(":libraries:core"))
28+
api(libs.rxjava3)
29+
api(libs.rxrelay3)
30+
31+
implementation(libs.androidx.lifecycle.java8)
32+
33+
testImplementation(libs.junit.api)
34+
testRuntimeOnly(libs.junit.engine)
35+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<issues format="6" by="lint 7.3.1" type="baseline" client="gradle" dependencies="false" name="AGP (7.3.1)" variant="all" version="7.3.1">
3+
4+
</issues>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.bumble.appyx.interop.rx3.connectable
2+
3+
import com.bumble.appyx.core.plugin.NodeLifecycleAware
4+
import com.jakewharton.rxrelay3.Relay
5+
6+
interface Connectable<Input, Output> : NodeLifecycleAware {
7+
val input: Relay<Input>
8+
val output: Relay<Output>
9+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.bumble.appyx.interop.rx3.connectable
2+
3+
import androidx.lifecycle.Lifecycle
4+
import com.bumble.appyx.core.lifecycle.subscribe
5+
import com.jakewharton.rxrelay3.PublishRelay
6+
import com.jakewharton.rxrelay3.Relay
7+
import io.reactivex.rxjava3.core.Observer
8+
9+
class NodeConnector<Input, Output : Any>(
10+
override val input: Relay<Input> = PublishRelay.create(),
11+
) : Connectable<Input, Output> {
12+
13+
private val intake: Relay<Output> = PublishRelay.create()
14+
private val exhaust: Relay<Output> = PublishRelay.create()
15+
private var isFlushed = false
16+
private val outputCache = mutableListOf<Output>()
17+
18+
override val output: Relay<Output> = object : Relay<Output>() {
19+
20+
override fun subscribeActual(observer: Observer<in Output>) {
21+
exhaust.subscribe(observer)
22+
}
23+
24+
override fun accept(value: Output) {
25+
intake.accept(value)
26+
}
27+
28+
override fun hasObservers() = exhaust.hasObservers()
29+
30+
}
31+
32+
override fun onCreate(lifecycle: Lifecycle) {
33+
lifecycle.subscribe(onCreate = { flushOutputCache() })
34+
}
35+
36+
private val cacheSubscription = intake.subscribe {
37+
synchronized(this) {
38+
if (!isFlushed) {
39+
outputCache.add(it)
40+
} else {
41+
exhaust.accept(it)
42+
switchToExhaust()
43+
}
44+
}
45+
}
46+
47+
private fun flushOutputCache() {
48+
synchronized(this) {
49+
if (isFlushed) error("Already flushed")
50+
isFlushed = true
51+
outputCache.forEach { exhaust.accept(it) }
52+
outputCache.clear()
53+
}
54+
}
55+
56+
private fun switchToExhaust() {
57+
intake.subscribe { exhaust.accept(it) }
58+
cacheSubscription.dispose()
59+
}
60+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.bumble.appyx.interop.rx3.plugin
2+
3+
import com.bumble.appyx.core.plugin.Destroyable
4+
import com.bumble.appyx.core.plugin.Plugin
5+
import io.reactivex.rxjava3.disposables.CompositeDisposable
6+
import io.reactivex.rxjava3.disposables.Disposable
7+
8+
private class DisposeOnDestroy(disposables: List<Disposable>) : Destroyable {
9+
private val disposable = CompositeDisposable(disposables)
10+
11+
override fun destroy() {
12+
disposable.dispose()
13+
}
14+
}
15+
16+
fun disposeOnDestroyPlugin(vararg disposables: Disposable): Plugin =
17+
DisposeOnDestroy(disposables.toList())

0 commit comments

Comments
 (0)