Skip to content

Commit 418c555

Browse files
committed
Update Time implementation
1 parent 8cf2f76 commit 418c555

File tree

2 files changed

+218
-11
lines changed

2 files changed

+218
-11
lines changed

Sources/OpenSwiftUICore/Data/Time.swift

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,90 +9,174 @@
99
public import QuartzCore
1010
#endif
1111

12+
/// A type that represents a time value in seconds.
13+
///
14+
/// Use `Time` to represent durations or time intervals within the OpenSwiftUI framework.
15+
/// The structure provides various operators and methods for time-related calculations.
16+
///
17+
/// Example:
18+
///
19+
/// let duration = Time(seconds: 2.5)
20+
/// let delay = Time.systemUptime + 1.0
21+
///
1222
@_spi(ForOpenSwiftUIOnly)
1323
public struct Time: Equatable, Hashable, Comparable {
24+
/// The time value in seconds.
1425
public var seconds: Double
26+
27+
/// Creates a time value from the specified number of seconds.
28+
/// - Parameter seconds: The number of seconds.
1529
public init(seconds: Double) {
1630
self.seconds = seconds
1731
}
32+
33+
/// Creates a time value initialized to zero seconds.
1834
public init() {
1935
self.seconds = .zero
2036
}
37+
38+
/// A time value of zero seconds.
2139
public static let zero: Time = Time(seconds: .zero)
22-
public static let infinity: Time = Time(seconds: .infinity)
2340

24-
#if canImport(QuartzCore)
41+
/// A time value representing infinity.
42+
public static let infinity: Time = Time(seconds: .infinity)
43+
44+
/// The current system uptime as a `Time` value.
45+
///
46+
/// This property provides the time since system boot using platform-specific
47+
/// implementation.
2548
@inlinable
2649
public static var systemUptime: Time {
50+
// NOTE: ProcessInfo.systemUptime is a general API available on all platforms via Foundation.
51+
// The implementation result of ProcessInfo().systemUptime and CACurrentMediaTime() is the same on Darwin platforms.
52+
// Both of them is using `mach_absolute_time` under the hood for Darwin platforms.
53+
// On non-Darwin platforms, `CACurrentMediaTime` is not available. But `ProcessInfo.systemUptime` is available.
54+
#if canImport(QuartzCore)
2755
Time(seconds: CACurrentMediaTime())
56+
#else
57+
Time(seconds: ProcessInfo().systemUptime)
58+
#endif
2859
}
29-
#endif
3060

61+
/// Returns the negation of the specified time value.
62+
/// - Parameter lhs: A time value.
63+
/// - Returns: A time value that is the negation of the input.
3164
@inlinable
32-
prefix public static func - (lhs: Time) -> Time {
65+
public static prefix func - (lhs: Time) -> Time {
3366
Time(seconds: -lhs.seconds)
3467
}
35-
68+
69+
/// Adds a time value and a number of seconds.
70+
/// - Parameters:
71+
/// - lhs: A time value.
72+
/// - rhs: The number of seconds to add.
73+
/// - Returns: A new time value representing the sum.
3674
@inlinable
3775
public static func + (lhs: Time, rhs: Double) -> Time {
3876
Time(seconds: lhs.seconds + rhs)
3977
}
4078

79+
/// Adds a number of seconds to a time value.
80+
/// - Parameters:
81+
/// - lhs: The number of seconds to add.
82+
/// - rhs: A time value.
83+
/// - Returns: A new time value representing the sum.
4184
@inlinable
4285
public static func + (lhs: Double, rhs: Time) -> Time {
4386
rhs + lhs
4487
}
4588

89+
/// Subtracts a number of seconds from a time value.
90+
/// - Parameters:
91+
/// - lhs: A time value.
92+
/// - rhs: The number of seconds to subtract.
93+
/// - Returns: A new time value representing the difference.
4694
@inlinable
4795
public static func - (lhs: Time, rhs: Double) -> Time {
4896
Time(seconds: lhs.seconds - rhs)
4997
}
5098

99+
/// Calculates the time difference between two time values.
100+
/// - Parameters:
101+
/// - lhs: The first time value.
102+
/// - rhs: The second time value.
103+
/// - Returns: The difference in seconds between the two time values.
51104
@inlinable
52105
public static func - (lhs: Time, rhs: Time) -> Double {
53106
lhs.seconds - rhs.seconds
54107
}
55-
108+
109+
/// Multiplies a time value by a scalar.
110+
/// - Parameters:
111+
/// - lhs: A time value.
112+
/// - rhs: The scalar to multiply by.
113+
/// - Returns: A new time value representing the product.
56114
@inlinable
57115
public static func * (lhs: Time, rhs: Double) -> Time {
58116
Time(seconds: lhs.seconds * rhs)
59117
}
60-
118+
119+
/// Divides a time value by a scalar.
120+
/// - Parameters:
121+
/// - lhs: A time value.
122+
/// - rhs: The scalar to divide by.
123+
/// - Returns: A new time value representing the quotient.
61124
@inlinable
62125
public static func / (lhs: Time, rhs: Double) -> Time {
63126
return Time(seconds: lhs.seconds / rhs)
64127
}
65-
128+
129+
/// Adds a number of seconds to a time value, storing the result in the left-hand operand.
130+
/// - Parameters:
131+
/// - lhs: The time value to modify.
132+
/// - rhs: The number of seconds to add.
66133
@inlinable
67134
public static func += (lhs: inout Time, rhs: Double) {
68135
lhs = lhs + rhs
69136
}
70137

138+
/// Subtracts a number of seconds from a time value, storing the result in the left-hand operand.
139+
/// - Parameters:
140+
/// - lhs: The time value to modify.
141+
/// - rhs: The number of seconds to subtract.
71142
@inlinable
72143
public static func -= (lhs: inout Time, rhs: Double) {
73144
lhs = lhs - rhs
74145
}
75146

147+
/// Multiplies a time value by a scalar, storing the result in the left-hand operand.
148+
/// - Parameters:
149+
/// - lhs: The time value to modify.
150+
/// - rhs: The scalar to multiply by.
76151
@inlinable
77152
public static func *= (lhs: inout Time, rhs: Double) {
78153
lhs = lhs * rhs
79154
}
80-
155+
156+
/// Divides a time value by a scalar, storing the result in the left-hand operand.
157+
/// - Parameters:
158+
/// - lhs: The time value to modify.
159+
/// - rhs: The scalar to divide by.
81160
@inlinable
82161
public static func /= (lhs: inout Time, rhs: Double) {
83162
lhs = lhs / rhs
84163
}
85164

165+
/// Returns a Boolean value indicating whether the first time value is less than the second.
166+
/// - Parameters:
167+
/// - lhs: A time value to compare.
168+
/// - rhs: Another time value to compare.
169+
/// - Returns: `true` if the first value is less than the second value; otherwise, `false`.
86170
@inlinable
87171
public static func < (lhs: Time, rhs: Time) -> Bool {
88172
lhs.seconds < rhs.seconds
89173
}
90-
174+
91175
@inlinable
92176
public static func == (a: Time, b: Time) -> Bool {
93177
a.seconds == b.seconds
94178
}
95-
179+
96180
@inlinable
97181
public func hash(into hasher: inout Hasher) {
98182
hasher.combine(seconds)
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
//
2+
// TimeTests.swift
3+
// OpenSwiftUICoreTests
4+
5+
@_spi(ForOpenSwiftUIOnly)
6+
import OpenSwiftUICore
7+
import Testing
8+
import Numerics
9+
10+
struct TimeTests {
11+
@Test
12+
func initialization() {
13+
let time1 = Time(seconds: 10)
14+
#expect(time1.seconds.isApproximatelyEqual(to: 10))
15+
16+
let time2 = Time()
17+
#expect(time2.seconds.isApproximatelyEqual(to: 0))
18+
19+
#expect(Time.zero.seconds.isApproximatelyEqual(to: 0))
20+
#expect(Time.infinity.seconds == Double.infinity)
21+
}
22+
23+
@Test
24+
func systemUptime() {
25+
let uptime = Time.systemUptime
26+
#expect(uptime.seconds > 0)
27+
}
28+
29+
@Test
30+
func negation() {
31+
let time = Time(seconds: 5)
32+
let negated = -time
33+
#expect(negated.seconds.isApproximatelyEqual(to: -5))
34+
}
35+
36+
@Test
37+
func addition() {
38+
let time = Time(seconds: 5)
39+
let result1 = time + 3
40+
#expect(result1.seconds.isApproximatelyEqual(to: 8))
41+
42+
let result2 = 3 + time
43+
#expect(result2.seconds.isApproximatelyEqual(to: 8))
44+
45+
var time2 = Time(seconds: 5)
46+
time2 += 3
47+
#expect(time2.seconds.isApproximatelyEqual(to: 8))
48+
}
49+
50+
@Test
51+
func subtraction() {
52+
let time = Time(seconds: 5)
53+
let result1 = time - 3
54+
#expect(result1.seconds.isApproximatelyEqual(to: 2))
55+
56+
let time2 = Time(seconds: 8)
57+
let diff = time2 - time
58+
#expect(diff.isApproximatelyEqual(to: 3))
59+
60+
var time3 = Time(seconds: 5)
61+
time3 -= 3
62+
#expect(time3.seconds.isApproximatelyEqual(to: 2))
63+
}
64+
65+
@Test
66+
func multiplication() {
67+
let time = Time(seconds: 5)
68+
let result = time * 3
69+
#expect(result.seconds.isApproximatelyEqual(to: 15))
70+
71+
var time2 = Time(seconds: 5)
72+
time2 *= 3
73+
#expect(time2.seconds.isApproximatelyEqual(to: 15))
74+
}
75+
76+
@Test
77+
func division() {
78+
let time = Time(seconds: 15)
79+
let result = time / 3
80+
#expect(result.seconds.isApproximatelyEqual(to: 5))
81+
82+
var time2 = Time(seconds: 15)
83+
time2 /= 3
84+
#expect(time2.seconds.isApproximatelyEqual(to: 5))
85+
}
86+
87+
@Test
88+
func comparison() {
89+
let time1 = Time(seconds: 5)
90+
let time2 = Time(seconds: 10)
91+
let time3 = Time(seconds: 5)
92+
93+
#expect(time1 < time2)
94+
#expect(time1 <= time2)
95+
#expect(time2 > time1)
96+
#expect(time2 >= time1)
97+
#expect(time1 == time3)
98+
#expect(time1 != time2)
99+
}
100+
101+
@Test
102+
func hashable() {
103+
let time1 = Time(seconds: 5)
104+
let time2 = Time(seconds: 5)
105+
let time3 = Time(seconds: 10)
106+
107+
var set = Set<Time>()
108+
set.insert(time1)
109+
set.insert(time2)
110+
set.insert(time3)
111+
112+
#expect(set.count == 2)
113+
}
114+
115+
@Test
116+
func sendable() {
117+
let time = Time(seconds: 5)
118+
Task {
119+
let copiedTime = time
120+
#expect(copiedTime.seconds.isApproximatelyEqual(to: 5))
121+
}
122+
}
123+
}

0 commit comments

Comments
 (0)