@@ -2,7 +2,7 @@ package org.reduxkotlin
22
33import kotlin.jvm.JvmField
44
5- private typealias EqualityCheckFn = (a: Any , b: Any ) -> Boolean
5+ private typealias EqualityCheckFn = (a: Any , b: Any ) -> Boolean
66
77/* *
88 * A rewrite for kotlin of https://github.com/reactjs/reselect library for redux (https://github.com/reactjs/redux)
@@ -27,18 +27,18 @@ interface Memoizer<T> {
2727fun <T > computationMemoizer (computeFn : (Array <out Any >) -> T ) = object : Memoizer <T > {
2828 var lastArgs: Array <out Any >? = null
2929 var lastResult: T ? = null
30- override fun memoize (state : Any ,vararg inputs : SelectorInput <Any , Any >): T {
31- val nInputs= inputs.size
32- val args= Array <Any >(nInputs) { inputs[it].invoke(state) }
33- if (lastArgs!= null && lastArgs!! .size== inputs.size) {
34- var bMatchedArgs= true
35- for (i in 0 until nInputs) {
36- if (! inputs[i].equalityCheck(args[i],lastArgs!! [i])) {
37- bMatchedArgs= false
30+ override fun memoize (state : Any , vararg inputs : SelectorInput <Any , Any >): T {
31+ val nInputs = inputs.size
32+ val args = Array <Any >(nInputs) { inputs[it].invoke(state) }
33+ if (lastArgs != null && lastArgs!! .size == inputs.size) {
34+ var bMatchedArgs = true
35+ for (i in 0 until nInputs) {
36+ if (! inputs[i].equalityCheck(args[i], lastArgs!! [i])) {
37+ bMatchedArgs = false
3838 break
3939 }
4040 }
41- if (bMatchedArgs) {
41+ if (bMatchedArgs) {
4242 return lastResult!!
4343 }
4444 }
@@ -48,19 +48,18 @@ fun <T> computationMemoizer(computeFn: (Array<out Any>) -> T) = object : Memoize
4848 }
4949}
5050
51-
52-
5351/* *
5452 * specialization for the case of single input (a little bit faster)
5553 */
56- fun <T > singleInputMemoizer (func : (Array <out Any >) -> T )= object : Memoizer <T > {
57- var lastArg: Any? = null
58- var lastResult: T ? = null
54+ fun <T > singleInputMemoizer (func : (Array <out Any >) -> T ) = object : Memoizer <T > {
55+ var lastArg: Any? = null
56+ var lastResult: T ? = null
5957 override fun memoize (state : Any , vararg inputs : SelectorInput <Any , Any >): T {
60- val input= inputs[0 ]
61- val arg= input.invoke(state)
58+ val input = inputs[0 ]
59+ val arg = input.invoke(state)
6260 if (lastArg != null &&
63- input.equalityCheck(arg,lastArg!! )){
61+ input.equalityCheck(arg, lastArg!! )
62+ ) {
6463 return lastResult!!
6564 }
6665 lastArg = arg
@@ -69,7 +68,6 @@ fun <T> singleInputMemoizer(func: (Array<out Any>) -> T)=object: Memoizer<T> {
6968 }
7069}
7170
72-
7371interface SelectorInput <S , I > {
7472 operator fun invoke (state : S ): I
7573 val equalityCheck: EqualityCheckFn
@@ -78,11 +76,10 @@ interface SelectorInput<S, I> {
7876/* *
7977 * a selector function is a function that map a field in state object to the input for the selector compute function
8078 */
81- class InputField <S , I >(val fn : S .() -> I ,override val equalityCheck : EqualityCheckFn ) : SelectorInput<S, I> {
79+ class InputField <S , I >(val fn : S .() -> I , override val equalityCheck : EqualityCheckFn ) : SelectorInput<S, I> {
8280 override operator fun invoke (state : S ): I = state.fn()
8381}
8482
85-
8683/* *
8784 * note: [Selector] inherit from [SelectorInput] because of support for composite selectors
8885 */
@@ -107,7 +104,6 @@ interface Selector<S, O> : SelectorInput<S, O> {
107104 fun onChangeIn (state : S , blockfn : (O ) -> Unit ) {
108105 getIfChangedIn(state)?.let (blockfn)
109106 }
110-
111107}
112108
113109/* *
@@ -130,37 +126,34 @@ abstract class AbstractSelector<S, O> : Selector<S, O> {
130126 recomputationsLastChanged = _recomputations
131127 }
132128
133-
134129 protected abstract val computeAndCount: (i: Array <out Any >) -> O
135130 /* *
136131 * 'lazy' because computeandcount is abstract. Cannot reference to it before it is initialized in concrete selectors
137132 * 'open' because we can provide a custom memoizer if needed
138133 */
139134 open val memoizer by lazy { computationMemoizer(computeAndCount) }
140-
141135}
142136
143-
144137/* *
145138 * wrapper class for Selector factory methods , that basically is used only to capture
146139 * type information for the state parameter
147140 */
148- class SelectorBuilder <S : Any > {
141+ class SelectorBuilder <S : Any > {
149142 /* *
150143 * special single input selector that should be used when you just want to retrieve a single field:
151144 * Warning: Don't use this with primitive type fields, use [withSingleFieldByValue] instead!!!
152145 */
153146 fun <I : Any > withSingleField (fn : S .() -> I ) = object : AbstractSelector <S , I >() {
154147 @Suppress(" UNCHECKED_CAST" )
155- private val inputField= InputField (fn, byRefEqualityCheck) as SelectorInput <Any , Any >
148+ private val inputField = InputField (fn, byRefEqualityCheck) as SelectorInput <Any , Any >
156149 override val computeAndCount = fun (i : Array <out Any >): I {
157150 ++ _recomputations
158151 @Suppress(" UNCHECKED_CAST" )
159152 return i[0 ] as I
160153 }
161154
162155 override operator fun invoke (state : S ): I {
163- return memoizer.memoize(state,inputField)
156+ return memoizer.memoize(state, inputField)
164157 }
165158 override val equalityCheck: EqualityCheckFn
166159 get() = byRefEqualityCheck
@@ -174,14 +167,14 @@ class SelectorBuilder<S:Any> {
174167 */
175168 fun <I : Any > withSingleFieldByValue (fn : S .() -> I ) = object : AbstractSelector <S , I >() {
176169 @Suppress(" UNCHECKED_CAST" )
177- private val inputField= InputField (fn, byValEqualityCheck) as SelectorInput <Any , Any >
170+ private val inputField = InputField (fn, byValEqualityCheck) as SelectorInput <Any , Any >
178171 override val computeAndCount = fun (i : Array <out Any >): I {
179172 ++ _recomputations
180173 @Suppress(" UNCHECKED_CAST" )
181174 return i[0 ] as I
182175 }
183176 override operator fun invoke (state : S ): I {
184- return memoizer.memoize(state,inputField)
177+ return memoizer.memoize(state, inputField)
185178 }
186179 override val equalityCheck: EqualityCheckFn
187180 get() = byValEqualityCheck
@@ -209,7 +202,7 @@ class SelectorBuilder<S:Any> {
209202 * }
210203 * }
211204 */
212- fun <State : Any >Store<State>.selectors (selectorSubscriberBuilderInit : SelectorSubscriberBuilder <State >.() -> Unit ): StoreSubscriber {
205+ fun <State : Any > Store<State>.selectors (selectorSubscriberBuilderInit : SelectorSubscriberBuilder <State >.() -> Unit ): StoreSubscriber {
213206 val subscriberBuilder: SelectorSubscriberBuilder <State > = SelectorSubscriberBuilder (this )
214207 subscriberBuilder.selectorSubscriberBuilderInit()
215208 val sub = {
@@ -220,13 +213,15 @@ fun <State: Any>Store<State>.selectors(selectorSubscriberBuilderInit: SelectorSu
220213 subscriberBuilder.withAnyChangeFun?.invoke()
221214 Unit
222215 }
223- // call subscriber immediately when subscribing
216+ // call subscriber immediately when subscribing
224217 sub()
225218 return this .subscribe(sub)
226219}
227220
228- fun <State : Any >Store<State>.select (selector : (State ) -> Any , action : (Any ) -> Unit ): StoreSubscriber {
229- return subscribe(this .selectors {
230- select(selector, action)
231- })
221+ fun <State : Any > Store<State>.select (selector : (State ) -> Any , action : (Any ) -> Unit ): StoreSubscriber {
222+ return subscribe(
223+ this .selectors {
224+ select(selector, action)
225+ }
226+ )
232227}
0 commit comments