Skip to content

Commit 47b60cc

Browse files
author
Adrián García
authored
Add support for TypedTasks (#8)
* Add TypedTask<T> * Fix onIdle to be an extension function of TypedTask * Update README
1 parent 7f873c2 commit 47b60cc

File tree

2 files changed

+33
-12
lines changed

2 files changed

+33
-12
lines changed

README.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,17 @@ Each ``Store`` exposes a custom `StoreCallback` though the method `observe` or a
8080
If you make use of the RxJava methods, you can make use of the `SubscriptionTracker` interface to keep track of the `Disposables` used on your activities and fragments.
8181

8282
### Tasks
83-
A Task is a basic object to represent an ongoing process. They should be used in the state of our `Store` to represent ongoing processes that must be represented in the UI.
83+
A `Task` is a basic object to represent an ongoing process. They should be used in the state of our `Store` to represent ongoing processes that must be represented in the UI.
8484

85+
You can also use `TypedTask` to save metadata related the current task.
86+
87+
**IMPORTANT: Do not use TypedTask to hold values that must survive multiple task executions. Save them as a variable in the state instead.**
88+
89+
90+
### Example
8591
Given the example Stores and Actions explained before, the workflow will be:
8692

87-
- View dispatch `LoginAction`.
93+
- View dispatches `LoginAction`.
8894
- Store changes his `LoginTask` status to running and call though his SessionController which will do all the async work to log in the given user.
8995
- View shows an Spinner when `LoginTask` is in running state.
9096
- The async call ends and `LoginCompleteAction` is dispatched on UI, sending a null `User` and an error state `Task` if the async work failed or a success `Task` and an `User`.
@@ -201,7 +207,7 @@ dependencies {
201207
You'll need to add the following snippet to your `Application`'s `onCreate` method. If you don't have it, then create it and reference it in your `AndroidManifest.xml` file:
202208

203209
```kotlin
204-
val stores = listOf<Store<*>>(...) // Here you'll set-up you store list, you can retrieve it using your preferred DI framework
210+
val stores = listOf<Store<*>>() // Here you'll set-up you store list, you can retrieve it using your preferred DI framework
205211
val dispatcher = MiniGen.newDispatcher() // Create a new dispatcher
206212

207213
// Initialize Mini
@@ -211,9 +217,9 @@ stores.forEach { store ->
211217
}
212218

213219
// Optional: add logging interceptor to log action events
214-
dispatcher.addInterceptor(LoggerInterceptor(stores, { tag, msg ->
220+
dispatcher.addInterceptor(LoggerInterceptor(stores)) { tag, msg ->
215221
Log.d(tag, msg)
216-
}))
222+
}
217223
```
218224

219225
## License

mini-common/src/main/java/mini/Resource.kt

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,19 @@ open class Resource<out T> @PublishedApi internal constructor(val value: Any?) {
7272
}
7373

7474
/**
75-
* An empty resource that just abstracts asynchronous operation but with idle
75+
* A resource that abstracts asynchronous operation but with idle
7676
* state instead of empty.
77+
*
78+
* It accepts temporary metadata objects as value.
7779
*/
78-
class Task(value: Any?) : Resource<Unit>(value) {
80+
open class TypedTask<T> @PublishedApi internal constructor(value: Any?) : Resource<T>(value) {
7981
val isIdle: Boolean get() = isEmpty
8082

8183
companion object {
82-
fun success(): Task = Task(Unit)
83-
fun idle(): Task = Task(Empty)
84-
fun loading(): Task = Task(Loading<Unit>())
85-
fun failure(exception: Throwable? = null): Task = Task(Failure(exception))
84+
fun <T> success(value: T): TypedTask<T> = TypedTask(value)
85+
fun <T> idle(): TypedTask<T> = TypedTask(Empty)
86+
fun <T> loading(value: T? = null): TypedTask<T> = TypedTask(Loading(value))
87+
fun <T> failure(exception: Throwable? = null): TypedTask<T> = TypedTask(Failure(exception))
8688
}
8789

8890
override fun toString(): String {
@@ -94,6 +96,19 @@ class Task(value: Any?) : Resource<Unit>(value) {
9496
}
9597
}
9698

99+
/**
100+
* An empty resource that just abstracts asynchronous operation but with idle
101+
* state instead of empty.
102+
*/
103+
class Task(value: Any?) : TypedTask<Unit>(value) {
104+
companion object {
105+
fun success(): Task = Task(Unit)
106+
fun idle(): Task = Task(Empty)
107+
fun loading(): Task = Task(Loading<Unit>())
108+
fun failure(exception: Throwable? = null): Task = Task(Failure(exception))
109+
}
110+
}
111+
97112
inline fun <T> Resource<T>.onSuccess(crossinline action: (data: T) -> Unit): Resource<T> {
98113
if (isSuccess) action(value as T)
99114
return this
@@ -109,7 +124,7 @@ inline fun <T> Resource<T>.onLoading(crossinline action: (data: T?) -> Unit): Re
109124
return this
110125
}
111126

112-
inline fun Task.onIdle(crossinline action: () -> Unit): Task {
127+
inline fun <T> TypedTask<T>.onIdle(crossinline action: () -> Unit): TypedTask<T> {
113128
if (isEmpty) action()
114129
return this
115130
}

0 commit comments

Comments
 (0)