diff options
author | Robert Jaros <rjaros@finn.pl> | 2019-10-13 00:04:39 +0200 |
---|---|---|
committer | Robert Jaros <rjaros@finn.pl> | 2019-10-13 00:04:39 +0200 |
commit | 32551e8918b22762c067a895382a4faee53b9003 (patch) | |
tree | e0722fdd5a6c01079cfbf22ccba38a3e21a779b9 /kvision-modules | |
parent | 6ea600defefbe16e59c421785d9a09989e672083 (diff) | |
download | kvision-32551e8918b22762c067a895382a4faee53b9003.tar.gz kvision-32551e8918b22762c067a895382a4faee53b9003.tar.bz2 kvision-32551e8918b22762c067a895382a4faee53b9003.zip |
Refactor StateBinding class with ObservableState interface.
Diffstat (limited to 'kvision-modules')
8 files changed, 18 insertions, 243 deletions
diff --git a/kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt b/kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt index 58cf86c6..a37f1ac9 100644 --- a/kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt +++ b/kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt @@ -28,6 +28,7 @@ import org.reduxkotlin.applyMiddleware import org.reduxkotlin.createStore import org.reduxkotlin.createThunk import org.reduxkotlin.createThunkMiddleware +import pl.treksoft.kvision.state.ObservableState interface RAction typealias ReducerFun<S, A> = (S, A) -> S @@ -65,7 +66,7 @@ class ReduxStore<S : Any, A : RAction>( reducer: ReducerFun<S, A>, initialState: S, vararg middlewares: Middleware<S> -) { +) : ObservableState<S> { @Suppress("UNCHECKED_CAST") private val store: Store<S> = createStore({ s: S, a: Any -> if (a == ActionTypes.INIT || a == ActionTypes.REPLACE) { @@ -75,11 +76,7 @@ class ReduxStore<S : Any, A : RAction>( } }, initialState, applyMiddleware(createThunkMiddleware(), *middlewares)) - /** - * Returns the current state. - */ fun getState(): S { - @Suppress("UNCHECKED_CAST") return store.getState() } @@ -99,12 +96,10 @@ class ReduxStore<S : Any, A : RAction>( store.dispatch(thunk) } - /** - * Subscribes a client for the change state notifications. - */ - fun subscribe(listener: (S) -> Unit): () -> Unit { - return store.subscribe { - listener(getState()) + override fun subscribe(observer: (S) -> Unit) { + store.subscribe { + observer(getState()) } + observer(getState()) } } diff --git a/kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/StateBinding.kt b/kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/StateBinding.kt deleted file mode 100644 index a980a79a..00000000 --- a/kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/StateBinding.kt +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2017-present Robert Jaros - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package pl.treksoft.kvision.redux - -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.Widget - -/** - * A class which binds the redux store with the given container. - * - * @constructor Creates StateBinding which binds the redux store with the given container. - * @param S redux state type - * @param A redux action type - * @param CONT container type - * @param store a redux store - * @param container a container - * @param factory a function which re-creates the view based on the given state - */ -class StateBinding<S : Any, A : RAction, CONT : Container, CONTENT>( - store: ReduxStore<S, A>, - private val container: CONT, - private val factory: (CONT.(S) -> CONTENT) -) : Widget(setOf()) { - - init { - update(store.getState()) - store.subscribe { update(it) } - } - - private var updateState: ((S, CONTENT) -> Unit)? = null - private var content: CONTENT? = null - - /** - * Updates view from the current state. - */ - @Suppress("ComplexMethod") - fun update(state: S) { - singleRender { - if (updateState == null || content == null) { - container.removeAll() - container.add(this) - content = container.factory(state) - } else { - content?.let { - updateState?.invoke(state, it) - } - } - } - } - - private fun setUpdateState(updateState: (S, CONTENT) -> Unit) { - this.updateState = updateState - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun <S : Any, A : RAction, CONT : Container> CONT.stateBinding( - store: ReduxStore<S, A>, - factory: (CONT.(S) -> Unit) - ): StateBinding<S, A, CONT, Unit> { - return StateBinding(store, this, factory) - } - - /** - * DSL builder extension function for updateable redux content. - * - * It takes the same parameters as the constructor of the built component. - */ - fun <S : Any, A : RAction, CONT : Container, CONTENT> CONT.stateUpdate( - store: ReduxStore<S, A>, - factory: (CONT.(S) -> CONTENT) - ): Updateable<S, CONTENT> { - return Updateable(StateBinding(store, this, factory)::setUpdateState) - } - } -} - -/** - * A helper class for updateable redux content. - */ -class Updateable<S : Any, CONTENT>(private val setUpdateState: ((S, CONTENT) -> Unit) -> Unit) { - infix fun updateWith(updateState: (S, CONTENT) -> Unit) { - setUpdateState(updateState) - } -} diff --git a/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt b/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt index a518d0ca..56195ca8 100644 --- a/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt +++ b/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt @@ -76,7 +76,7 @@ class ReduxStoreSpec : SimpleSpec { } store.dispatch(TestAction.Inc) store.dispatch(TestAction.Dec) - assertEquals(2, counter) + assertEquals(3, counter) } } } diff --git a/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt b/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt index 61845c6e..dee4daa9 100644 --- a/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt +++ b/kvision-modules/kvision-redux-kotlin/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt @@ -25,8 +25,8 @@ import pl.treksoft.kvision.html.Div.Companion.div import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.panel.SimplePanel import pl.treksoft.kvision.redux.RAction -import pl.treksoft.kvision.redux.StateBinding.Companion.stateBinding -import pl.treksoft.kvision.redux.StateBinding.Companion.stateUpdate +import pl.treksoft.kvision.state.StateBinding.Companion.stateBinding +import pl.treksoft.kvision.state.StateBinding.Companion.stateUpdate import pl.treksoft.kvision.redux.createReduxStore import test.pl.treksoft.kvision.DomSpec import kotlin.browser.document diff --git a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt index 8cb1540d..93c4f6a9 100644 --- a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt +++ b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/ReduxStore.kt @@ -22,6 +22,7 @@ package pl.treksoft.kvision.redux import pl.treksoft.kvision.KVManagerRedux +import pl.treksoft.kvision.state.ObservableState import redux.Reducer import redux.Store import redux.WrapperAction @@ -62,7 +63,7 @@ class ReduxStore<S : Any, A : RAction>( reducer: Reducer<S, A>, initialState: S, vararg middlewares: dynamic -) { +) : ObservableState<S> { private val store: Store<S, dynamic, WrapperAction> init { @@ -83,9 +84,6 @@ class ReduxStore<S : Any, A : RAction>( ) } - /** - * Returns the current state. - */ fun getState(): S { return store.getState() } @@ -114,12 +112,10 @@ class ReduxStore<S : Any, A : RAction>( }) } - /** - * Subscribes a client for the change state notifications. - */ - fun subscribe(listener: (S) -> Unit): () -> Unit { - return store.subscribe { - listener(getState()) + override fun subscribe(observer: (S) -> Unit) { + store.subscribe { + observer(getState()) } + observer(getState()) } } diff --git a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/StateBinding.kt b/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/StateBinding.kt deleted file mode 100644 index a980a79a..00000000 --- a/kvision-modules/kvision-redux/src/main/kotlin/pl/treksoft/kvision/redux/StateBinding.kt +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2017-present Robert Jaros - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package pl.treksoft.kvision.redux - -import pl.treksoft.kvision.core.Container -import pl.treksoft.kvision.core.Widget - -/** - * A class which binds the redux store with the given container. - * - * @constructor Creates StateBinding which binds the redux store with the given container. - * @param S redux state type - * @param A redux action type - * @param CONT container type - * @param store a redux store - * @param container a container - * @param factory a function which re-creates the view based on the given state - */ -class StateBinding<S : Any, A : RAction, CONT : Container, CONTENT>( - store: ReduxStore<S, A>, - private val container: CONT, - private val factory: (CONT.(S) -> CONTENT) -) : Widget(setOf()) { - - init { - update(store.getState()) - store.subscribe { update(it) } - } - - private var updateState: ((S, CONTENT) -> Unit)? = null - private var content: CONTENT? = null - - /** - * Updates view from the current state. - */ - @Suppress("ComplexMethod") - fun update(state: S) { - singleRender { - if (updateState == null || content == null) { - container.removeAll() - container.add(this) - content = container.factory(state) - } else { - content?.let { - updateState?.invoke(state, it) - } - } - } - } - - private fun setUpdateState(updateState: (S, CONTENT) -> Unit) { - this.updateState = updateState - } - - companion object { - /** - * DSL builder extension function. - * - * It takes the same parameters as the constructor of the built component. - */ - fun <S : Any, A : RAction, CONT : Container> CONT.stateBinding( - store: ReduxStore<S, A>, - factory: (CONT.(S) -> Unit) - ): StateBinding<S, A, CONT, Unit> { - return StateBinding(store, this, factory) - } - - /** - * DSL builder extension function for updateable redux content. - * - * It takes the same parameters as the constructor of the built component. - */ - fun <S : Any, A : RAction, CONT : Container, CONTENT> CONT.stateUpdate( - store: ReduxStore<S, A>, - factory: (CONT.(S) -> CONTENT) - ): Updateable<S, CONTENT> { - return Updateable(StateBinding(store, this, factory)::setUpdateState) - } - } -} - -/** - * A helper class for updateable redux content. - */ -class Updateable<S : Any, CONTENT>(private val setUpdateState: ((S, CONTENT) -> Unit) -> Unit) { - infix fun updateWith(updateState: (S, CONTENT) -> Unit) { - setUpdateState(updateState) - } -} diff --git a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt index b45eb9dd..80ff65df 100644 --- a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt +++ b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/ReduxStoreSpec.kt @@ -76,7 +76,7 @@ class ReduxStoreSpec : SimpleSpec { } store.dispatch(TestAction.Inc) store.dispatch(TestAction.Dec) - assertEquals(2, counter) + assertEquals(3, counter) } } } diff --git a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt index ec32d0d6..005a2da3 100644 --- a/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt +++ b/kvision-modules/kvision-redux/src/test/kotlin/test/pl/treksoft/kvision/redux/StateBindingSpec.kt @@ -24,8 +24,8 @@ package test.pl.treksoft.kvision.redux import pl.treksoft.kvision.html.Div.Companion.div import pl.treksoft.kvision.panel.Root import pl.treksoft.kvision.panel.SimplePanel -import pl.treksoft.kvision.redux.StateBinding.Companion.stateBinding -import pl.treksoft.kvision.redux.StateBinding.Companion.stateUpdate +import pl.treksoft.kvision.state.StateBinding.Companion.stateBinding +import pl.treksoft.kvision.state.StateBinding.Companion.stateUpdate import pl.treksoft.kvision.redux.createReduxStore import redux.RAction import test.pl.treksoft.kvision.DomSpec |