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 @file:Suppress("NOTHING_TO_INLINE")
18 
19 package androidx.compose.ui.unit
20 
21 import androidx.compose.runtime.Immutable
22 import androidx.compose.runtime.Stable
23 import androidx.compose.ui.util.packFloats
24 import androidx.compose.ui.util.unpackFloat1
25 import androidx.compose.ui.util.unpackFloat2
26 
27 /**
28  * Constructs an Velocity from the given relative x and y velocities.
29  *
30  * @param x Horizontal component of the velocity in pixels per second
31  * @param y Vertical component of the velocity in pixels per second
32  */
Velocitynull33 @Stable fun Velocity(x: Float, y: Float) = Velocity(packFloats(x, y))
34 
35 /** A two dimensional velocity in pixels per second. */
36 @Immutable
37 @kotlin.jvm.JvmInline
38 value class Velocity internal constructor(private val packedValue: Long) {
39     /** The horizontal component of the velocity in pixels per second. */
40     @Stable
41     val x: Float
42         get() = unpackFloat1(packedValue)
43 
44     /** The vertical component of the velocity in pixels per second. */
45     @Stable
46     val y: Float
47         get() = unpackFloat2(packedValue)
48 
49     /** The horizontal component of the velocity in pixels per second. */
50     @Stable inline operator fun component1(): Float = x
51 
52     /** The vertical component of the velocity in pixels per second. */
53     @Stable inline operator fun component2(): Float = y
54 
55     /** Returns a copy of this [Velocity] instance optionally overriding the x or y parameter */
56     fun copy(x: Float = unpackFloat1(packedValue), y: Float = unpackFloat2(packedValue)) =
57         Velocity(packFloats(x, y))
58 
59     companion object {
60         /**
61          * An offset with zero magnitude.
62          *
63          * This can be used to represent the origin of a coordinate space.
64          */
65         @Stable val Zero = Velocity(0x0L)
66     }
67 
68     /**
69      * Unary negation operator.
70      *
71      * Returns a [Velocity] with the coordinates negated.
72      *
73      * If the [Velocity] represents an arrow on a plane, this operator returns the same arrow but
74      * pointing in the reverse direction.
75      */
76     @Stable operator fun unaryMinus(): Velocity = Velocity(packedValue xor DualFloatSignBit)
77 
78     /**
79      * Binary subtraction operator.
80      *
81      * Returns a [Velocity] whose [x] value is the left-hand-side operand's [x] minus the
82      * right-hand-side operand's [x] and whose [y] value is the left-hand-side operand's [y] minus
83      * the right-hand-side operand's [y].
84      */
85     @Stable
86     operator fun minus(other: Velocity): Velocity =
87         Velocity(
88             packFloats(
89                 unpackFloat1(packedValue) - unpackFloat1(other.packedValue),
90                 unpackFloat2(packedValue) - unpackFloat2(other.packedValue)
91             )
92         )
93 
94     /**
95      * Binary addition operator.
96      *
97      * Returns a [Velocity] whose [x] value is the sum of the [x] values of the two operands, and
98      * whose [y] value is the sum of the [y] values of the two operands.
99      */
100     @Stable
101     operator fun plus(other: Velocity): Velocity =
102         Velocity(
103             packFloats(
104                 unpackFloat1(packedValue) + unpackFloat1(other.packedValue),
105                 unpackFloat2(packedValue) + unpackFloat2(other.packedValue)
106             )
107         )
108 
109     /**
110      * Multiplication operator.
111      *
112      * Returns a [Velocity] whose coordinates are those of the left-hand-side operand (a [Velocity])
113      * multiplied by the scalar right-hand-side operand (a [Float]).
114      */
115     @Stable
116     operator fun times(operand: Float): Velocity =
117         Velocity(
118             packFloats(unpackFloat1(packedValue) * operand, unpackFloat2(packedValue) * operand)
119         )
120 
121     /**
122      * Division operator.
123      *
124      * Returns a [Velocity] whose coordinates are those of the left-hand-side operand (an
125      * [Velocity]) divided by the scalar right-hand-side operand (a [Float]).
126      */
127     @Stable
128     operator fun div(operand: Float): Velocity =
129         Velocity(
130             packFloats(unpackFloat1(packedValue) / operand, unpackFloat2(packedValue) / operand)
131         )
132 
133     /**
134      * Modulo (remainder) operator.
135      *
136      * Returns a [Velocity] whose coordinates are the remainder of dividing the coordinates of the
137      * left-hand-side operand (a [Velocity]) by the scalar right-hand-side operand (a [Float]).
138      */
139     @Stable
140     operator fun rem(operand: Float) =
141         Velocity(
142             packFloats(unpackFloat1(packedValue) % operand, unpackFloat2(packedValue) % operand)
143         )
144 
145     override fun toString() = "($x, $y) px/sec"
146 }
147