1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.compose.runtime 18 19 internal interface ValueHolder<T> { readValuenull20 fun readValue(map: PersistentCompositionLocalMap): T 21 22 fun toProvided(local: CompositionLocal<T>): ProvidedValue<T> 23 } 24 25 /** A StaticValueHolder holds a value that will never change. */ 26 internal data class StaticValueHolder<T>(val value: T) : ValueHolder<T> { 27 override fun readValue(map: PersistentCompositionLocalMap): T = value 28 29 override fun toProvided(local: CompositionLocal<T>): ProvidedValue<T> = 30 ProvidedValue( 31 compositionLocal = local, 32 value = value, 33 explicitNull = value === null, 34 mutationPolicy = null, 35 state = null, 36 compute = null, 37 isDynamic = false 38 ) 39 } 40 41 /** 42 * A lazy value holder is static value holder for which the value is produced by the valueProducer 43 * parameter which is called once and the result is remembered for the life of LazyValueHolder. 44 */ 45 internal class LazyValueHolder<T>(valueProducer: () -> T) : ValueHolder<T> { 46 private val current by lazy(valueProducer) 47 readValuenull48 override fun readValue(map: PersistentCompositionLocalMap): T = current 49 50 override fun toProvided(local: CompositionLocal<T>): ProvidedValue<T> = 51 composeRuntimeError("Cannot produce a provider from a lazy value holder") 52 } 53 54 internal data class ComputedValueHolder<T>(val compute: CompositionLocalAccessorScope.() -> T) : 55 ValueHolder<T> { 56 override fun readValue(map: PersistentCompositionLocalMap): T = map.compute() 57 58 override fun toProvided(local: CompositionLocal<T>): ProvidedValue<T> = 59 ProvidedValue( 60 compositionLocal = local, 61 value = null, 62 explicitNull = false, 63 mutationPolicy = null, 64 state = null, 65 compute = compute, 66 isDynamic = false 67 ) 68 } 69 70 internal data class DynamicValueHolder<T>(val state: MutableState<T>) : ValueHolder<T> { readValuenull71 override fun readValue(map: PersistentCompositionLocalMap): T = state.value 72 73 override fun toProvided(local: CompositionLocal<T>): ProvidedValue<T> = 74 ProvidedValue( 75 compositionLocal = local, 76 value = null, 77 explicitNull = false, 78 mutationPolicy = null, 79 state = state, 80 compute = null, 81 isDynamic = true 82 ) 83 } 84