Skip to content

Commit

Permalink
Updating readme.
Browse files Browse the repository at this point in the history
  • Loading branch information
Laimiux committed Mar 24, 2022
1 parent 2447967 commit a32add9
Showing 1 changed file with 127 additions and 0 deletions.
127 changes: 127 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,133 @@ deterministic, composable, testable applications.

[Check samples](samples)

## Quick Example
As a quick example, we'll show how a counter application looks which shows
current amount and allows you to increment or decrement it.
```kotlin
class CounterFormula : Formula<Unit, State, Output>() {

data class State(val currentCount: Int)

data class Output(
val countText: String,
val onIncrement: () -> Unit,
val onDecrement: () -> Unit,
)

override fun initialState(input: Unit) = State(currentCount = 0)

override fun Snapshot<Unit, State>.evaluate(): Evaluation<Output> {
val currentCount = state.currentCount
val output = Output(
countText = "Count: $currentCount",
onIncrement = context.callback {
val newState = state.copy(
currentCount = currentCount + 1
)
transition(newState)
},
onDecrement = context.callback {
val newState = state.copy(
currentCount = currentCount - 1
)
transition(newState)
}
)
return Evaluation(output = output)
}
}

// Vanilla Android rendering logic
val currentCountTextView: TextView = ...
val incrementButton: Button = ...
val decrementButton: Button = ...

// We convert Formula instance to RxJava observable.
val counterOutput: Observable<CounterFormula.Output> = CounterFormula().toObservable()
counterOutput.subscribe { output ->
counterTextView.text = output.countText
incrementButton.setOnClickListener { output.onIncrement() }
decrementButton.setOnClickListener { output.onDecrement() }
}
```

## Quick Example - Async code
To display how to handle asynchronous actions, let's update previous counter example where
we persist and read current counter state from disk.
```kotlin
// We use simple in-memory implementation which could be changed to support real disk cache.
class CounterRepository {
private var count: Int = 0

fun saveCurrentCount(count: Int) {
this.count = count
}

fun getCounterState(): Observable<Int> {
return Observable.fromCallable { count }
}
}

class CounterFormula(val repository: CounterRepository) : Formula<Unit, State, Output>() {

// We make currentCount nullable to indicate not-loaded / loaded states.
data class State(val currentCount: Int?)

data class Output(
val countText: String,
val onIncrement: () -> Unit,
val onDecrement: () -> Unit,
)

override fun initialState(input: Unit) = State(currentCount = null)

override fun Snapshot<Unit, State>.evaluate(): Evaluation<Output> {
val currentCount = state.currentCount
val output = if (currentCount == null) {
Output(
countText = "Loading",
onIncrement = {},
onDecrement = {}
)
} else {
Output(
countText = "Count: $currentCount",
onIncrement = context.callback {
val newState = state.copy(
currentCount = currentCount + 1
)
transition(newState) {
repository.saveCurrentCount(newState.currentCount)
}
},
onDecrement = context.callback {
val newState = state.copy(
currentCount = currentCount - 1
)
transition(newState) {
repository.saveCurrentCount(newState.currentCount)
}
}
)
}

return Evaluation(
output = output,
actions = context.actions {
// We add an action which gets the counter state and updates our state.
RxAction.fromObservable { repository.getCounterState() }.onEvent { currentCount ->
val newState = state.copy(currentCount = currentCount)
transition(newState)
}
}
)
}
}


```

## Android Module
The Android module provides declarative API to connect reactive state management to Android Fragments.
This module has been designed for gradual adoption. You can use as much or as little of it as you like.
Expand Down

0 comments on commit a32add9

Please sign in to comment.