From 32551e8918b22762c067a895382a4faee53b9003 Mon Sep 17 00:00:00 2001 From: Robert Jaros Date: Sun, 13 Oct 2019 00:04:39 +0200 Subject: Refactor StateBinding class with ObservableState interface. --- .../kotlin/pl/treksoft/kvision/redux/ReduxStore.kt | 17 ++-- .../pl/treksoft/kvision/redux/StateBinding.kt | 108 --------------------- 2 files changed, 6 insertions(+), 119 deletions(-) delete mode 100644 kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft/kvision/redux/StateBinding.kt (limited to 'kvision-modules/kvision-redux-kotlin/src/main/kotlin/pl/treksoft') 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 @@ -65,7 +66,7 @@ class ReduxStore( reducer: ReducerFun, initialState: S, vararg middlewares: Middleware -) { +) : ObservableState { @Suppress("UNCHECKED_CAST") private val store: Store = createStore({ s: S, a: Any -> if (a == ActionTypes.INIT || a == ActionTypes.REPLACE) { @@ -75,11 +76,7 @@ class ReduxStore( } }, initialState, applyMiddleware(createThunkMiddleware(), *middlewares)) - /** - * Returns the current state. - */ fun getState(): S { - @Suppress("UNCHECKED_CAST") return store.getState() } @@ -99,12 +96,10 @@ class ReduxStore( 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( - store: ReduxStore, - 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 CONT.stateBinding( - store: ReduxStore, - factory: (CONT.(S) -> Unit) - ): StateBinding { - 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 CONT.stateUpdate( - store: ReduxStore, - factory: (CONT.(S) -> CONTENT) - ): Updateable { - return Updateable(StateBinding(store, this, factory)::setUpdateState) - } - } -} - -/** - * A helper class for updateable redux content. - */ -class Updateable(private val setUpdateState: ((S, CONTENT) -> Unit) -> Unit) { - infix fun updateWith(updateState: (S, CONTENT) -> Unit) { - setUpdateState(updateState) - } -} -- cgit