Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passing side-effects to rendering layer. #203

Open
Laimiux opened this issue May 14, 2021 · 2 comments
Open

Passing side-effects to rendering layer. #203

Laimiux opened this issue May 14, 2021 · 2 comments
Labels
enhancement New feature or request

Comments

@Laimiux
Copy link
Collaborator

Laimiux commented May 14, 2021

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.

@Laimiux Laimiux added the enhancement New feature or request label May 14, 2021
@jhowens89
Copy link
Contributor

jhowens89 commented Aug 3, 2021

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.

@Laimiux
Copy link
Collaborator Author

Laimiux commented Aug 3, 2021

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants