diff --git a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppModel.kt b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppModel.kt index 37c6ca597..963cb7dc3 100644 --- a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppModel.kt +++ b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppModel.kt @@ -1,18 +1,28 @@ package com.novoda.gol.presentation +import com.novoda.gol.patterns.PatternEntity import kotlin.properties.Delegates.observable class AppModel { - private var isIdle by observable(true) { _, _, newValue -> - onSimulationStateChanged(newValue) + private var boardViewState by observable(BoardViewState(true)) { _, _, newValue -> + onBoardStateChanged(newValue) } var onSimulationStateChanged: (isIdle: Boolean) -> Unit by observable<(Boolean) -> Unit>({}) { _, _, newValue -> - newValue(isIdle) + newValue(boardViewState.isIdle) + } + + var onBoardStateChanged: (BoardViewState) -> Unit by observable<(BoardViewState) -> Unit>({}) { _, _, newValue -> + newValue(boardViewState) } fun toggleSimulation() { - isIdle = isIdle.not() + boardViewState = BoardViewState(isIdle = boardViewState.isIdle.not()) + onSimulationStateChanged(boardViewState.isIdle) + } + + fun selectPattern(pattern: PatternEntity) { + boardViewState = boardViewState.copy(selectedPattern = pattern) } } diff --git a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppPresenter.kt b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppPresenter.kt index 1fbc99549..08f525f7a 100644 --- a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppPresenter.kt +++ b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppPresenter.kt @@ -7,18 +7,15 @@ class AppPresenter { fun bind(view: AppView) { model.onSimulationStateChanged = { isIdle -> - view.controlButtonLabel = if (isIdle) "Start simulation" else "Stop Simulation" - view.patternSelectionVisibility = isIdle - view.board = view.board.copy(isIdle = isIdle) + view.renderControlButtonLabel(if (isIdle) "Start simulation" else "Stop Simulation") + view.renderPatternSelectionVisibility(visibility = isIdle) } - view.onControlButtonClicked = { - model.toggleSimulation() - } + model.onBoardStateChanged = view::renderBoard - view.onPatternSelected = { pattern -> - view.board = view.board.copy(selectedPattern = pattern) - } + view.onControlButtonClicked = model::toggleSimulation + + view.onPatternSelected = model::selectPattern } fun unbind(view: AppView) { diff --git a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppView.kt b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppView.kt index 0f903d660..510570870 100644 --- a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppView.kt +++ b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/AppView.kt @@ -4,11 +4,10 @@ import com.novoda.gol.patterns.PatternEntity interface AppView { - var controlButtonLabel: String - var patternSelectionVisibility: Boolean - var board: BoardViewState - var onControlButtonClicked : () -> Unit var onPatternSelected: (pattern : PatternEntity) -> Unit + fun renderControlButtonLabel(controlButtonLabel: String) + fun renderPatternSelectionVisibility(visibility: Boolean) + fun renderBoard(boardViewState: BoardViewState) } diff --git a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardModelImpl.kt b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardModelImpl.kt index ac09a999c..b8d92b997 100644 --- a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardModelImpl.kt +++ b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardModelImpl.kt @@ -34,7 +34,7 @@ class BoardModelImpl private constructor(initialBoard: BoardEntity, private val } override fun selectPattern(pattern: PatternEntity) { - if (gameLoop.isLooping() || this.pattern == pattern) { + if (gameLoop.isLooping()) { return } this.pattern = pattern diff --git a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardViewState.kt b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardViewState.kt index b11527e7e..b27a98f1e 100644 --- a/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardViewState.kt +++ b/game-of-life-multiplatform/common/src/main/kotlin/com/novoda/gol/presentation/BoardViewState.kt @@ -4,5 +4,5 @@ import com.novoda.gol.patterns.PatternEntity data class BoardViewState( val isIdle: Boolean, - val selectedPattern: PatternEntity? + val selectedPattern: PatternEntity? = null ) diff --git a/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/App.kt b/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/App.kt index d3f29261d..ea4e8727a 100644 --- a/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/App.kt +++ b/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/App.kt @@ -12,31 +12,12 @@ import kotlinx.html.style import react.* import react.dom.div import react.dom.h2 -import kotlin.properties.Delegates.observable class App : RComponent(), AppView { override var onControlButtonClicked: () -> Unit = {} override var onPatternSelected: (pattern: PatternEntity) -> Unit = {} - override var controlButtonLabel by observable("") { _, _, newValue -> - setState { - controlButtonLabel = newValue - } - } - - override var patternSelectionVisibility by observable(true) { _, _, newValue -> - setState { - patternViewState.shouldDisplay = newValue - } - } - - override var board by observable(BoardViewState(true, null)) { _, _, newValue -> - setState { - boardViewState = newValue - } - } - private val presenter: AppPresenter = AppPresenter() override fun componentWillMount() { @@ -51,6 +32,24 @@ class App : RComponent(), AppView { patternViewState = PatternViewState(true, PatternRepository.patterns()) } + override fun renderControlButtonLabel(controlButtonLabel: String) { + setState { + this.controlButtonLabel = controlButtonLabel + } + } + + override fun renderPatternSelectionVisibility(visibility: Boolean) { + setState { + patternViewState.shouldDisplay = visibility + } + } + + override fun renderBoard(boardViewState: BoardViewState) { + setState { + this.boardViewState = boardViewState + } + } + override fun RBuilder.render(): ReactElement? = div { attrs.style = kotlinext.js.js { diff --git a/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/pattern.kt b/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/pattern.kt index fb64cb5e2..97dbbc16b 100644 --- a/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/pattern.kt +++ b/game-of-life-multiplatform/game-of-life-js/src/main/kotlin/com/novoda/gol/components/pattern.kt @@ -43,4 +43,4 @@ fun RBuilder.pattern(patternEntity: PatternEntity, onPatternSelected: () -> Unit } } } -} \ No newline at end of file +}