• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright (C) 2024 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 com.android.systemui.kairos.internal
18 
19 import com.android.systemui.kairos.internal.util.logDuration
20 import java.util.concurrent.atomic.AtomicBoolean
21 
22 internal class InputNode<A>(
23     private val activate: EvalScope.() -> Unit = {},
<lambda>null24     private val deactivate: () -> Unit = {},
25 ) : PushNode<A> {
26 
27     private val downstreamSet = DownstreamSet()
28     val activated = AtomicBoolean(false)
29 
30     private val transactionCache = TransactionCache<A>()
31     private val epoch
32         get() = transactionCache.epoch
33 
34     override val depthTracker: DepthTracker = DepthTracker()
35 
hasCurrentValuenull36     override fun hasCurrentValue(logIndent: Int, evalScope: EvalScope): Boolean =
37         epoch == evalScope.epoch
38 
39     fun visit(evalScope: EvalScope, value: A) {
40         transactionCache.put(evalScope, value)
41         if (!scheduleAll(0, downstreamSet, evalScope)) {
42             evalScope.scheduleDeactivation(this@InputNode)
43         }
44     }
45 
removeDownstreamnull46     override fun removeDownstream(downstream: Schedulable) {
47         downstreamSet.remove(downstream)
48     }
49 
deactivateIfNeedednull50     override fun deactivateIfNeeded() {
51         if (downstreamSet.isEmpty() && activated.getAndSet(false)) {
52             deactivate()
53         }
54     }
55 
scheduleDeactivationIfNeedednull56     override fun scheduleDeactivationIfNeeded(evalScope: EvalScope) {
57         if (downstreamSet.isEmpty()) {
58             evalScope.scheduleDeactivation(this)
59         }
60     }
61 
addDownstreamnull62     override fun addDownstream(downstream: Schedulable) {
63         downstreamSet.add(downstream)
64     }
65 
addDownstreamAndActivateIfNeedednull66     fun addDownstreamAndActivateIfNeeded(downstream: Schedulable, evalScope: EvalScope) {
67         val needsActivation = run {
68             val wasEmpty = downstreamSet.isEmpty()
69             downstreamSet.add(downstream)
70             wasEmpty && !activated.getAndSet(true)
71         }
72         if (needsActivation) {
73             activate(evalScope)
74         }
75     }
76 
removeDownstreamAndDeactivateIfNeedednull77     override fun removeDownstreamAndDeactivateIfNeeded(downstream: Schedulable) {
78         downstreamSet.remove(downstream)
79         val needsDeactivation = downstreamSet.isEmpty() && activated.getAndSet(false)
80         if (needsDeactivation) {
81             deactivate()
82         }
83     }
84 
getPushEventnull85     override fun getPushEvent(logIndent: Int, evalScope: EvalScope): A =
86         logDuration(logIndent, "Input.getPushEvent", false) {
87             transactionCache.getCurrentValue(evalScope)
88         }
89 }
90 
downstreamnull91 internal fun <A> InputNode<A>.activated() = EventsImplCheap { downstream ->
92     val input = this@activated
93     addDownstreamAndActivateIfNeeded(downstream, evalScope = this)
94     ActivationResult(
95         connection = NodeConnection(input, input),
96         needsEval = input.hasCurrentValue(0, evalScope = this),
97     )
98 }
99 
100 internal data object AlwaysNode : PushNode<Unit> {
101 
102     override val depthTracker = DepthTracker()
103 
hasCurrentValuenull104     override fun hasCurrentValue(logIndent: Int, evalScope: EvalScope): Boolean = true
105 
106     override fun removeDownstream(downstream: Schedulable) {}
107 
deactivateIfNeedednull108     override fun deactivateIfNeeded() {}
109 
scheduleDeactivationIfNeedednull110     override fun scheduleDeactivationIfNeeded(evalScope: EvalScope) {}
111 
addDownstreamnull112     override fun addDownstream(downstream: Schedulable) {}
113 
removeDownstreamAndDeactivateIfNeedednull114     override fun removeDownstreamAndDeactivateIfNeeded(downstream: Schedulable) {}
115 
getPushEventnull116     override fun getPushEvent(logIndent: Int, evalScope: EvalScope) =
117         logDuration(logIndent, "Always.getPushEvent", false) { Unit }
118 }
119