Dalek

General

Category
Free
Tag
FSM
License
MIT License
Min SDK
16 (Android 4.1 Jelly Bean)
Registered
Apr 1, 2020
Favorites
0
Link
https://github.com/adrielcafe/Dalek
See also
TinyMachine
KStateMachine
Kaskade
HAL
EasyFlow

Additional

Language
Kotlin
Version
1.1.0 (Aug 9, 2021)
Created
Jan 24, 2020
Updated
Aug 9, 2021 (Retired)
Owner
Adriel Café (adrielcafe)
Contributor
Adriel Café (adrielcafe)
1
Activity
Badge
Generate
Download
Source code

Dalek

Dalek is a tiny (~10 LOC) finite state machine that helps you manage the UI state of your app when running async/breakable tasks.

It's powered by Coroutines Flow and works on Android & JVM.

Why Dalek?

Daleks are a fictional extraterrestrial race of mutants portrayed in Doctor Who.

They are creatures that live inside a tank-like robotic shell, and this is basically how this library works: your code (the "creature") is wrapped and executed inside a state machine (the "robotic shell").

"EXTERMINATE! EXTERMINATE! EXTERMINATE!"
(Any Dalek will say that)

Motivation

Let's imagine the following scenario: you need to retrieve a Post object from a REST API, something like:

class PostRepository {

    suspend fun getPost(id: String): Post {
        // async api call
        // serialization
        // error handling
    }
}

It's an asynchronous operation that can take a while to complete and can fail (TimeoutException, IOException, SerializationException...). But wait, there's more: you need to keep the UI updated so your user knows what's going on.

This is a nightmare, right? Calm down! Dalek is here to help ????

Usage

1. Wrap your code inside Dalek

To start using Dalek, you just need to wrap your existing code inside it.

Dalek will run your code inside a suspend fun and return a Flow<DalekEvent<T>>, where T is the output of your code (you can return null, Unit and Any, I won't judge you).

class MyViewModel(private val repository: PostRepository) : ViewModel() {

    fun getPost(id: String): Flow<DalekEvent<Post>> =
        Dalek(Dispatchers.IO) {
            repository.getPost(id)
        }
}

2. Handle the UI events

Dalek will emit the following events:

  • Start: always emitted
  • Success(value: T): only emitted when your code is successfully executed
  • Failure(exception: Throwable): only emitted when an exception is thrown
  • Finish: always emitted
class MyActivity : AppCompatActivity() {

    private fun loadPost(id: String) {
        viewModel.getPost(id)
            .collectIn(lifecycleScope) { event ->
                when (event) {
                    is Start -> setLoading(true)
                    is Success -> showPost(event.value)
                    is Failure -> showError(event.exception)
                    is Finish -> setLoading(false)
                }
            }
    }
}

Import to your project

  1. Add the JitPack repository in your root build.gradle at the end of repositories:
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
  1. Next, add the library to your module:
dependencies {
    implementation "com.github.adrielcafe:dalek:$currentVersion"
}

Current version: