importre / kotlin-maze

:steam_locomotive: A simple way to implement applications using observable streams

Home Page:https://speakerdeck.com/importre/compose-everything-with-rx-and-kotlin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool


kotlin-maze

Download Build Status

πŸš‚ A simple way to implement applications using observable streams


β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•—     β–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—      β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β•šβ•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘      β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β•šβ•β•β–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β•β•β•β•β•
β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β–ˆβ–ˆβ–ˆβ–ˆβ•”β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘  β–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  
β–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β•šβ•β•β•β•β•β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ–ˆβ•”β•  β–ˆβ–ˆβ•”β•β•β•  
β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘      β–ˆβ–ˆβ•‘ β•šβ•β• β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
β•šβ•β•  β•šβ•β• β•šβ•β•β•β•β•β•    β•šβ•β•   β•šβ•β•β•β•β•β•β•β•šβ•β•β•šβ•β•  β•šβ•β•β•β•      β•šβ•β•     β•šβ•β•β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•
                                                                                        

Usage

Create immutable view model

Recommend create class as comparable like data class

data class HelloModel(
    val name: String = ""
)

Implement MazeListener

class HelloFragment : BaseFragment(), MazeListener<HelloModel> {

    override val layoutId: Int = R.layout.fragment_hello

    // Don't be in lifecycle of `Fragment`/`Activity`
    // In this case, `BaseFragment` is set to `retainInstance = true` basically
    // Set initial view model
    private val maze by lazy { Maze(HelloModel()) }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        // Attach maze with user events
        // Event.id is used to filter in `main` function
        maze.attach(this, arrayOf(
            toolbar.navigationClicks()
                .map { ClickEvent(R.id.homeAsUp) },
            inputName.textChanges()
                .map { TextChangeEvent(R.id.inputName, it) }
        ))
    }

    override fun onDestroyView() {
        // Detach
        maze.detach()
        super.onDestroyView()
    }

    // Implement main function
    override fun main(sources: Sources<HelloModel>) = helloMain(sources)

    // Render view model
    override fun render(prev: HelloModel, curr: HelloModel) {
        val hello = getString(R.string.hello_message)
        textHello.text = hello.format(curr.name)
    }

    // Navigate somethings
    override fun navigate(navigation: Navigation) {
        when (navigation) {
            is Back -> activity?.onBackPressed()
        }
    }

    // Cleanup if Activity is finished
    override fun finish() = maze.finish()

    // Handle errors
    override fun error(t: Throwable) {
        t.printStackTrace()
    }
}

Implement main function

Implement main logic using Observables

fun helloMain(sources: Sources<HelloModel>): Sinks<HelloModel> {

    val model = sources.event
        .textChanges(R.id.inputName)
        .map(CharSequence::toString)
        .withLatestFrom(sources.model,
            BiFunction { name: String, model: HelloModel ->
                model.copy(name = name)
            })
        .cacheWithInitialCapacity(1)

    val navigation = sources.event
        .clicks(R.id.homeAsUp)
        .map { Back() }

    // `model` must be `ObservableCache`
    return Sinks(model, navigation)
}

Customize Navigations, Events

You can extend Navigations and/or Events if you want

Please refer to default Navigations, Events

More examples

videos

Install

repositories {
    jcenter()
}

compile "com.importre:kotlin-maze:$maze_version"

for test

testCompile "com.importre:kotlin-maze-test:$maze_version"

Slides

License

Apache 2.0 Β© Jaewe Heo

About

:steam_locomotive: A simple way to implement applications using observable streams

https://speakerdeck.com/importre/compose-everything-with-rx-and-kotlin

License:Apache License 2.0


Languages

Language:Kotlin 100.0%