1

This is in Kotlin, but I think anyone who writes Java will be able to understand.

I'm trying to make a stopwatch with Rx and I'm having a little trouble with doing the actual stopping and starting. The big problem is that I don't know how to keep the current time, while modifying it as different actions (starting and stopping) come in. Here's what I've got right now.

fullTime.switchMap { startTime ->
    controlCommands.switchMap { command ->
        when (command) {
            ControlState.PLAY -> Observable.interval(1L, TimeUnit.SECONDS).map {
                ControlState.PLAY
            }
            ControlState.PAUSE -> Observable.just(ControlState.PAUSE)
            else -> Observable.just(ControlState.STOP)
        }
    }
}

Where fullTime and controlCommands are Observables that emit events about the current starting time to count down from and say what to do next, respectively. I want to chain off of controlCommands and be able to keep state starting at startTime that will count down when a PLAY event appears, pause when PAUSE appears, and reset at startTime when STOP appears.

scan almost works, but I don't know how to stop after the timer hits 0 and PLAY is still being sent every second, since it would be sending duplicate info. Also it doesn't allow a separation between the state and the observed value. So the value I accumulate with scan has to be the same type as the value inside the Observable (if that makes sense).

Any ideas what I should do?

mrobinson7627
  • 298
  • 1
  • 4
  • 13

1 Answers1

0

If I understand you correctly, you are on the right track with scan. You just need

  • a .takeUntil(state -> state.hasCompleted) to stop when you need to stop (ow maybe a takeWhile, it depends).
  • then a .map(state -> state.getValute()) to get the value

Does this make sense?

Tassos Bassoukos
  • 16,017
  • 2
  • 36
  • 40
  • Will that cause the subscription to complete, or will it continue if a new command / time comes in? – mrobinson7627 May 31 '17 at 11:40
  • `.takeUntil` will cause the subscription to terminate - it will unsubcribe from the parent when the condition is met. – Tassos Bassoukos May 31 '17 at 12:45
  • So this isn't really what I want then, since I want to continue observing `fullTime` and `controlCommands`. – mrobinson7627 May 31 '17 at 13:37
  • Hmmm - ok, can you produce a marble diagram that shows your usecase? I don't think I understand your requirements. – Tassos Bassoukos May 31 '17 at 16:02
  • I want `fullTime` and `controlCommands` to always be emitting things, as they come from the UI. Really what I'm asking is how can I pause the `interval` with knowledge from downstream (the `scan`). When the scan result hits zero, I want to stop ticking on the `interval` and just use the zero. My attempt right now is to just use `distinctUntilChanged` which I think will work for this case. – mrobinson7627 May 31 '17 at 17:48