TimerEngine
open class TimerEngine : Codable, Identifiable
This class implements the “executable heart” of the timer app.
BASIC OVERVIEW
This is a countdown timer, in seconds. It starts from a “starting” time, and counts down to 0, at which time it starts an alarm.
It is a class, as opposed to a struct, so it can be referenced, and so that it can be easily mutated.
The “granularity” of the timer is seconds. It does not deal with fractions of a second. Callbacks only happen on the second or state transitions, and can occur in any thread.
It has six “modes” of operation:
- ### STOPPED MODE
The timer is “stopped.” It is set to the starting time, and the timer is not running.
- ### COUNTDOWN MODE
This is the basic countdown mode, starting from the “starting time” threshold.
- ### WARNING MODE
This is a threshold, in seconds. Once the coundown reaches this, the timer goes into “warning” mode. This cannot be less than the final threshold (or 0), and cannot be higher than the starting threshold.
- ### FINAL MODE
This is a threshold, in seconds. Once the coundown reaches this, the timer goes into “final” mode. The timer is running. This cannot be less than 0, and cannot be higher than the warning threshold.
- ### ALARM MODE
Once it hits 0, it goes into “alarm” mode. The timer stops running, once this threshold is encountered.
- ### PAUSED MODE
The timer countdown is in one of the above ranges, but has been “paused.” It is not running.
-
We will ask for a callback, every millisecond.
Declaration
Swift
private static let _timerInterval: TimeInterval
-
The integer above our maximum number of hours.
Declaration
Swift
static let maxHours: Int
-
The integer above our maximum number of minutes.
Declaration
Swift
static let maxMinutes: Int
-
The integer above our maximum number of seconds.
Declaration
Swift
static let maxSeconds: Int
-
The number of seconds in a minute.
Declaration
Swift
static let secondsInMinute: Int
-
The number of seconds in an hour.
Declaration
Swift
static let secondsInHour: Int
-
This is the actual timer instance that runs the clock.
Declaration
Swift
private var _timer: RVS_BasicGCDTimer?
-
The time to be used as the starting point of the current countdown.
It is adjusted, when pausing.
Declaration
Swift
private var _startTime: Date?
-
This saves the last paused time.
Declaration
Swift
private var _lastPausedTime: TimeInterval
-
This is used to determine whether or not to move to the next second.
Declaration
Swift
private var _countdownTime: Int
-
This is the previous timer mode (to track transitions).
Declaration
Swift
private var _lastMode: Mode
-
This is the structure of the callback for each “tick,” handed to the instance. It is called once a second. It may be called in any thread.
Declaration
Swift
public typealias TimerTickHandler = (_ timerEngine: TimerEngine) -> Void
Parameters
timerEngine
The timer engine instance calling it.
-
This is the structure of the callback for mode transitions, handed to the instance. It is called, once only, when the timer mode changes. It may be called in any thread.
Declaration
Parameters
timerEngine
The timer engine instance calling it.
fromMode
The mode we have transitioned from.
toMode
The mode we have transitioned into.
-
These are part of the Codable conformance. They are used to mark the various field in the encoder/decoder.
See moreDeclaration
Swift
public enum CodingKeys : String, CodingKey
-
This defines the six timer states
See moreDeclaration
Swift
public indirect enum Mode : Equatable, CustomStringConvertible
-
This is the unique ID of this instance.
Declaration
Swift
public var id: UUID
-
This is any data that the implementor may want to attach to this instance.
Declaration
Swift
public var refCon: Any?
-
This is the beginning (total) countdown time.
Declaration
Swift
public var startingTimeInSeconds: Int
-
This is the threshold, at which the clock switches into “warning” mode.
Declaration
Swift
public var warningTimeInSeconds: Int
-
This is the threshold, at which the clock switches into “final” mode.
Declaration
Swift
public var finalTimeInSeconds: Int
-
The callback for the tick handler. This can be called in any thread.
Declaration
Swift
public var tickHandler: TimerTickHandler?
-
The callback for the transition handler. This can be called in any thread. It may also be nil.
Declaration
Swift
public var transitionHandler: TimerTransitionHandler?
-
init(startingTimeInSeconds:
warningTimeInSeconds: finalTimeInSeconds: transitionHandler: id: refCon: startImmediately: tickHandler: ) Default initializer
We specify all three thresholds. The starting threshold is required. The other two are optional, and will be ignored, if not specified.
Declaration
Swift
public init(startingTimeInSeconds inStartingTimeInSeconds: Int = 0, warningTimeInSeconds inWarningTimeInSeconds: Int = 0, finalTimeInSeconds inFinalTimeInSeconds: Int = 0, transitionHandler inTransitionHandler: TimerTransitionHandler? = nil, id inID: UUID = UUID(), refCon inRefCon: Any? = nil, startImmediately inStartImmediately: Bool = false, tickHandler inTickHandler: TimerTickHandler? = nil )
Parameters
inStartingTimeInSeconds
This is the beginning (total) countdown time. If not supplied, is set to 0.
inWarningTimeInSeconds
This is the threshold, at which the clock switches into “warning” mode. If not supplied, is set to 0.
inFinalTimeInSeconds
This is the threshold, at which the clock switches into “final” mode. If not supplied, is set to 0.
inTransitionHandler
The callback for each transition. This is optional.
inID
The ID of this instance (Standard UUID). It must be unique, in the scope of this app. A new UUID is assigned, if not provided.
inRefCon
Any data the implementer wants to attach to this instance. It is not saved or retrieved in the dictionary or encoder, nor is it affected.
inStartImmediately
If true (default is false), the timer will start as soon as the instance is initialized.
inTickHandler
The callback for each tick. This can be a tail completion, and is optional.
-
Codable Conformance. Decoder Initializer.
Declaration
Swift
public required init(from inDecoder: any Decoder) throws
Parameters
inDecoder
The decoder with the state.
-
This is the “first-level” callback from the timer. It can be called in any thread.
Declaration
Swift
func _timerCallback(_ inTimer: RVS_BasicGCDTimer, _ inSuccess: Bool)
Parameters
inTimer
The timer object.
inSuccess
True, if the timer completed its term.
-
This returns the entire timer state as a simple dictionary, suitable for use in plists. The instance can be saved or restored from this. Restoring stops the timer.
Note
This does not affect the
tickHandler
ortransitionHandler
properties.Declaration
Swift
var asDictionary: [String : any Hashable] { get set }
-
This is the current time. It can be set to change the time in the timer. The new value is clamped to the timer range.
Declaration
Swift
var currentTime: Int { get set }
-
This returns the time, in a precise manner.
You can also use this to set the timer to a specific time.
Declaration
Swift
var currentPreciseTime: TimeInterval? { get set }
-
This is the timer mode (computed from the timer state). Read-Only.
Declaration
Swift
var mode: Mode { get }
-
This is a closed range, from one second after the warn or final (if no warn), or the very beginning (if no final), to (and including) the start time.
Note
The range needs to be at least one second long, to be valid.
Declaration
Swift
var startRange: ClosedRange<Int> { get }
-
This is a closed range, from one second after the final, or the very beginning, to (and including) the warn time.
Note
If no warn time (set to 0), then this returns an empty range. The range needs to be at least one second long, to be valid.
Declaration
Swift
var warnRange: ClosedRange<Int> { get }
-
This is a closed range, from the very beginning, to (and including) the final time.
Note
If no final time (set to 0), then this returns an empty range. The range needs to be at least one second long (value of 2), to be valid.
Declaration
Swift
var finalRange: ClosedRange<Int> { get }
-
This is the entire timer range, expressed as a closed seconds range.
Declaration
Swift
var fullRange: ClosedRange<Int> { get }
-
Returns true, if the timer is currently “ticking.”
Declaration
Swift
var isTicking: Bool { get }
-
This returns an “optimized” string, with the current countdown time.
Declaration
Swift
var timerDisplay: String { get }
-
This simply sets the last paused time, to the current time.
Declaration
Swift
func resetLastPausedTime()
-
This forces the timer to sync directly to the given seconds. The date is the time that corresponds to the exact second. The timer is started, if it was not already running.
Note
This directly sets the timer to a running state, but the
tickHandler
andtransitionHandler
callbacks may not be immediately executed. The timer must already be in.countdown
,.warning
, or.final
state.Declaration
Swift
func sync(to inSeconds: Int, date inDate: Date = .now)
Parameters
inSeconds
The actual integer second.
inDate
The date that corresponds to the given second. If not supplied, .now is used.
-
Starts the timer from the beginning. It will do so, from any timer state.
This will interrupt any current timer.
Declaration
Swift
func start()
-
This stops the timer, and resets it to the starting point, with no alarm. It will do so, from any timer state.
This will interrupt any current timer.
Declaration
Swift
func stop()
-
This forces the timer into alarm mode. It will do so, from any timer state.
This will interrupt any current timer.
Declaration
Swift
func end()
-
This pauses a running timer. The timer must already be in
.countdown
,.warning
, or.final
state.Declaration
Swift
@discardableResult func pause() -> [String : any Hashable]
Return Value
The state of the instance, just prior to pausing (empty, if failed). Can be ignored.
-
This resumes a paused timer. The timer must already be in
.paused
state, or a new state should be provided.You can use this method to set a timer to a saved state, and start it going immediately.
Note
This does not affect the
tickHandler
ortransitionHandler
properties, unless they are provided as method arguments. If thetickHandler
ortransitionHandler
method arguments are supplied, and the resume fails, they will not be applied.Declaration
Swift
@discardableResult func resume(_ inState: [String: any Hashable]? = nil, transitionHandler inTransitionHandler: TimerTransitionHandler? = nil, tickHandler inTickHandler: TimerTickHandler? = nil ) -> Bool
Parameters
inState
The saved state of the timer. If provided, the timer is set to that state, and started immediately, as opposed to a regular resume.
inTransitionHandler
The callback for each transition. This is optional.
inTickHandler
The callback for each tick. This can be a tail completion, and is optional.
Return Value
True, if the resume was successful.
-
Codable Conformance: The Encoder.
Declaration
Swift
func encode(to inEncoder: any Encoder) throws
Parameters
inEncoder
The Encoder to be loaded with our state.
-
Simple cast to the wrapper instance that “owns” this timer.
Declaration
Swift
var timer: Timer? { get }
-
The group to which this timer’s container belongs.
Declaration
Swift
var group: TimerGroup? { get }
-
The model that contains this timer.
Declaration
Swift
var model: TimerModel? { get }