Created
February 1, 2019 20:42
-
-
Save alexsullivan114/67522d9b6f1dc572d18e1780d20c753a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class GameStateMachine( | |
events: Flowable<Event>, | |
gameStateManager: GameStateManager, | |
playHarvester: PlayHarvesterImpl | |
) { | |
private var state: GameStateMachineState = | |
BatterUpState(GameCoordinator(gameStateManager, playHarvester)) | |
val viewStates: Flowable<ViewState> = Flowable.just(state.viewState).concatWith(events | |
.doOnNext { state = state.consumeEvent(it) } | |
.map { state.viewState }) | |
} | |
sealed class ViewState { | |
class BatterUpViewState( | |
val batter: Player, | |
val organizations: Organizations, | |
val playersOnBase: List<PlayerOnBase> | |
) : ViewState() | |
class BatterOptionViewState : ViewState() | |
class BatterOutViewState : ViewState() | |
class BatterOutOptionsViewState : ViewState() | |
class BatterOutFieldViewState(val fielders: List<Position>) : ViewState() | |
class BatterOnOptionsViewState(val options: List<Option>, val selectedBase: Base) : ViewState() | |
class BaseRunnerViewState(val playerOnBase: PlayerOnBase) : ViewState() | |
class BaseRunnerOptionsViewState(val options: List<Option>, val playerOnBase: PlayerOnBase): ViewState() | |
class AdvanceRunnerViewState(val playerOnBase: PlayerOnBase): ViewState() | |
} | |
interface GameStateMachineState { | |
val viewState: ViewState | |
fun consumeEvent(event: Event): GameStateMachineState | |
sealed class Event { | |
class BatterClick : Event() | |
class BaseClick(val base: Base) : Event() | |
class OutClick : Event() | |
class OccupiedBaseClick(val base: Base) : Event() | |
class OptionsSelected(val option: Option) : Event() | |
class OutRecordingBarLeftBtnClick : Event() | |
class OutRecordingBarRightBtnClick : Event() | |
class PositionInserted(val position: Position) : Event() | |
} | |
} | |
// Example of a GameStateMachineState | |
class BaseRunnerState( | |
private val playerOnBase: PlayerOnBase, | |
private val gameCoordinator: GameCoordinator | |
) : GameStateMachineState { | |
override val viewState: ViewState | |
get() = BaseRunnerViewState(playerOnBase) | |
override fun consumeEvent(event: Event): GameStateMachineState { | |
return when(event) { | |
is OutClick -> handleOutClick() | |
is BaseClick -> handleBaseClick(event) | |
else -> throw IllegalStateException("$this cannot handle $event") | |
} | |
} | |
private fun handleOutClick(): GameStateMachineState { | |
gameCoordinator.baseRunnerOut(playerOnBase.player) | |
return BatterUpState(gameCoordinator) | |
} | |
private fun handleBaseClick(baseClick: BaseClick): GameStateMachineState { | |
return BaseRunnerOptionsState(gameCoordinator, PlayerOnBase(playerOnBase.player, baseClick.base)) | |
} | |
} | |
// This function is in a top level presenter. I'm sure there's a better way to do this ugly block. | |
private fun renderViewStateChange(old: ViewState, new: ViewState) { | |
return when { | |
(old is BatterUpViewState && new is BatterOptionViewState) -> old.transitionTo(new) | |
(old is BatterOptionViewState && new is BatterOutViewState) -> old.transitionTo(new) | |
(old is BatterOutViewState && new is BatterUpViewState) -> old.transitionTo(new) | |
(old is BatterOutViewState && new is BatterOutOptionsViewState) -> old.transitionTo(new) | |
(old is BatterOutViewState && new is BatterOutFieldViewState) -> old.transitionTo(new) | |
(old is BatterOutFieldViewState && new is BatterOutFieldViewState) -> old.transitionTo(new) | |
(old is BatterOutFieldViewState && new is BatterOutViewState) -> old.transitionTo(new) | |
(old is BatterOutFieldViewState && new is BatterUpViewState) -> old.transitionTo(new) | |
(old is BatterOutOptionsViewState && new is BatterUpViewState) -> old.transitionTo(new) | |
(old is BatterOptionViewState && new is BatterOnOptionsViewState) -> old.transitionTo(new) | |
(old is BatterOnOptionsViewState && new is BatterOnOptionsViewState) -> old.transitionTo(new) | |
(old is BatterOnOptionsViewState && new is BatterUpViewState) -> old.transitionTo(new) | |
(old is BatterUpViewState && new is BaseRunnerViewState) -> old.transitionTo(new) | |
(old is BaseRunnerViewState && new is BatterUpViewState) -> old.transitionTo(new) | |
(old is BaseRunnerViewState && new is BaseRunnerOptionsViewState) -> old.transitionTo(new) | |
(old is BaseRunnerOptionsViewState && new is BaseRunnerOptionsViewState) -> old.transitionTo( | |
new | |
) | |
(old is BaseRunnerOptionsViewState && new is BatterUpViewState) -> old.transitionTo(new) | |
(old is BatterOnOptionsViewState && new is AdvanceRunnerViewState) -> old.transitionTo(new) | |
(old is BatterOutOptionsViewState && new is AdvanceRunnerViewState) -> old.transitionTo(new) | |
(old is BatterOutViewState && new is AdvanceRunnerViewState) -> old.transitionTo(new) | |
(old is AdvanceRunnerViewState && new is AdvanceRunnerViewState) -> old.transitionTo(new) | |
(old is AdvanceRunnerViewState && new is BatterUpViewState) -> old.transitionTo(new) | |
else -> throw IllegalStateException("Invalid view states: Going from $old to $new") | |
} | |
} | |
// Example of one of the `transitionTo` methods. | |
private fun BatterUpViewState.transitionTo(newState: BatterOptionViewState) { | |
view.hideBatterButton() | |
view.showOutButton(this@GamePresenter) | |
view.showBases(this@GamePresenter, null) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment