Loading mechanics/src/com/android/mechanics/debug/DebugInspector.kt +4 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import androidx.compose.runtime.setValue import com.android.mechanics.MotionValue import com.android.mechanics.impl.DiscontinuityAnimation import com.android.mechanics.spec.InputDirection import com.android.mechanics.spec.MotionSpec import com.android.mechanics.spec.SegmentData import com.android.mechanics.spec.SegmentKey import com.android.mechanics.spec.SemanticKey Loading Loading @@ -88,4 +89,7 @@ internal constructor( val semantics: List<SemanticValue<*>> get() = with(segment) { spec.semantics(key) } val spec: MotionSpec get() = segment.spec } mechanics/src/com/android/mechanics/debug/DebugVisualization.kt +10 −8 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf Loading @@ -46,7 +47,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastCoerceAtLeast import androidx.compose.ui.util.fastCoerceAtMost import androidx.compose.ui.util.fastForEachIndexed import com.android.mechanics.MotionValue import com.android.mechanics.MotionValueState import com.android.mechanics.spec.DirectionalMotionSpec import com.android.mechanics.spec.Guarantee import com.android.mechanics.spec.InputDirection Loading Loading @@ -79,7 +80,7 @@ typealias OutputRangeFn = */ @Composable fun DebugMotionValueVisualization( motionValue: MotionValue, motionValue: MotionValueState, inputRange: ClosedFloatingPointRange<Float>, modifier: Modifier = Modifier, outputRange: OutputRangeFn = DebugMotionValueVisualization.default, Loading @@ -87,8 +88,9 @@ fun DebugMotionValueVisualization( ) { val inspector = remember(motionValue) { motionValue.debugInspector() } val computedOutputRange = remember(motionValue.spec, inputRange) { outputRange(motionValue.spec, inputRange) } val spec = remember(motionValue) { derivedStateOf { inspector.frame.spec } }.value val computedOutputRange = remember(spec, inputRange) { outputRange(spec, inputRange) } DisposableEffect(inspector) { onDispose { inspector.dispose() } } val colorScheme = MaterialTheme.colorScheme Loading @@ -96,7 +98,7 @@ fun DebugMotionValueVisualization( val specColor = colorScheme.tertiary val valueColor = colorScheme.primary val primarySpec = motionValue.spec.get(inspector.frame.gestureDirection) val primarySpec = spec.get(inspector.frame.gestureDirection) val activeSegment = inspector.frame.segmentKey Spacer( Loading Loading @@ -179,7 +181,7 @@ fun Modifier.debugMotionSpecGraph( */ @Composable fun Modifier.debugMotionValueGraph( motionValue: MotionValue, motionValue: MotionValueState, color: Color, inputRange: ClosedFloatingPointRange<Float>, outputRange: ClosedFloatingPointRange<Float>, Loading Loading @@ -241,7 +243,7 @@ fun DirectionalMotionSpec.computeOutputValueRange( } private data class DebugMotionValueGraphElement( val motionValue: MotionValue, val motionValue: MotionValueState, val color: Color, val inputRange: ClosedFloatingPointRange<Float>, val outputRange: ClosedFloatingPointRange<Float>, Loading Loading @@ -269,7 +271,7 @@ private data class DebugMotionValueGraphElement( } private class DebugMotionValueGraphNode( motionValue: MotionValue, motionValue: MotionValueState, var color: Color, var inputRange: ClosedFloatingPointRange<Float>, var outputRange: ClosedFloatingPointRange<Float>, Loading mechanics/src/com/android/mechanics/debug/MotionValueDebugger.kt +9 −9 Original line number Diff line number Diff line Loading @@ -30,25 +30,25 @@ import androidx.compose.ui.node.ObserverModifierNode import androidx.compose.ui.node.currentValueOf import androidx.compose.ui.node.observeReads import androidx.compose.ui.platform.InspectorInfo import com.android.mechanics.MotionValue import com.android.mechanics.MotionValueState import kotlinx.coroutines.DisposableHandle /** Keeps track of MotionValues that are registered for debug-inspection. */ class MotionValueDebugController { private val observedMotionValues = mutableStateListOf<MotionValue>() private val observedMotionValues = mutableStateListOf<MotionValueState>() /** * Registers a [MotionValue] to be debugged. * Registers a [MotionValueState] to be debugged. * * Clients must call [DisposableHandle.dispose] when done. */ fun register(motionValue: MotionValue): DisposableHandle { fun register(motionValue: MotionValueState): DisposableHandle { observedMotionValues.add(motionValue) return DisposableHandle { observedMotionValues.remove(motionValue) } } /** The currently registered `MotionValues`. */ val observed: List<MotionValue> val observed: List<MotionValueState> get() = observedMotionValues } Loading @@ -70,12 +70,12 @@ fun MotionValueDebuggerProvider(enableDebugger: Boolean = true, content: @Compos } /** Registers the [motionValue] with the [LocalMotionValueDebugController], if available. */ fun Modifier.debugMotionValue(motionValue: MotionValue): Modifier = fun Modifier.debugMotionValue(motionValue: MotionValueState): Modifier = this.then(DebugMotionValueElement(motionValue)) /** Registers the [motionValue] with the [LocalMotionValueDebugController], if available. */ @Composable fun DebugEffect(motionValue: MotionValue) { fun DebugEffect(motionValue: MotionValueState) { val debugger = LocalMotionValueDebugController.current if (debugger != null) { DisposableEffect(debugger, motionValue) { Loading @@ -89,7 +89,7 @@ fun DebugEffect(motionValue: MotionValue) { * [DelegatableNode] to register the [motionValue] with the [LocalMotionValueDebugController], if * available. */ class DebugMotionValueNode(motionValue: MotionValue) : class DebugMotionValueNode(motionValue: MotionValueState) : Modifier.Node(), DelegatableNode, CompositionLocalConsumerModifierNode, ObserverModifierNode { private var debugger: MotionValueDebugController? = null Loading Loading @@ -118,7 +118,7 @@ class DebugMotionValueNode(motionValue: MotionValue) : } } private data class DebugMotionValueElement(val motionValue: MotionValue) : private data class DebugMotionValueElement(val motionValue: MotionValueState) : ModifierNodeElement<DebugMotionValueNode>() { override fun create(): DebugMotionValueNode = DebugMotionValueNode(motionValue) Loading Loading
mechanics/src/com/android/mechanics/debug/DebugInspector.kt +4 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import androidx.compose.runtime.setValue import com.android.mechanics.MotionValue import com.android.mechanics.impl.DiscontinuityAnimation import com.android.mechanics.spec.InputDirection import com.android.mechanics.spec.MotionSpec import com.android.mechanics.spec.SegmentData import com.android.mechanics.spec.SegmentKey import com.android.mechanics.spec.SemanticKey Loading Loading @@ -88,4 +89,7 @@ internal constructor( val semantics: List<SemanticValue<*>> get() = with(segment) { spec.semantics(key) } val spec: MotionSpec get() = segment.spec }
mechanics/src/com/android/mechanics/debug/DebugVisualization.kt +10 −8 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf Loading @@ -46,7 +47,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.util.fastCoerceAtLeast import androidx.compose.ui.util.fastCoerceAtMost import androidx.compose.ui.util.fastForEachIndexed import com.android.mechanics.MotionValue import com.android.mechanics.MotionValueState import com.android.mechanics.spec.DirectionalMotionSpec import com.android.mechanics.spec.Guarantee import com.android.mechanics.spec.InputDirection Loading Loading @@ -79,7 +80,7 @@ typealias OutputRangeFn = */ @Composable fun DebugMotionValueVisualization( motionValue: MotionValue, motionValue: MotionValueState, inputRange: ClosedFloatingPointRange<Float>, modifier: Modifier = Modifier, outputRange: OutputRangeFn = DebugMotionValueVisualization.default, Loading @@ -87,8 +88,9 @@ fun DebugMotionValueVisualization( ) { val inspector = remember(motionValue) { motionValue.debugInspector() } val computedOutputRange = remember(motionValue.spec, inputRange) { outputRange(motionValue.spec, inputRange) } val spec = remember(motionValue) { derivedStateOf { inspector.frame.spec } }.value val computedOutputRange = remember(spec, inputRange) { outputRange(spec, inputRange) } DisposableEffect(inspector) { onDispose { inspector.dispose() } } val colorScheme = MaterialTheme.colorScheme Loading @@ -96,7 +98,7 @@ fun DebugMotionValueVisualization( val specColor = colorScheme.tertiary val valueColor = colorScheme.primary val primarySpec = motionValue.spec.get(inspector.frame.gestureDirection) val primarySpec = spec.get(inspector.frame.gestureDirection) val activeSegment = inspector.frame.segmentKey Spacer( Loading Loading @@ -179,7 +181,7 @@ fun Modifier.debugMotionSpecGraph( */ @Composable fun Modifier.debugMotionValueGraph( motionValue: MotionValue, motionValue: MotionValueState, color: Color, inputRange: ClosedFloatingPointRange<Float>, outputRange: ClosedFloatingPointRange<Float>, Loading Loading @@ -241,7 +243,7 @@ fun DirectionalMotionSpec.computeOutputValueRange( } private data class DebugMotionValueGraphElement( val motionValue: MotionValue, val motionValue: MotionValueState, val color: Color, val inputRange: ClosedFloatingPointRange<Float>, val outputRange: ClosedFloatingPointRange<Float>, Loading Loading @@ -269,7 +271,7 @@ private data class DebugMotionValueGraphElement( } private class DebugMotionValueGraphNode( motionValue: MotionValue, motionValue: MotionValueState, var color: Color, var inputRange: ClosedFloatingPointRange<Float>, var outputRange: ClosedFloatingPointRange<Float>, Loading
mechanics/src/com/android/mechanics/debug/MotionValueDebugger.kt +9 −9 Original line number Diff line number Diff line Loading @@ -30,25 +30,25 @@ import androidx.compose.ui.node.ObserverModifierNode import androidx.compose.ui.node.currentValueOf import androidx.compose.ui.node.observeReads import androidx.compose.ui.platform.InspectorInfo import com.android.mechanics.MotionValue import com.android.mechanics.MotionValueState import kotlinx.coroutines.DisposableHandle /** Keeps track of MotionValues that are registered for debug-inspection. */ class MotionValueDebugController { private val observedMotionValues = mutableStateListOf<MotionValue>() private val observedMotionValues = mutableStateListOf<MotionValueState>() /** * Registers a [MotionValue] to be debugged. * Registers a [MotionValueState] to be debugged. * * Clients must call [DisposableHandle.dispose] when done. */ fun register(motionValue: MotionValue): DisposableHandle { fun register(motionValue: MotionValueState): DisposableHandle { observedMotionValues.add(motionValue) return DisposableHandle { observedMotionValues.remove(motionValue) } } /** The currently registered `MotionValues`. */ val observed: List<MotionValue> val observed: List<MotionValueState> get() = observedMotionValues } Loading @@ -70,12 +70,12 @@ fun MotionValueDebuggerProvider(enableDebugger: Boolean = true, content: @Compos } /** Registers the [motionValue] with the [LocalMotionValueDebugController], if available. */ fun Modifier.debugMotionValue(motionValue: MotionValue): Modifier = fun Modifier.debugMotionValue(motionValue: MotionValueState): Modifier = this.then(DebugMotionValueElement(motionValue)) /** Registers the [motionValue] with the [LocalMotionValueDebugController], if available. */ @Composable fun DebugEffect(motionValue: MotionValue) { fun DebugEffect(motionValue: MotionValueState) { val debugger = LocalMotionValueDebugController.current if (debugger != null) { DisposableEffect(debugger, motionValue) { Loading @@ -89,7 +89,7 @@ fun DebugEffect(motionValue: MotionValue) { * [DelegatableNode] to register the [motionValue] with the [LocalMotionValueDebugController], if * available. */ class DebugMotionValueNode(motionValue: MotionValue) : class DebugMotionValueNode(motionValue: MotionValueState) : Modifier.Node(), DelegatableNode, CompositionLocalConsumerModifierNode, ObserverModifierNode { private var debugger: MotionValueDebugController? = null Loading Loading @@ -118,7 +118,7 @@ class DebugMotionValueNode(motionValue: MotionValue) : } } private data class DebugMotionValueElement(val motionValue: MotionValue) : private data class DebugMotionValueElement(val motionValue: MotionValueState) : ModifierNodeElement<DebugMotionValueNode>() { override fun create(): DebugMotionValueNode = DebugMotionValueNode(motionValue) Loading