formula
formula copied to clipboard
Passing side-effects to rendering layer.
What
Currently, there isn't a well-defined mechanism for passing side-effects to the rendering layer.
Using SingleLiveEvent concept
class SideEffect<Type>(val value: Type) {
private var performed: Boolean = false
inline fun performIfNeeded(crossinline action: () -> Unit) {
if (!performed) {
performed = true
action()
}
}
}
renderModel.scrollToTopSideEffect?.performIfNeeded {
recyclerView.scrollToTop()
}
The limitation is that there cannot be multiple things trying to handle the same side-effect. The side-effect should always be handled by a single RenderModel consumer.
Using Relay concept
Side effect relay type passed through RenderModel
data class MyFeatureRenderModel(
val scrollSideEffects: SideEffect<ScrollPosition>
)
Rendering layer
class MyFeatureRenderView(): RenderView<MyFeatureRenderModel> {
private val recyclerView: RecyclerView = ...
private val scrollEffectHandler = SideEffect.Handler { effect: ScrollPosition ->
recyclerView.scrollTo(effect.position)
}
override fun render = Renderer { model: MyFeatureRenderModel ->
scrollEffectHandler.attach(model.scrollSideEffects)
}
}
Potential issues could be a missed side-effect event due to the subscription lifecycle. An effect could happen before the rendering layer is subscribed and can receive it.
Perhaps you could emulate DispatchWorkSubject (source) and also take in a subscriber count (defaulting to 1) as requirement for emission?
I believe that would fulfill your requirements plus have the ability to queue multiple events while not subscribed.
Edit: I would like to add that DispatchWorkSubject emissions are exclusive to a particular observer. You would need to modify that implementation detail if you wanted a single event to be consumed by more than one observer.
Perhaps you could emulate DispatchWorkSubject (source) and also take in a subscriber count (defaulting to 1) as requirement for emission?
I believe that would fulfill your requirements plus have the ability to queue multiple events while not subscribed.
Edit: I would like to add that DispatchWorkSubject emissions are exclusive to a particular observer. You would need to modify that implementation detail if you wanted a single event to be consumed by more than one observer.
That seems like a good option that is worth exploring. Thanks!