tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 82f2a69289213c15124bd60ea079c38fecd8e173
parent d8cfecf2945ff88835e3a52fe535865b4c9fc903
Author: pollymce <pmceldowney@mozilla.com>
Date:   Mon, 22 Dec 2025 13:53:48 +0000

Bug 2005444 - remove ReducerChainBuilder. r=android-reviewers,mcarare

Inline the reducer chain into Store and remove this wrapper class.
It's a bit easier to see what Store.dispatch() is actually doing now.
Also inlining removeSubscription for readability, as it's a one line method that is called once.

Differential Revision: https://phabricator.services.mozilla.com/D277157

Diffstat:
Mmobile/android/android-components/components/lib/state/src/main/java/mozilla/components/lib/state/Store.kt | 45+++++++++++++++++++++------------------------
Dmobile/android/android-components/components/lib/state/src/main/java/mozilla/components/lib/state/internal/ReducerChainBuilder.kt | 48------------------------------------------------
2 files changed, 21 insertions(+), 72 deletions(-)

diff --git a/mobile/android/android-components/components/lib/state/src/main/java/mozilla/components/lib/state/Store.kt b/mobile/android/android-components/components/lib/state/src/main/java/mozilla/components/lib/state/Store.kt @@ -6,7 +6,6 @@ package mozilla.components.lib.state import androidx.annotation.CheckResult import androidx.annotation.VisibleForTesting -import mozilla.components.lib.state.internal.ReducerChainBuilder import java.lang.ref.WeakReference import java.util.Collections import java.util.concurrent.ConcurrentHashMap @@ -23,10 +22,10 @@ import java.util.concurrent.ConcurrentHashMap */ open class Store<S : State, A : Action>( initialState: S, - reducer: Reducer<S, A>, - middleware: List<Middleware<S, A>> = emptyList(), + private val reducer: Reducer<S, A>, + private val middleware: List<Middleware<S, A>> = emptyList(), ) { - private val reducerChainBuilder = ReducerChainBuilder(reducer, middleware) + private var reducerChain: ((A) -> Unit)? = null @VisibleForTesting internal val subscriptions = Collections.newSetFromMap(ConcurrentHashMap<Subscription<S, A>, Boolean>()) @@ -70,26 +69,24 @@ open class Store<S : State, A : Action>( * * @return Unit. Previously this returned a new Job that was launched here, but this no longer happens. */ - fun dispatch(action: A) = - synchronized(this@Store) { - reducerChainBuilder.get(this@Store).invoke(action) - } - - /** - * Transitions from the current [State] to the passed in [state] and notifies all observers. - */ - internal fun transitionTo(state: S) { - if (state == currentState) { - // Nothing has changed. - return + fun dispatch(action: A) { + synchronized(this) { + if (reducerChain == null) { + var chain: (A) -> Unit = { action -> + val newState = reducer(state, action) + if (newState != currentState) { + currentState = newState + subscriptions.forEach { subscription -> subscription.dispatch(newState) } + } + } + middleware.reversed().forEach { middleware -> + val next = chain + chain = { action -> middleware(this, next, action) } + } + reducerChain = chain + } + reducerChain?.invoke(action) } - - currentState = state - subscriptions.forEach { subscription -> subscription.dispatch(state) } - } - - private fun removeSubscription(subscription: Subscription<S, A>) { - subscriptions.remove(subscription) } /** @@ -146,7 +143,7 @@ open class Store<S : State, A : Action>( fun unsubscribe() { active = false - storeReference.get()?.removeSubscription(this) + storeReference.get()?.subscriptions?.remove(this) storeReference.clear() binding?.unbind() diff --git a/mobile/android/android-components/components/lib/state/src/main/java/mozilla/components/lib/state/internal/ReducerChainBuilder.kt b/mobile/android/android-components/components/lib/state/src/main/java/mozilla/components/lib/state/internal/ReducerChainBuilder.kt @@ -1,48 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -package mozilla.components.lib.state.internal - -import mozilla.components.lib.state.Action -import mozilla.components.lib.state.Middleware -import mozilla.components.lib.state.Reducer -import mozilla.components.lib.state.State -import mozilla.components.lib.state.Store - -/** - * Builder to lazily create a function that will invoke the chain of [middleware] and finally the - * [reducer]. - */ -internal class ReducerChainBuilder<S : State, A : Action>( - private val reducer: Reducer<S, A>, - private val middleware: List<Middleware<S, A>>, -) { - private var chain: ((A) -> Unit)? = null - - /** - * Returns a function that will invoke the chain of [middleware] and the [reducer] for the given - * [Store]. - */ - fun get(store: Store<S, A>): (A) -> Unit { - chain?.let { return it } - - return build(store).also { - chain = it - } - } - - private fun build(store: Store<S, A>): (A) -> Unit { - var chain: (A) -> Unit = { action -> - val state = reducer(store.state, action) - store.transitionTo(state) - } - - middleware.reversed().forEach { middleware -> - val next = chain - chain = { action -> middleware(store, next, action) } - } - - return chain - } -}