33 |
34 |
35 |
--------------------------------------------------------------------------------
/orbit-2-livedata/orbit-2-livedata_build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | plugins {
18 | id("com.android.library")
19 | kotlin("android")
20 | }
21 |
22 | dependencies {
23 | implementation(kotlin("stdlib-jdk8"))
24 | implementation(ProjectDependencies.androidxLifecycleComponents)
25 | implementation(ProjectDependencies.androidxLiveDataKtx)
26 | implementation(ProjectDependencies.kotlinCoroutines)
27 | implementation(ProjectDependencies.kotlinCoroutinesAndroid)
28 |
29 | api(project(":orbit-2-core"))
30 |
31 | // Testing
32 | testImplementation(project(":orbit-2-test"))
33 | testImplementation(project(":test-common"))
34 | testImplementation(ProjectDependencies.androidxTesting)
35 | testImplementation(ProjectDependencies.kotlinCoroutines)
36 | testImplementation(ProjectDependencies.kotlinCoroutinesTest)
37 | GroupedDependencies.testsImplementation.forEach { testImplementation(it) }
38 | testRuntimeOnly(ProjectDependencies.junitJupiterEngine)
39 | }
40 |
--------------------------------------------------------------------------------
/orbit-2-core/src/main/kotlin/com/babylon/orbit2/syntax/strict/OrbitDslPlugin.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.syntax.strict
18 |
19 | import com.babylon.orbit2.Container
20 | import com.babylon.orbit2.syntax.Operator
21 | import kotlinx.coroutines.flow.Flow
22 |
23 | /**
24 | * Extend this interface to create your own DSL plugin.
25 | */
26 | public interface OrbitDslPlugin {
27 | public fun apply(
28 | containerContext: ContainerContext,
29 | flow: Flow,
30 | operator: Operator,
31 | createContext: (event: E) -> VolatileContext
32 | ): Flow
33 |
34 | public class ContainerContext(
35 | public val settings: Container.Settings,
36 | public val postSideEffect: suspend (SE) -> Unit,
37 | private val getState: () -> S,
38 | public val reduce: suspend ((S) -> S) -> Unit
39 | ) {
40 | public val state: S
41 | get() = getState()
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/orbit-2-core/orbit-2-core_build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | plugins {
18 | kotlin("jvm")
19 | }
20 | apply()
21 |
22 | dependencies {
23 | implementation(kotlin("stdlib-jdk8"))
24 | implementation(ProjectDependencies.kotlinCoroutines)
25 |
26 | compileOnly(ProjectDependencies.androidxAnnotation)
27 |
28 | // Testing
29 | testImplementation(project(":orbit-2-test"))
30 | testImplementation(project(":test-common"))
31 | testImplementation(kotlin("test"))
32 | testImplementation(kotlin("test-junit"))
33 | testImplementation(ProjectDependencies.kotlinCoroutinesTest)
34 | testImplementation(ProjectDependencies.kotestAssertions)
35 | }
36 |
37 | // Fix lack of source code when publishing pure Kotlin projects
38 | // See https://github.com/novoda/bintray-release/issues/262
39 | tasks.whenTaskAdded {
40 | if (name == "generateSourcesJarForMavenPublication") {
41 | this as Jar
42 | from(sourceSets.main.get().allSource)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/samples/orbit-2-posts/src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/MainActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.posts.app.features
18 |
19 | import android.os.Bundle
20 | import androidx.appcompat.app.AppCompatActivity
21 | import androidx.appcompat.widget.Toolbar
22 | import androidx.navigation.findNavController
23 | import androidx.navigation.ui.setupActionBarWithNavController
24 | import com.babylon.orbit2.sample.posts.R
25 |
26 | class MainActivity : AppCompatActivity() {
27 |
28 | private val navController by lazy { findNavController(R.id.nav_host_fragment) }
29 |
30 | override fun onCreate(savedInstanceState: Bundle?) {
31 | super.onCreate(savedInstanceState)
32 | setContentView(R.layout.main_activity)
33 |
34 | findViewById(R.id.toolbar).apply {
35 | setSupportActionBar(this)
36 | }
37 |
38 | setupActionBarWithNavController(navController)
39 | }
40 |
41 | override fun onSupportNavigateUp() = navController.navigateUp()
42 | }
43 |
--------------------------------------------------------------------------------
/samples/orbit-2-posts/src/main/kotlin/com/babylon/orbit2/sample/posts/data/posts/network/TypicodeService.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.posts.data.posts.network
18 |
19 | import com.babylon.orbit2.sample.posts.data.posts.model.CommentData
20 | import com.babylon.orbit2.sample.posts.data.posts.model.PostData
21 | import com.babylon.orbit2.sample.posts.data.posts.model.UserData
22 | import retrofit2.http.GET
23 | import retrofit2.http.Path
24 |
25 | // https://jsonplaceholder.typicode.com
26 | interface TypicodeService {
27 | @GET("posts/{id}")
28 | suspend fun post(@Path("id") id: Int): PostData
29 |
30 | @GET("posts")
31 | suspend fun posts(): List
32 |
33 | @GET("users/{id}")
34 | suspend fun user(@Path("id") id: Int): UserData
35 |
36 | @GET("users")
37 | suspend fun users(): List
38 |
39 | @GET("comments")
40 | suspend fun comments(): List
41 |
42 | @GET("posts/{id}/comments")
43 | suspend fun comments(@Path("id") postId: Int): List
44 | }
45 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/README.md:
--------------------------------------------------------------------------------
1 | # Orbit 2 Sample - Stock List
2 |
3 | This sample implements a stock list using [Orbit MVI](https://github.com/babylonhealth/orbit-mvi).
4 |
5 | - The application uses the [strict syntax](../../strict-syntax.md).
6 |
7 | - The application uses Koin for dependency injection which is initialised in
8 | [StockListApplication](src/main/kotlin/com/babylon/orbit2/sample/stocklist/StockListApplication.kt).
9 |
10 | - Streaming data is provided by [Lightstreamer](https://lightstreamer.com) and
11 | their demo server with callback interfaces converted to Kotlin Flow's with
12 | [callbackFlow](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/callback-flow.html).
13 |
14 | - Navigation between the stock list and the detail view uses Jetpack's [Navigation](https://developer.android.com/guide/navigation)
15 | and [Safe Args](https://developer.android.com/guide/navigation/navigation-pass-data#Safe-args).
16 | [ListViewModel](src/main/kotlin/com/babylon/orbit2/sample/stocklist/list/business/ListViewModel.kt)
17 | posts a side effect which [ListFragment](src/main/kotlin/com/babylon/orbit2/sample/stocklist/list/ui/ListFragment.kt)
18 | observes and sends to the `NavController`.
19 |
20 | - Both [ListViewModel](src/main/kotlin/com/babylon/orbit2/sample/stocklist/list/business/ListViewModel.kt)
21 | and [DetailViewModel](src/main/kotlin/com/babylon/orbit2/sample/stocklist/detail/business/DetailViewModel.kt)
22 | use `transformFlow` to receive the streaming data before reducing it to the
23 | UI.
24 |
25 | - [Data Binding Library](https://developer.android.com/topic/libraries/data-binding)
26 | is used to populate layouts throughout.
27 |
--------------------------------------------------------------------------------
/orbit-2-coroutines/README.md:
--------------------------------------------------------------------------------
1 | # Orbit 2 Coroutines plugin
2 |
3 | - [Orbit 2 Coroutines plugin](#orbit-2-coroutines-plugin)
4 | - [transformSuspend](#transformsuspend)
5 | - [transformFlow](#transformflow)
6 |
7 | The coroutine plugin provides Coroutine Orbit operators.
8 |
9 | ```kotlin
10 | implementation("com.babylon.orbit2:orbit-coroutines:")
11 | ```
12 |
13 | ## transformSuspend
14 |
15 | ``` kotlin
16 | suspend fun apiCall(): SomeResult { ... }
17 | suspend fun anotherApiCall(param: SomeResult): OtherResult { ... }
18 |
19 | class ExampleViewModel : ContainerHost {
20 | ...
21 |
22 | fun example(number: Int) = orbit {
23 | transformSuspend { delay(100) }
24 | }
25 | }
26 | fun anotherExample() = orbit {
27 | transformSuspend { apiCall() }
28 | .transformSuspend { anotherApiCall(event) } // "event" is the result of the first api call
29 | }
30 | }
31 | }
32 | ```
33 |
34 | Suspending transformers allow you to call suspending functions
35 |
36 | ## transformFlow
37 |
38 | ``` kotlin
39 | fun subscribeToLocationUpdates(): Flow { ... }
40 |
41 | class ExampleViewModel : ContainerHost {
42 | ...
43 |
44 | fun startLocationTracking() = orbit {
45 | transformFlow { subscribeToLocationUpdates() }
46 | .reduce { state.copy(currentLocation = event) }
47 | }
48 | }
49 | }
50 | ```
51 |
52 | You can use this operator to subscribe to hot or cold coroutine flows. The flows
53 | will emit until completion or until the
54 | [Container](../orbit-2-core/src/main/kotlin/com/babylon/orbit2/Container.kt) has
55 | been closed.
56 |
--------------------------------------------------------------------------------
/orbit-2-core/src/main/kotlin/com/babylon/orbit2/syntax/strict/OrbitDslPlugins.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.syntax.strict
18 |
19 | /**
20 | * Orbit DSL plugin registry. In order for DSL extensions to work they need to be registered here
21 | * before use.
22 | *
23 | * The base DSL provided by [BaseDslPlugin] does not have to be registered as it is registered
24 | * implicitly, even after a [reset].
25 | */
26 | public object OrbitDslPlugins {
27 |
28 | internal var plugins: Set = setOf(BaseDslPlugin)
29 | private set
30 |
31 | /**
32 | * Register DSL plugins. This has to be done before using the DSL provided by the plugin.
33 | *
34 | * @param plugin The DSL plugin to register
35 | */
36 | public fun register(plugin: OrbitDslPlugin) {
37 | if (!plugins.contains(plugin)) {
38 | plugins = plugins + plugin
39 | }
40 | }
41 |
42 | /**
43 | * Clears all registered plugins apart from the [BaseDslPlugin].
44 | */
45 | public fun reset() {
46 | plugins = setOf(BaseDslPlugin)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/orbit-2-viewmodel/orbit-2-viewmodel_build.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | plugins {
18 | id("com.android.library")
19 | kotlin("android")
20 | id("kotlin-android-extensions")
21 | }
22 |
23 | dependencies {
24 | implementation(kotlin("stdlib-jdk8"))
25 | implementation(ProjectDependencies.kotlinCoroutines)
26 |
27 | api(project(":orbit-2-core"))
28 |
29 | implementation(ProjectDependencies.androidxLifecycleSavedState)
30 | implementation(ProjectDependencies.androidxLifecycleKtx)
31 | implementation(ProjectDependencies.androidxEspressoIdlingResource)
32 |
33 | // Testing
34 | testImplementation(project(":orbit-2-test"))
35 | testImplementation(project(":test-common"))
36 | testImplementation(project(":orbit-2-coroutines"))
37 | testImplementation(ProjectDependencies.androidxEspressoCore)
38 | testImplementation(ProjectDependencies.robolectric)
39 |
40 | GroupedDependencies.testsImplementation.forEach { testImplementation(it) }
41 | testRuntimeOnly(ProjectDependencies.junitJupiterEngine)
42 | }
43 |
44 | android {
45 | testOptions.unitTests.isIncludeAndroidResources = true
46 | }
47 |
--------------------------------------------------------------------------------
/samples/orbit-2-posts/README.md:
--------------------------------------------------------------------------------
1 | # Orbit 2 Sample - Posts
2 |
3 | This sample implements a simple master-detail application using
4 | [Orbit MVI](https://github.com/babylonhealth/orbit-mvi).
5 |
6 | - The application uses the [simple syntax](../../simple-syntax.md).
7 |
8 | - The application uses Koin for dependency injection which is initialised in
9 | [PostsApplication](src/main/kotlin/com/babylon/orbit2/sample/posts/app//PostsApplication.kt).
10 |
11 | - [PostListViewModel](src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postlist/viewmodel/PostListViewModel.kt)
12 | loads a list of posts. Upon clicking a post it navigates to the
13 | [PostDetailsFragment](src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postdetails/ui/PostDetailsFragment.kt)
14 | which displays the details of the clicked post.
15 |
16 | - Navigation between the list and the detail view uses Jetpack's
17 | [Navigation](https://developer.android.com/guide/navigation) and
18 | [SafeArgs](https://developer.android.com/guide/navigation/navigation-pass-data#Safe-args).
19 | [PostListViewModel](src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postlist/viewmodel/PostListViewModel.kt)
20 | posts a side effect which
21 | [PostListFragment](src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postlist/ui/PostListFragment.kt)
22 | observes and sends to the `NavController`.
23 |
24 | - The state is accessed in the fragments through `Flow`.
25 |
26 | - [PostListViewModel](src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postlist/viewmodel/PostListViewModel.kt)
27 | and
28 | [PostDetailsViewModel](src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postdetails/viewmodel/PostDetailsViewModel.kt)
29 | use a `SavedStateHandle` for retaining the current state.
30 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/src/main/kotlin/com/babylon/orbit2/sample/stocklist/list/ui/TickAnimation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.stocklist.list.ui
18 |
19 | import android.view.View
20 | import android.widget.TextView
21 | import kotlinx.coroutines.GlobalScope
22 | import kotlinx.coroutines.Job
23 | import kotlinx.coroutines.async
24 | import kotlinx.coroutines.delay
25 |
26 | fun animateChange(textView: TextView, tick: CheckableImageView, newValue: String, jobReference: JobHolder) {
27 | val currentValue = textView.text.toString()
28 | if (newValue != currentValue && currentValue.isNotEmpty()) {
29 | val diff = newValue.toDouble().compareTo(currentValue.toDouble())
30 |
31 | if (diff != 0) {
32 | tick.isChecked = diff > 0
33 | tick.visibility = View.VISIBLE
34 |
35 | jobReference.job?.cancel()
36 |
37 | jobReference.job = GlobalScope.async {
38 | @Suppress("MagicNumber")
39 | (delay(300))
40 |
41 | tick.visibility = View.INVISIBLE
42 | }
43 | }
44 | }
45 | }
46 |
47 | class JobHolder(var job: Job? = null)
48 |
--------------------------------------------------------------------------------
/gradle/scripts/detekt.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import io.gitlab.arturbosch.detekt.Detekt
18 | import io.gitlab.arturbosch.detekt.DetektPlugin
19 |
20 | buildscript {
21 | repositories {
22 | maven(url = "https://plugins.gradle.org/m2/")
23 | }
24 | dependencies {
25 | classpath(PluginDependencies.detekt)
26 | }
27 | }
28 |
29 | repositories {
30 | jcenter()
31 | }
32 |
33 | apply()
34 |
35 | tasks.named("detekt", Detekt::class.java).configure {
36 | setSource(files(rootProject.projectDir))
37 |
38 | include("**/*.kt")
39 | include("**/*.kts")
40 | exclude("**/resources/**")
41 | exclude("**/build/**")
42 |
43 | parallel = true
44 |
45 | autoCorrect = true
46 | buildUponDefaultConfig = true
47 | config.setFrom(files("${rootProject.projectDir}/gradle/scripts/detekt.yml"))
48 |
49 | reports {
50 | xml {
51 | enabled = true
52 | destination = file("build/reports/detekt/detekt.xml")
53 | }
54 | html {
55 | enabled = true
56 | }
57 | }
58 | }
59 |
60 | dependencies {
61 | "detektPlugins"(ProjectDependencies.detektFormatting)
62 | }
63 |
--------------------------------------------------------------------------------
/samples/orbit-2-posts/src/main/res/layout/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
24 |
25 |
28 |
29 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/gradle/scripts/jacoco-android.gradle.kts:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | apply()
18 |
19 | val jacocoTask = tasks.register("jacocoTestReport") {
20 | dependsOn(tasks.named("testDebugUnitTest"))
21 |
22 | reports {
23 | html.isEnabled = true
24 | xml.isEnabled = true
25 | csv.isEnabled = false
26 | }
27 |
28 | val fileFilter = listOf(
29 | "**/R.class",
30 | "**/R\$*.class",
31 | "**/BuildConfig.*",
32 | "**/Manifest*.*",
33 | "**/*Test*.*",
34 | "android/**/*.*"
35 | )
36 | val debugTree = fileTree("${project.buildDir}/intermediates/javac/debug") {
37 | exclude(fileFilter)
38 | }
39 |
40 | val mainSrc = "${project.projectDir}/src/main/kotlin"
41 |
42 | sourceDirectories.setFrom(files(listOf(mainSrc)))
43 | classDirectories.setFrom(files(listOf(debugTree)))
44 | executionData.setFrom(
45 | fileTree(project.buildDir) {
46 | include(listOf("jacoco/testDebugUnitTest.exec"))
47 | }
48 | )
49 | }
50 |
51 | tasks.withType {
52 | finalizedBy(jacocoTask)
53 | extensions.getByType().isIncludeNoLocationClasses = true
54 | }
55 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/src/main/kotlin/com/babylon/orbit2/sample/stocklist/detail/business/DetailViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.stocklist.detail.business
18 |
19 | import androidx.lifecycle.SavedStateHandle
20 | import androidx.lifecycle.ViewModel
21 | import com.babylon.orbit2.ContainerHost
22 | import com.babylon.orbit2.coroutines.transformFlow
23 | import com.babylon.orbit2.sample.stocklist.streaming.stock.StockRepository
24 | import com.babylon.orbit2.syntax.strict.orbit
25 | import com.babylon.orbit2.syntax.strict.reduce
26 | import com.babylon.orbit2.viewmodel.container
27 |
28 | class DetailViewModel(
29 | savedStateHandle: SavedStateHandle,
30 | private val itemName: String,
31 | private val stockRepository: StockRepository
32 | ) : ViewModel(), ContainerHost {
33 |
34 | override val container =
35 | container(DetailState(), savedStateHandle) { requestStock() }
36 |
37 | private fun requestStock(): Unit = orbit {
38 | transformFlow {
39 | stockRepository.stockDetails(itemName)
40 | }.reduce {
41 | state.copy(stock = event)
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/src/main/res/layout/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
13 |
14 |
20 |
21 |
22 |
23 |
29 |
30 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/orbit-2-livedata/src/test/kotlin/com/babylon/orbit2/livedata/InstantTaskExecutorExtension.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.livedata
18 |
19 | import androidx.arch.core.executor.ArchTaskExecutor
20 | import androidx.arch.core.executor.TaskExecutor
21 | import org.junit.jupiter.api.extension.AfterEachCallback
22 | import org.junit.jupiter.api.extension.BeforeEachCallback
23 | import org.junit.jupiter.api.extension.ExtensionContext
24 |
25 | class InstantTaskExecutorExtension : BeforeEachCallback, AfterEachCallback {
26 | override fun beforeEach(context: ExtensionContext?) {
27 | ArchTaskExecutor.getInstance().setDelegate(
28 | object : TaskExecutor() {
29 | override fun executeOnDiskIO(runnable: Runnable) {
30 | runnable.run()
31 | }
32 |
33 | override fun postToMainThread(runnable: Runnable) {
34 | runnable.run()
35 | }
36 |
37 | override fun isMainThread(): Boolean {
38 | return true
39 | }
40 | }
41 | )
42 | }
43 |
44 | override fun afterEach(context: ExtensionContext?) {
45 | ArchTaskExecutor.getInstance().setDelegate(null)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/samples/orbit-2-posts/src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postdetails/ui/PostCommentItem.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.posts.app.features.postdetails.ui
18 |
19 | import android.widget.TextView
20 | import com.babylon.orbit2.sample.posts.R
21 | import com.babylon.orbit2.sample.posts.domain.repositories.PostComment
22 | import com.xwray.groupie.kotlinandroidextensions.GroupieViewHolder
23 | import com.xwray.groupie.kotlinandroidextensions.Item
24 |
25 | data class PostCommentItem(private val post: PostComment) : Item() {
26 |
27 | override fun isSameAs(other: com.xwray.groupie.Item<*>) = other is PostCommentItem && post.id == other.post.id
28 |
29 | override fun hasSameContentAs(other: com.xwray.groupie.Item<*>) = other is PostCommentItem && post == other.post
30 |
31 | override fun getLayout() = R.layout.post_comment_list_item
32 |
33 | override fun bind(viewHolder: GroupieViewHolder, position: Int) {
34 | viewHolder.itemView.apply {
35 | findViewById(R.id.comment_username).text = post.name
36 | findViewById(R.id.comment_email).text = post.email
37 | findViewById(R.id.comment_body).text = post.body
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/samples/orbit-2-calculator/README.md:
--------------------------------------------------------------------------------
1 | # Orbit 2 Sample - Calculator
2 |
3 | This sample implements a simple calculator using [Orbit MVI](https://github.com/babylonhealth/orbit-mvi).
4 |
5 | - The application uses the [simple syntax](../../simple-syntax.md).
6 |
7 | - The application uses Koin for dependency injection which is initialised in
8 | [CalculatorApplication](src/main/kotlin/com/babylon/orbit2/sample/calculator/CalculatorApplication.kt).
9 |
10 | - [CalculatorActivity](src/main/kotlin/com/babylon/orbit2/sample/calculator/CalculatorActivity.kt)
11 | uses the [Data Binding Library](https://developer.android.com/topic/libraries/data-binding)
12 | to provide the [CalculatorViewModel](src/main/kotlin/com/babylon/orbit2/sample/calculator/CalculatorViewModel.kt)
13 | to the layout [activity_main.xml](src/main/res/layout/activity_main.xml). The
14 | layout accesses the current state through LiveData.
15 |
16 | - [CalculatorViewModel](src/main/kotlin/com/babylon/orbit2/sample/calculator/CalculatorViewModel.kt)
17 | uses a `SavedStateHandle` for retaining the current state. It implements a
18 | private [ContainerHost](../../orbit-2-core/src/main/kotlin/com/babylon/orbit2/ContainerHost.kt)
19 | so the internal implementation of [CalculatorState](src/main/kotlin/com/babylon/orbit2/sample/calculator/CalculatorState.kt)
20 | is not exposed.
21 |
22 | ## How the calculator works
23 |
24 | The calculator itself is based off the principle of two registers, x and y. In
25 | short:
26 |
27 | - Digits are stored in the x register.
28 | - The x register is rendered to screen unless it is empty in which case we
29 | render the y register.
30 | - Plus, minus, multiply and divide operators transfer data from x to y register
31 | and then clears x. The operator is stored as it is not actioned immediately.
32 | - Equals operator performs the calculation using the stored operator and the
33 | values in the x and y registers.
34 |
--------------------------------------------------------------------------------
/samples/orbit-2-posts/src/test/kotlin/com/babylon/orbit2/sample/posts/InstantTaskExecutorExtension.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.posts
18 |
19 | import androidx.arch.core.executor.ArchTaskExecutor
20 | import androidx.arch.core.executor.TaskExecutor
21 | import org.junit.jupiter.api.extension.AfterEachCallback
22 | import org.junit.jupiter.api.extension.BeforeEachCallback
23 | import org.junit.jupiter.api.extension.ExtensionContext
24 |
25 | class InstantTaskExecutorExtension : BeforeEachCallback, AfterEachCallback {
26 | override fun beforeEach(context: ExtensionContext?) {
27 | ArchTaskExecutor.getInstance().setDelegate(
28 | object : TaskExecutor() {
29 | override fun executeOnDiskIO(runnable: Runnable) {
30 | runnable.run()
31 | }
32 |
33 | override fun postToMainThread(runnable: Runnable) {
34 | runnable.run()
35 | }
36 |
37 | override fun isMainThread(): Boolean {
38 | return true
39 | }
40 | }
41 | )
42 | }
43 |
44 | override fun afterEach(context: ExtensionContext?) {
45 | ArchTaskExecutor.getInstance().setDelegate(null)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/src/main/kotlin/com/babylon/orbit2/sample/stocklist/MainActivity.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.stocklist
18 |
19 | import android.os.Bundle
20 | import androidx.appcompat.app.AppCompatActivity
21 | import androidx.appcompat.widget.Toolbar
22 | import androidx.navigation.findNavController
23 | import androidx.navigation.ui.setupActionBarWithNavController
24 | import com.babylon.orbit2.sample.stocklist.streaming.StreamingClient
25 | import org.koin.android.ext.android.inject
26 |
27 | class MainActivity : AppCompatActivity() {
28 |
29 | private val navController by lazy { findNavController(R.id.nav_host_fragment) }
30 |
31 | private val streamingClient by inject()
32 |
33 | override fun onCreate(savedInstanceState: Bundle?) {
34 | super.onCreate(savedInstanceState)
35 | setContentView(R.layout.main_activity)
36 |
37 | findViewById(R.id.toolbar).apply {
38 | setSupportActionBar(this)
39 | setLogo(R.drawable.ic_orbit_toolbar)
40 | }
41 |
42 | setupActionBarWithNavController(navController)
43 |
44 | lifecycle.addObserver(streamingClient)
45 | }
46 |
47 | override fun onSupportNavigateUp() = navController.navigateUp()
48 | }
49 |
--------------------------------------------------------------------------------
/orbit-2-viewmodel/src/main/kotlin/com/babylon/orbit2/viewmodel/SavedStateContainerDecorator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.viewmodel
18 |
19 | import androidx.lifecycle.SavedStateHandle
20 | import com.babylon.orbit2.Container
21 | import com.babylon.orbit2.ContainerDecorator
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugin
23 | import kotlinx.coroutines.flow.Flow
24 | import kotlinx.coroutines.flow.collect
25 | import kotlinx.coroutines.flow.flow
26 |
27 | internal class SavedStateContainerDecorator(
28 | override val actual: Container,
29 | private val savedStateHandle: SavedStateHandle
30 | ) : ContainerDecorator {
31 | override val currentState: STATE
32 | get() = actual.currentState
33 |
34 | override val stateFlow: Flow
35 | get() = flow {
36 | actual.stateFlow.collect {
37 | savedStateHandle[SAVED_STATE_KEY] = it
38 | emit(it)
39 | }
40 | }
41 | override val sideEffectFlow: Flow
42 | get() = actual.sideEffectFlow
43 |
44 | override fun orbit(orbitFlow: suspend OrbitDslPlugin.ContainerContext.() -> Unit) =
45 | actual.orbit(orbitFlow)
46 | }
47 |
--------------------------------------------------------------------------------
/test-common/src/main/kotlin/com/babylon/orbit2/test/ScopedBlockingWorkSimulator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.test
18 |
19 | import kotlinx.coroutines.CoroutineScope
20 | import kotlinx.coroutines.Dispatchers
21 | import kotlinx.coroutines.Job
22 | import kotlinx.coroutines.channels.awaitClose
23 | import kotlinx.coroutines.channels.produce
24 | import kotlinx.coroutines.currentCoroutineContext
25 | import kotlinx.coroutines.isActive
26 | import kotlinx.coroutines.launch
27 | import kotlinx.coroutines.runBlocking
28 |
29 | @Suppress("EXPERIMENTAL_API_USAGE")
30 | public class ScopedBlockingWorkSimulator(private val scope: CoroutineScope) {
31 |
32 | private var job: Job? = null
33 |
34 | init {
35 | scope.produce(Dispatchers.Unconfined) {
36 | awaitClose {
37 | job?.cancel()
38 | }
39 | }
40 | }
41 |
42 | @Suppress("ControlFlowWithEmptyBody", "EmptyWhileBlock")
43 | public fun simulateWork() {
44 | if (job != null) {
45 | throw IllegalStateException("Can be invoked only once")
46 | }
47 | job = scope.launch {
48 | while (currentCoroutineContext().isActive) {
49 | }
50 | }
51 | runBlocking(job!!) { job!!.join() }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/samples/orbit-2-calculator/src/test/kotlin/com/babylon/orbit2/sample/calculator/livedata/InstantTaskExecutorExtension.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.calculator.livedata
18 |
19 | import androidx.arch.core.executor.ArchTaskExecutor
20 | import androidx.arch.core.executor.TaskExecutor
21 | import org.junit.jupiter.api.extension.AfterEachCallback
22 | import org.junit.jupiter.api.extension.BeforeEachCallback
23 | import org.junit.jupiter.api.extension.ExtensionContext
24 |
25 | class InstantTaskExecutorExtension : BeforeEachCallback, AfterEachCallback {
26 | override fun beforeEach(context: ExtensionContext?) {
27 | ArchTaskExecutor.getInstance().setDelegate(
28 | object : TaskExecutor() {
29 | override fun executeOnDiskIO(runnable: Runnable) {
30 | runnable.run()
31 | }
32 |
33 | override fun postToMainThread(runnable: Runnable) {
34 | runnable.run()
35 | }
36 |
37 | override fun isMainThread(): Boolean {
38 | return true
39 | }
40 | }
41 | )
42 | }
43 |
44 | override fun afterEach(context: ExtensionContext?) {
45 | ArchTaskExecutor.getInstance().setDelegate(null)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-core/src/test/kotlin/com/babylon/orbit2/syntax/strict/OrbitDslPluginsTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.syntax.strict
18 |
19 | import com.babylon.orbit2.syntax.Operator
20 | import io.kotest.matchers.collections.shouldContainExactly
21 | import kotlinx.coroutines.flow.Flow
22 | import kotlin.test.AfterTest
23 | import kotlin.test.Test
24 |
25 | internal class OrbitDslPluginsTest {
26 |
27 | @AfterTest
28 | fun afterEach() {
29 | OrbitDslPlugins.reset()
30 | }
31 |
32 | @Test
33 | fun `base plugin is present by default`() {
34 | OrbitDslPlugins.plugins.shouldContainExactly(BaseDslPlugin)
35 | }
36 |
37 | @Test
38 | fun `base plugin is present after another plugin has been added`() {
39 |
40 | OrbitDslPlugins.register(TestPlugin)
41 |
42 | OrbitDslPlugins.plugins.shouldContainExactly(BaseDslPlugin, TestPlugin)
43 | }
44 |
45 | private object TestPlugin : OrbitDslPlugin {
46 | override fun apply(
47 | containerContext: OrbitDslPlugin.ContainerContext,
48 | flow: Flow,
49 | operator: Operator,
50 | createContext: (event: E) -> VolatileContext
51 | ): Flow {
52 | return flow
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/orbit-2-test/src/test/kotlin/com/babylon/orbit2/SideEffectTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2
18 |
19 | import kotlinx.coroutines.ExperimentalCoroutinesApi
20 | import kotlin.test.Test
21 |
22 | @ExperimentalCoroutinesApi
23 | internal class SideEffectTest {
24 | @Test
25 | fun `BLOCKING - succeeds if posted side effects match expected side effects`() {
26 | ParameterisedSideEffectTest(blocking = true)
27 | .`succeeds if posted side effects match expected side effects`()
28 | }
29 |
30 | @Test
31 | fun `NON BLOCKING - succeeds if posted side effects match expected side effects`() {
32 | ParameterisedSideEffectTest(blocking = false)
33 | .`succeeds if posted side effects match expected side effects`()
34 | }
35 |
36 | @Test
37 | fun `BLOCKING - fails if posted side effects do not match expected side effects`() {
38 | ParameterisedSideEffectTest(blocking = true)
39 | .`fails if posted side effects do not match expected side effects`()
40 | }
41 |
42 | @Test
43 | fun `NON BLOCKING - fails if posted side effects do not match expected side effects`() {
44 | ParameterisedSideEffectTest(blocking = false)
45 | .`fails if posted side effects do not match expected side effects`()
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava1/src/main/kotlin/com/babylon/orbit2/rxjava1/RxJava1Single.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava1
18 |
19 | import com.babylon.orbit2.syntax.Operator
20 | import com.babylon.orbit2.syntax.Orbit2Dsl
21 | import com.babylon.orbit2.syntax.strict.Builder
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import rx.Single
25 |
26 | internal class RxJava1Single(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Single
29 | ) : Operator
30 |
31 | /**
32 | * The observable transformer flat maps incoming [VolatileContext] for every event into a [Single] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Single] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx1Single(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Single
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava1DslPlugin)
46 | return add(RxJava1Single(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/src/main/kotlin/com/babylon/orbit2/sample/stocklist/streaming/EmptySubscriptionListener.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) Lightstreamer Srl
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.stocklist.streaming
18 |
19 | import com.lightstreamer.client.ItemUpdate
20 | import com.lightstreamer.client.Subscription
21 | import com.lightstreamer.client.SubscriptionListener
22 |
23 | /**
24 | * Empty SubscriptionListener
25 | */
26 | @Suppress("TooManyFunctions")
27 | object EmptySubscriptionListener : SubscriptionListener {
28 | override fun onListenEnd(p0: Subscription) = Unit
29 |
30 | override fun onItemUpdate(p0: ItemUpdate) = Unit
31 |
32 | override fun onSubscription() = Unit
33 |
34 | override fun onEndOfSnapshot(p0: String?, p1: Int) = Unit
35 |
36 | override fun onItemLostUpdates(p0: String?, p1: Int, p2: Int) = Unit
37 |
38 | override fun onSubscriptionError(p0: Int, p1: String?) = Unit
39 |
40 | override fun onClearSnapshot(p0: String?, p1: Int) = Unit
41 |
42 | override fun onCommandSecondLevelSubscriptionError(p0: Int, p1: String?, p2: String?) = Unit
43 |
44 | override fun onUnsubscription() = Unit
45 |
46 | override fun onCommandSecondLevelItemLostUpdates(p0: Int, p1: String) = Unit
47 |
48 | override fun onListenStart(p0: Subscription) = Unit
49 |
50 | override fun onRealMaxFrequency(p0: String?) = Unit
51 | }
52 |
--------------------------------------------------------------------------------
/orbit-2-rxjava2/src/main/kotlin/com/babylon/orbit2/rxjava2/RxJava2Maybe.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava2
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.Maybe
25 |
26 | internal class RxJava2Maybe(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Maybe
29 | ) : Operator
30 |
31 | /**
32 | * The maybe transformer flat maps incoming [VolatileContext] for every event into a [Maybe] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Maybe] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx2Maybe(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Maybe
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava2DslPlugin)
46 | return add(RxJava2Maybe(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava1/src/main/kotlin/com/babylon/orbit2/rxjava1/RxJava1Completable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava1
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import rx.Completable
25 |
26 | internal class RxJava1Completable(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Completable
29 | ) : Operator
30 |
31 | /**
32 | * The maybe transformer flat maps incoming [VolatileContext] for every event into a [Completable] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Completable] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx1Completable(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Completable
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava1DslPlugin)
46 | return add(RxJava1Completable(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava2/src/main/kotlin/com/babylon/orbit2/rxjava2/RxJava2Single.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava2
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.Single
25 |
26 | internal class RxJava2Single(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Single
29 | ) : Operator
30 |
31 | /**
32 | * The observable transformer flat maps incoming [VolatileContext] for every event into a [Single] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Single] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx2Single(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Single
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava2DslPlugin)
46 | return add(RxJava2Single(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava3/src/main/kotlin/com/babylon/orbit2/rxjava3/RxJava3Maybe.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava3
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.rxjava3.core.Maybe
25 |
26 | internal class RxJava3Maybe(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Maybe
29 | ) : Operator
30 |
31 | /**
32 | * The maybe transformer flat maps incoming [VolatileContext] for every event into a [Maybe] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Maybe] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx3Maybe(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Maybe
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava3DslPlugin)
46 | return add(RxJava3Maybe(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-coroutines/src/main/kotlin/com/babylon/orbit2/coroutines/TransformSuspend.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.coroutines
18 |
19 | import com.babylon.orbit2.syntax.Operator
20 | import com.babylon.orbit2.syntax.Orbit2Dsl
21 | import com.babylon.orbit2.syntax.strict.Builder
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import kotlinx.coroutines.Dispatchers
25 |
26 | internal class TransformSuspend(
27 | override val registerIdling: Boolean,
28 | val block: suspend VolatileContext.() -> E2
29 | ) : Operator
30 |
31 | /**
32 | * The suspend transformer maps the incoming state and event into a new event using a suspending
33 | * lambda.
34 | *
35 | * The transformer executes on [Dispatchers.IO] by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the suspending lambda returning a new event given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformSuspend(
42 | registerIdling: Boolean = true,
43 | block: suspend VolatileContext.() -> E2
44 | ): Builder {
45 | OrbitDslPlugins.register(CoroutineDslPlugin)
46 | return add(TransformSuspend(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/src/main/kotlin/com/babylon/orbit2/sample/stocklist/list/business/ListViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.stocklist.list.business
18 |
19 | import androidx.lifecycle.SavedStateHandle
20 | import androidx.lifecycle.ViewModel
21 | import com.babylon.orbit2.ContainerHost
22 | import com.babylon.orbit2.coroutines.transformFlow
23 | import com.babylon.orbit2.sample.stocklist.streaming.stock.StockRepository
24 | import com.babylon.orbit2.syntax.strict.orbit
25 | import com.babylon.orbit2.syntax.strict.reduce
26 | import com.babylon.orbit2.syntax.strict.sideEffect
27 | import com.babylon.orbit2.viewmodel.container
28 |
29 | class ListViewModel(
30 | savedStateHandle: SavedStateHandle,
31 | private val stockRepository: StockRepository
32 | ) : ViewModel(), ContainerHost {
33 |
34 | override val container = container(ListState(), savedStateHandle) { requestStocks() }
35 |
36 | private fun requestStocks(): Unit = orbit {
37 | transformFlow {
38 | stockRepository.stockList()
39 | }.reduce {
40 | state.copy(stocks = event)
41 | }
42 | }
43 |
44 | fun viewMarket(itemName: String) = orbit {
45 | sideEffect {
46 | post(ListSideEffect.NavigateToDetail(itemName))
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/orbit-2-rxjava2/src/main/kotlin/com/babylon/orbit2/rxjava2/RxJava2Completable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava2
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.Completable
25 |
26 | internal class RxJava2Completable(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Completable
29 | ) : Operator
30 |
31 | /**
32 | * The maybe transformer flat maps incoming [VolatileContext] for every event into a [Completable] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Completable] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx2Completable(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Completable
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava2DslPlugin)
46 | return add(RxJava2Completable(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava3/src/main/kotlin/com/babylon/orbit2/rxjava3/RxJava3Single.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava3
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.rxjava3.core.Single
25 |
26 | internal class RxJava3Single(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Single
29 | ) : Operator
30 |
31 | /**
32 | * The observable transformer flat maps incoming [VolatileContext] for every event into a [Single] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Single] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx3Single(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Single
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava3DslPlugin)
46 | return add(RxJava3Single(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava1/src/main/kotlin/com/babylon/orbit2/rxjava1/RxJava1Observable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava1
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import rx.Observable
25 |
26 | internal class RxJava1Observable(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Observable
29 | ) : Operator
30 |
31 | /**
32 | * The observable transformer flat maps incoming [VolatileContext] for every event into an [Observable] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: false
38 | * @param block the lambda returning a new observable of events given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx1Observable(
42 | registerIdling: Boolean = false,
43 | block: VolatileContext.() -> Observable
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava1DslPlugin)
46 | return add(RxJava1Observable(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava3/src/main/kotlin/com/babylon/orbit2/rxjava3/RxJava3Completable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava3
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.rxjava3.core.Completable
25 |
26 | internal class RxJava3Completable(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Completable
29 | ) : Operator
30 |
31 | /**
32 | * The maybe transformer flat maps incoming [VolatileContext] for every event into a [Completable] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: true
38 | * @param block the lambda returning a new [Completable] given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx3Completable(
42 | registerIdling: Boolean = true,
43 | block: VolatileContext.() -> Completable
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava3DslPlugin)
46 | return add(RxJava3Completable(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-coroutines/src/main/kotlin/com/babylon/orbit2/coroutines/TransformFlow.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.coroutines
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import kotlinx.coroutines.Dispatchers
25 | import kotlinx.coroutines.flow.Flow
26 |
27 | internal class TransformFlow(
28 | override val registerIdling: Boolean,
29 | val block: suspend VolatileContext.() -> Flow
30 | ) : Operator
31 |
32 | /**
33 | * The flow transformer flat maps incoming [VolatileContext] for every event into coroutine flows.
34 | *
35 | * The transformer executes on [Dispatchers.IO] by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: false
38 | * @param block the suspending lambda returning a new flow of events given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformFlow(
42 | registerIdling: Boolean = false,
43 | block: suspend VolatileContext.() -> Flow
44 | ): Builder {
45 | OrbitDslPlugins.register(CoroutineDslPlugin)
46 | return add(TransformFlow(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-rxjava2/src/main/kotlin/com/babylon/orbit2/rxjava2/RxJava2Observable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava2
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.Observable
25 |
26 | internal class RxJava2Observable(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Observable
29 | ) : Operator
30 |
31 | /**
32 | * The observable transformer flat maps incoming [VolatileContext] for every event into an [Observable] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: false
38 | * @param block the lambda returning a new observable of events given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx2Observable(
42 | registerIdling: Boolean = false,
43 | block: VolatileContext.() -> Observable
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava2DslPlugin)
46 | return add(RxJava2Observable(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/orbit-2-viewmodel/src/test/koltin/com/babylon/orbit2/viewmodel/AndroidIdlingResourceRobolectricTest.kt:
--------------------------------------------------------------------------------
1 | package com.babylon.orbit2.viewmodel
2 |
3 | import androidx.test.espresso.Espresso
4 | import androidx.test.espresso.idling.CountingIdlingResource
5 | import com.babylon.orbit2.Container
6 | import com.babylon.orbit2.container
7 | import io.kotest.matchers.shouldBe
8 | import kotlinx.coroutines.CoroutineScope
9 | import kotlinx.coroutines.Dispatchers
10 | import kotlinx.coroutines.cancel
11 | import org.junit.After
12 | import org.junit.Test
13 | import org.junit.runner.RunWith
14 | import org.robolectric.RobolectricTestRunner
15 | import org.robolectric.annotation.Config
16 |
17 | @RunWith(RobolectricTestRunner::class)
18 | @Config(manifest = Config.NONE, sdk = [28])
19 | class AndroidIdlingResourceRobolectricTest {
20 |
21 | private val scope = CoroutineScope(Dispatchers.Unconfined)
22 |
23 | @After
24 | fun after() {
25 | scope.cancel()
26 | }
27 |
28 | @Test
29 | fun `idling resources have unique names`() {
30 | scope.container(
31 | initialState = TestState(0),
32 | settings = Container.Settings(idlingRegistry = AndroidIdlingResource())
33 | )
34 |
35 | scope.container(
36 | initialState = TestState(0),
37 | settings = Container.Settings(idlingRegistry = AndroidIdlingResource())
38 | )
39 |
40 | forceIdlingResourceSync()
41 |
42 | @Suppress("DEPRECATION")
43 | Espresso.getIdlingResources().size.shouldBe(2)
44 | }
45 |
46 | /**
47 | * Force IdlingRegistry to be synced into Espresso.baseRegistry
48 | */
49 | private fun forceIdlingResourceSync() {
50 | CountingIdlingResource("bob").apply {
51 | @Suppress("DEPRECATION")
52 | Espresso.registerIdlingResources(this)
53 | @Suppress("DEPRECATION")
54 | Espresso.unregisterIdlingResources(this)
55 | }
56 | }
57 |
58 | data class TestState(val value: Int)
59 | }
60 |
--------------------------------------------------------------------------------
/orbit-2-rxjava3/src/main/kotlin/com/babylon/orbit2/rxjava3/RxJava3Observable.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.rxjava3
18 |
19 | import com.babylon.orbit2.syntax.strict.Builder
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
23 | import com.babylon.orbit2.syntax.strict.VolatileContext
24 | import io.reactivex.rxjava3.core.Observable
25 |
26 | internal class RxJava3Observable(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> Observable
29 | ) : Operator
30 |
31 | /**
32 | * The observable transformer flat maps incoming [VolatileContext] for every event into an [Observable] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: false
38 | * @param block the lambda returning a new observable of events given the current state and event
39 | */
40 | @Orbit2Dsl
41 | public fun Builder.transformRx3Observable(
42 | registerIdling: Boolean = false,
43 | block: VolatileContext.() -> Observable
44 | ): Builder {
45 | OrbitDslPlugins.register(RxJava3DslPlugin)
46 | return add(RxJava3Observable(registerIdling, block))
47 | }
48 |
--------------------------------------------------------------------------------
/samples/orbit-2-stocklist/src/main/kotlin/com/babylon/orbit2/sample/stocklist/StockListApplication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.stocklist
18 |
19 | import android.app.Application
20 | import androidx.lifecycle.SavedStateHandle
21 | import com.babylon.orbit2.sample.stocklist.detail.business.DetailViewModel
22 | import com.babylon.orbit2.sample.stocklist.list.business.ListViewModel
23 | import com.babylon.orbit2.sample.stocklist.streaming.StreamingClient
24 | import com.babylon.orbit2.sample.stocklist.streaming.stock.StockRepository
25 | import org.koin.android.ext.koin.androidContext
26 | import org.koin.androidx.viewmodel.dsl.viewModel
27 | import org.koin.core.context.startKoin
28 | import org.koin.dsl.module
29 |
30 | @Suppress("unused")
31 | class StockListApplication : Application() {
32 |
33 | override fun onCreate() {
34 | super.onCreate()
35 |
36 | startKoin {
37 | androidContext(this@StockListApplication)
38 | modules(listOf(mainModule))
39 | }
40 | }
41 |
42 | private val mainModule = module {
43 | single { StreamingClient() }
44 | single { StockRepository(get()) }
45 |
46 | viewModel { (savedStateHandle: SavedStateHandle) -> ListViewModel(savedStateHandle, get()) }
47 | viewModel { (savedStateHandle: SavedStateHandle, itemName: String) -> DetailViewModel(savedStateHandle, itemName, get()) }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/orbit-2-livedata/src/main/kotlin/com/babylon/orbit2/livedata/LiveDataDslPlugin.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.livedata
18 |
19 | import androidx.lifecycle.asFlow
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugin
22 | import com.babylon.orbit2.syntax.strict.VolatileContext
23 | import com.babylon.orbit2.idling.withIdlingFlow
24 | import kotlinx.coroutines.flow.Flow
25 | import kotlinx.coroutines.flow.flatMapConcat
26 | import kotlinx.coroutines.flow.flowOn
27 |
28 | /**
29 | * Orbit plugin providing LiveData DSL operators:
30 | *
31 | * * [transformLiveData]
32 | */
33 | object LiveDataDslPlugin : OrbitDslPlugin {
34 |
35 | @Suppress("UNCHECKED_CAST", "EXPERIMENTAL_API_USAGE")
36 | override fun apply(
37 | containerContext: OrbitDslPlugin.ContainerContext,
38 | flow: Flow,
39 | operator: Operator,
40 | createContext: (event: E) -> VolatileContext
41 | ): Flow {
42 | return when (operator) {
43 | is LiveDataOperator<*, *, *> -> flow.flatMapConcat {
44 | containerContext.withIdlingFlow(operator as LiveDataOperator) {
45 | createContext(it).block().asFlow().flowOn(containerContext.settings.backgroundDispatcher)
46 | }
47 | }
48 | else -> flow
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/orbit-2-core/src/main/kotlin/com/babylon/orbit2/syntax/strict/Builder.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.syntax.strict
18 |
19 | import com.babylon.orbit2.syntax.Operator
20 | import com.babylon.orbit2.syntax.Orbit2Dsl
21 | import kotlinx.coroutines.flow.Flow
22 | import kotlinx.coroutines.flow.flowOf
23 |
24 | @Orbit2Dsl
25 | public class Builder(private val stack: List> = emptyList()) {
26 |
27 | public fun add(operator: Operator): Builder {
28 | return Builder(stack + operator)
29 | }
30 |
31 | @Suppress("UNCHECKED_CAST")
32 | internal fun build(
33 | pluginContext: OrbitDslPlugin.ContainerContext
34 | ): Flow {
35 | return stack.fold(flowOf(Unit)) { flow: Flow, operator: Operator ->
36 | OrbitDslPlugins.plugins.fold(flow) { flow2: Flow, plugin: OrbitDslPlugin ->
37 | plugin.apply(
38 | pluginContext,
39 | flow2,
40 | operator as Operator
41 | ) {
42 | object : VolatileContext {
43 | override val state = volatileState()
44 | override val event = it
45 | override fun volatileState() = pluginContext.state
46 | }
47 | }
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/orbit-2-livedata/src/main/kotlin/com/babylon/orbit2/livedata/LiveDataOperator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.livedata
18 |
19 | import androidx.lifecycle.LiveData
20 | import com.babylon.orbit2.syntax.Operator
21 | import com.babylon.orbit2.syntax.Orbit2Dsl
22 | import com.babylon.orbit2.syntax.strict.Builder
23 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugins
24 | import com.babylon.orbit2.syntax.strict.VolatileContext
25 |
26 | internal class LiveDataOperator(
27 | override val registerIdling: Boolean,
28 | val block: VolatileContext.() -> LiveData
29 | ) : Operator
30 |
31 | /**
32 | * The transformer flat maps incoming [VolatileContext] for every event into a [LiveData] of
33 | * another type.
34 | *
35 | * The transformer executes on an `IO` dispatcher by default.
36 | *
37 | * @param registerIdling When true tracks the block's idling state, default: false
38 | * @param block the lambda returning a new observable of events given the current state and event
39 | */
40 | @Orbit2Dsl
41 | fun Builder.transformLiveData(
42 | registerIdling: Boolean = false,
43 | block: VolatileContext.() -> LiveData
44 | ): Builder {
45 | OrbitDslPlugins.register(LiveDataDslPlugin)
46 | return add(
47 | LiveDataOperator(
48 | registerIdling,
49 | block
50 | )
51 | )
52 | }
53 |
--------------------------------------------------------------------------------
/orbit-2-test/src/main/kotlin/com/babylon/orbit2/TestContainer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2
18 |
19 | import com.babylon.orbit2.internal.RealContainer
20 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugin
21 | import kotlinx.atomicfu.atomic
22 | import kotlinx.coroutines.CoroutineScope
23 | import kotlinx.coroutines.Dispatchers
24 | import kotlinx.coroutines.runBlocking
25 |
26 | internal class TestContainer(
27 | initialState: STATE,
28 | private val isolateFlow: Boolean,
29 | private val blocking: Boolean
30 | ) : RealContainer(
31 | initialState = initialState,
32 | parentScope = CoroutineScope(Dispatchers.Unconfined),
33 | settings = Container.Settings(
34 | orbitDispatcher =
35 | @Suppress("EXPERIMENTAL_API_USAGE") if (blocking) Dispatchers.Unconfined else Dispatchers.Default,
36 | backgroundDispatcher = Dispatchers.Unconfined
37 | )
38 | ) {
39 | private val dispatched = atomic(0)
40 |
41 | override fun orbit(orbitFlow: suspend OrbitDslPlugin.ContainerContext.() -> Unit) {
42 | if (!isolateFlow || dispatched.compareAndSet(0, 1)) {
43 | if (blocking) {
44 | runBlocking {
45 | orbitFlow(pluginContext)
46 | }
47 | } else {
48 | super.orbit(orbitFlow)
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/orbit-2-core/src/main/kotlin/com/babylon/orbit2/CoroutineScopeExtensions.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2
18 |
19 | import com.babylon.orbit2.Container.Settings
20 | import com.babylon.orbit2.internal.LazyCreateContainerDecorator
21 | import com.babylon.orbit2.internal.RealContainer
22 | import kotlinx.coroutines.CoroutineScope
23 |
24 | /**
25 | * Helps create a concrete container in a standard way.
26 | *
27 | * @param initialState The initial state of the container.
28 | * @param settings The [Settings] to set the container up with.
29 | * @param onCreate The lambda to execute when the container is created. By default it is
30 | * executed in a lazy manner when the container is first interacted with in any way.
31 | * @return A [Container] implementation
32 | */
33 | public fun CoroutineScope.container(
34 | initialState: STATE,
35 | settings: Settings = Settings(),
36 | onCreate: ((state: STATE) -> Unit)? = null
37 | ): Container =
38 | if (onCreate == null) {
39 | RealContainer(
40 | initialState = initialState,
41 | settings = settings,
42 | parentScope = this
43 | )
44 | } else {
45 | LazyCreateContainerDecorator(
46 | RealContainer(
47 | initialState = initialState,
48 | settings = settings,
49 | parentScope = this
50 | ),
51 | onCreate
52 | )
53 | }
54 |
--------------------------------------------------------------------------------
/orbit-2-core/src/main/kotlin/com/babylon/orbit2/internal/LazyCreateContainerDecorator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.internal
18 |
19 | import com.babylon.orbit2.Container
20 | import com.babylon.orbit2.ContainerDecorator
21 | import com.babylon.orbit2.syntax.strict.OrbitDslPlugin
22 | import kotlinx.atomicfu.atomic
23 | import kotlinx.coroutines.flow.Flow
24 | import kotlinx.coroutines.flow.emitAll
25 | import kotlinx.coroutines.flow.flow
26 |
27 | public class LazyCreateContainerDecorator(
28 | override val actual: Container,
29 | public val onCreate: (state: STATE) -> Unit
30 | ) : ContainerDecorator {
31 | private val created = atomic(0)
32 |
33 | override val currentState: STATE
34 | get() = actual.currentState
35 |
36 | override val stateFlow: Flow
37 | get() = flow {
38 | runOnCreate()
39 | emitAll(actual.stateFlow)
40 | }
41 |
42 | override val sideEffectFlow: Flow
43 | get() = flow {
44 | runOnCreate()
45 | emitAll(actual.sideEffectFlow)
46 | }
47 |
48 | private fun runOnCreate() {
49 | if (created.compareAndSet(0, 1)) {
50 | onCreate(actual.currentState)
51 | }
52 | }
53 |
54 | override fun orbit(orbitFlow: suspend OrbitDslPlugin.ContainerContext.() -> Unit) {
55 | runOnCreate().also { actual.orbit(orbitFlow) }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/samples/orbit-2-posts/src/main/kotlin/com/babylon/orbit2/sample/posts/app/features/postlist/viewmodel/PostListViewModel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.posts.app.features.postlist.viewmodel
18 |
19 | import androidx.lifecycle.SavedStateHandle
20 | import androidx.lifecycle.ViewModel
21 | import com.babylon.orbit2.ContainerHost
22 | import com.babylon.orbit2.sample.posts.app.common.NavigationEvent
23 | import com.babylon.orbit2.sample.posts.domain.repositories.PostOverview
24 | import com.babylon.orbit2.sample.posts.domain.repositories.PostRepository
25 | import com.babylon.orbit2.syntax.simple.intent
26 | import com.babylon.orbit2.syntax.simple.postSideEffect
27 | import com.babylon.orbit2.syntax.simple.reduce
28 | import com.babylon.orbit2.viewmodel.container
29 |
30 | class PostListViewModel(
31 | savedStateHandle: SavedStateHandle,
32 | private val postRepository: PostRepository
33 | ) : ViewModel(), ContainerHost {
34 |
35 | override val container = container(PostListState(), savedStateHandle) {
36 | if (it.overviews.isEmpty()) {
37 | loadOverviews()
38 | }
39 | }
40 |
41 | private fun loadOverviews() = intent {
42 | val overviews = postRepository.getOverviews()
43 |
44 | reduce {
45 | state.copy(overviews = overviews)
46 | }
47 | }
48 |
49 | fun onPostClicked(post: PostOverview) = intent {
50 | postSideEffect(OpenPostNavigationEvent(post))
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/samples/orbit-2-calculator/src/test/kotlin/com/babylon/orbit2/sample/calculator/livedata/TestLiveDataObserver.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Babylon Partners Limited
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.babylon.orbit2.sample.calculator.livedata
18 |
19 | import androidx.lifecycle.LifecycleOwner
20 | import androidx.lifecycle.LiveData
21 | import androidx.lifecycle.Observer
22 |
23 | fun LiveData.test(lifecycleOwner: LifecycleOwner) =
24 | TestLiveDataObserver(lifecycleOwner, this)
25 |
26 | class TestLiveDataObserver(lifecycleOwner: LifecycleOwner, private val liveData: LiveData) {
27 | private val _values = mutableListOf()
28 | private val observer = Observer {
29 | _values.add(it)
30 | }
31 | val values: List