83 lines
2.0 KiB
Swift
83 lines
2.0 KiB
Swift
//
|
|
// Stopwatch.swift
|
|
// MultiChrono
|
|
//
|
|
// Created by Beatrice Dellacà on 26/01/26.
|
|
//
|
|
|
|
import Foundation
|
|
import Combine
|
|
|
|
class Stopwatch: ObservableObject, Identifiable {
|
|
let id = UUID()
|
|
@Published var name: String
|
|
@Published var elapsedTime: TimeInterval = 0
|
|
@Published var isRunning: Bool = false
|
|
|
|
private var timer: AnyCancellable?
|
|
private var startTime: Date?
|
|
private var accumulatedTime: TimeInterval = 0
|
|
|
|
init(name: String) {
|
|
self.name = name
|
|
}
|
|
|
|
deinit {
|
|
timer?.cancel()
|
|
}
|
|
|
|
func start() {
|
|
guard !isRunning else { return }
|
|
|
|
startTime = Date()
|
|
isRunning = true
|
|
|
|
timer = Timer.publish(every: 0.1, on: .main, in: .common)
|
|
.autoconnect()
|
|
.sink { [weak self] _ in
|
|
self?.tick()
|
|
}
|
|
}
|
|
|
|
func pause() {
|
|
guard isRunning else { return }
|
|
|
|
timer?.cancel()
|
|
timer = nil
|
|
|
|
if let startTime = startTime {
|
|
accumulatedTime += Date().timeIntervalSince(startTime)
|
|
}
|
|
|
|
isRunning = false
|
|
startTime = nil
|
|
|
|
// Ensure UI shows accurate accumulated time
|
|
elapsedTime = accumulatedTime
|
|
}
|
|
|
|
func reset() {
|
|
pause()
|
|
accumulatedTime = 0
|
|
elapsedTime = 0
|
|
}
|
|
|
|
private func tick() {
|
|
guard let startTime = startTime else { return }
|
|
elapsedTime = accumulatedTime + Date().timeIntervalSince(startTime)
|
|
}
|
|
|
|
var formattedTime: String {
|
|
let hours = Int(elapsedTime) / 3600
|
|
let minutes = Int(elapsedTime) / 60 % 60
|
|
let seconds = Int(elapsedTime) % 60
|
|
let tenths = Int((elapsedTime.truncatingRemainder(dividingBy: 1)) * 10)
|
|
|
|
if hours > 0 {
|
|
return String(format: "%02i:%02i:%02i.%01i", hours, minutes, seconds, tenths)
|
|
} else {
|
|
return String(format: "%02i:%02i.%01i", minutes, seconds, tenths)
|
|
}
|
|
}
|
|
}
|