Material Motion Exploring solutions that will empower creators with the tools needed to describe and implement rich, interactive motion on any platform. Edit this page · History
MotionObservable valve
Status Interface level Implementation level Library
Stable as of February 21, 2016 L2: Interaction creator L3: Stream creator material-motion
platformsrctests
iOS (Swift) View View
valve
upstream (T)
stream (MotionObservable)
(T) downstream

valve specification

This is the engineering specification for the MotionObservable operator: valve.

Overview

valve subscribes and emits values from upstream so long as the provided stream’s last emitted value was true.

MVP

Expose a valve operator API

Use MotionObservable to implement the operator. Accept a MotionObservable of type Bool.

class MotionObservable<T> {
  public func valve(openWhenTrue valveStream: MotionObservable<Bool>) -> MotionObservable<T>

Create a nullable upstream subscription

class MotionObservable<T> {
  func valve(openWhenTrue valveStream: MotionObservable<Bool>) -> MotionObservable<T>
    return MotionObservable<T> { observer in
      var upstreamSubscription: Subscription?
      
      ...
    }

Permanently subscribe to the valve stream

Toggle the upstream subscription based on the emitted value of the valve stream. Subscribe upstream when true is received. Unsubscribe from the upstream when false is received.

class MotionObservable<T> {
  func valve(openWhenTrue valveStream: MotionObservable<Bool>) -> MotionObservable<T>
    return MotionObservable<T> { observer in
      ...

      let valveSubscription = stream.subscribe { value in
        let shouldOpen = value

        if shouldOpen && upstreamSubscription == nil {
          upstreamSubscription = self.subscribe(observer: observer)
        }

        if !shouldOpen && upstreamSubscription != nil {
          upstreamSubscription?.unsubscribe()
          upstreamSubscription = nil
        }
      }
      
    }

Unsubscribe from all streams on disconnect

class MotionObservable<T> {
  func valve(openWhenTrue valveStream: MotionObservable<Bool>) -> MotionObservable<T>
    return MotionObservable<T> { observer in
      ...

      return {
        valveSubscription.unsubscribe()
        upstreamSubscription?.unsubscribe()
        upstreamSubscription = nil
      }
    }