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 import androidx.collection.ScatterSet
20 import androidx.compose.runtime.internal.persistentCompositionLocalHashMapOf
21 import androidx.compose.runtime.tooling.CompositionData
22 import kotlin.coroutines.CoroutineContext
23 
24 private val EmptyPersistentCompositionLocalMap: PersistentCompositionLocalMap =
25     persistentCompositionLocalHashMapOf()
26 
27 /**
28  * A [CompositionContext] is an opaque type that is used to logically "link" two compositions
29  * together. The [CompositionContext] instance represents a reference to the "parent" composition in
30  * a specific position of that composition's tree, and the instance can then be given to a new
31  * "child" composition. This reference ensures that invalidations and [CompositionLocal]s flow
32  * logically through the two compositions as if they were not separate.
33  *
34  * The "parent" of a root composition is a [Recomposer].
35  *
36  * @see rememberCompositionContext
37  */
38 @OptIn(InternalComposeApi::class, ExperimentalComposeRuntimeApi::class)
39 abstract class CompositionContext internal constructor() {
40     internal abstract val compositeKeyHashCode: CompositeKeyHashCode
41     internal abstract val collectingParameterInformation: Boolean
42     internal abstract val collectingSourceInformation: Boolean
43     internal abstract val collectingCallByInformation: Boolean
44     internal open val observerHolder: CompositionObserverHolder?
45         get() = null
46 
47     /** The [CoroutineContext] with which effects for the composition will be executed in. */
48     abstract val effectCoroutineContext: CoroutineContext
49     internal abstract val recomposeCoroutineContext: CoroutineContext
50 
51     /** Associated composition if one exists. */
52     internal abstract val composition: Composition?
53 
54     internal abstract fun composeInitial(
55         composition: ControlledComposition,
56         content: @Composable () -> Unit
57     )
58 
59     internal abstract fun composeInitialPaused(
60         composition: ControlledComposition,
61         shouldPause: ShouldPauseCallback,
62         content: @Composable () -> Unit
63     ): ScatterSet<RecomposeScopeImpl>
64 
recomposePausednull65     internal abstract fun recomposePaused(
66         composition: ControlledComposition,
67         shouldPause: ShouldPauseCallback,
68         invalidScopes: ScatterSet<RecomposeScopeImpl>
69     ): ScatterSet<RecomposeScopeImpl>
70 
71     internal abstract fun reportPausedScope(scope: RecomposeScopeImpl)
72 
73     internal abstract fun invalidate(composition: ControlledComposition)
74 
75     internal abstract fun invalidateScope(scope: RecomposeScopeImpl)
76 
77     internal open fun recordInspectionTable(table: MutableSet<CompositionData>) {}
78 
registerComposernull79     internal open fun registerComposer(composer: Composer) {}
80 
unregisterComposernull81     internal open fun unregisterComposer(composer: Composer) {}
82 
registerCompositionnull83     internal abstract fun registerComposition(composition: ControlledComposition)
84 
85     internal abstract fun unregisterComposition(composition: ControlledComposition)
86 
87     internal open fun getCompositionLocalScope(): PersistentCompositionLocalMap =
88         EmptyPersistentCompositionLocalMap
89 
90     internal open fun startComposing() {}
91 
doneComposingnull92     internal open fun doneComposing() {}
93 
insertMovableContentnull94     internal abstract fun insertMovableContent(reference: MovableContentStateReference)
95 
96     internal abstract fun deletedMovableContent(reference: MovableContentStateReference)
97 
98     internal abstract fun movableContentStateReleased(
99         reference: MovableContentStateReference,
100         data: MovableContentState,
101         applier: Applier<*>
102     )
103 
104     internal open fun movableContentStateResolve(
105         reference: MovableContentStateReference
106     ): MovableContentState? = null
107 
108     internal abstract fun reportRemovedComposition(composition: ControlledComposition)
109 }
110