Skip to content

Instantly share code, notes, and snippets.

@alifgiant
Last active July 20, 2021 12:57
Show Gist options
  • Save alifgiant/0946a70fb39ae1b730784c4576af54b5 to your computer and use it in GitHub Desktop.
Save alifgiant/0946a70fb39ae1b730784c4576af54b5 to your computer and use it in GitHub Desktop.
MVI example with scheduler
data class State (
   val coffee: CoffeeCup = EmptyCoffeeCup()
)

sealed class Intent(val state: State) {
   class CheckCupContent(state: State) : Intent(state)
   class Refill(state: State) : Intent(state)
}

class Reducer {
   var stateObservable = Observable()
   
   fun refillCoffee(state: State, newCoffee: CoffeeCup) {
      val newStete = state.copyWith { 
         this.coffee = newCoffe
      }
      publish(newStete)
   }
   
   fun publish(state) = stateObservable.publish(newStete)
}

class StateScheduler(val every: Duration, val callback: (State) -> Unit) {
   var state: State? = null
   
   fun update(newState: State) {
      state = newState
   }
   
   fun run() = Scheduler(every = every) {
      state?.let { callback(it) }
   }.run()
}

class Action {
   // our fake view x user
   // fake view, since it listen to state change
   // fake user, since it generate Intent
   val coffeEmptyCheckScheduler = StateScheduler(every = 10_MINUTE) { state ->
      val intent = Intent.CheckCupContent(state)
      handleIntent(intent)
   }
   
   val reducer = Reducer()
   
   val shopper = ShopController()
   val person = PersonController()
   
   fun handleIntent(intent: Intent) {
      when (intent) {
         is CheckCupContent -> {
            if (intent.state.coffee.isEmpty) {
               reducer.refillCoffee(intent.state, refill())            
            }
         }
         is Refill -> {
            reducer.refillCoffee(intent.state, refill())
         }
      }
   }
   
   fun refill(): Coffee {
      val money = person.getMoney(15000)
      val coffee = shopper.makeCoffee(money)
      return coffee
   }
   
   init {
      reducer.stateObservable.observe { coffeEmptyCheckScheduler.update(it) }
      reducer.publish(State())
   }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment