From c4c4fed4bcaf51b1333fe212f7062afb9383bf9d Mon Sep 17 00:00:00 2001 From: Michael Housh Date: Wed, 20 Nov 2024 22:43:05 -0500 Subject: [PATCH] feat: Updates tracking state of sensors --- .../Models/TemperatureAndHumiditySensor.swift | 11 ++-- Sources/Models/TrackedChanges.swift | 60 ++++++++++--------- Sources/SensorsService/SensorsService.swift | 2 +- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/Sources/Models/TemperatureAndHumiditySensor.swift b/Sources/Models/TemperatureAndHumiditySensor.swift index a68e65d..04e9b72 100644 --- a/Sources/Models/TemperatureAndHumiditySensor.swift +++ b/Sources/Models/TemperatureAndHumiditySensor.swift @@ -84,12 +84,11 @@ public struct TemperatureAndHumiditySensor: Identifiable, Sendable { /// Check whether any of the sensor values have changed and need processed. /// /// - Note: Setting a value will set to both the temperature and humidity properties. - public var needsProcessed: Bool { - get { $temperature.needsProcessed || $humidity.needsProcessed } - set { - $temperature.needsProcessed = newValue - $humidity.needsProcessed = newValue - } + public var needsProcessed: Bool { $temperature.needsProcessed || $humidity.needsProcessed } + + public mutating func setHasProcessed() { + $temperature.setHasProcessed() + $humidity.setHasProcessed() } /// Represents the different locations of a temperature and humidity sensor, which can diff --git a/Sources/Models/TrackedChanges.swift b/Sources/Models/TrackedChanges.swift index a1b60cf..675e9bf 100755 --- a/Sources/Models/TrackedChanges.swift +++ b/Sources/Models/TrackedChanges.swift @@ -5,24 +5,20 @@ @propertyWrapper public struct TrackedChanges: Sendable { - /// The current tracking state. - private var tracking: TrackingState - - /// The current wrapped value. - private var value: Value + /// The current value wrapped in a tracking state. + private var value: TrackingState /// Used to check if a new value is equal to an old value. private var isEqual: @Sendable (Value, Value) -> Bool /// Access to the underlying property that we are wrapping. public var wrappedValue: Value { - get { value } + get { value.currentValue } set { // Check if the new value is equal to the old value. - guard !isEqual(newValue, value) else { return } + guard !isEqual(newValue, value.currentValue) else { return } // If it's not equal then set it, as well as set the tracking to `.needsProcessed`. - value = newValue - tracking = .needsProcessed + value = .needsProcessed(newValue) } } @@ -37,31 +33,42 @@ public struct TrackedChanges: Sendable { needsProcessed: Bool = false, isEqual: @escaping @Sendable (Value, Value) -> Bool ) { - self.value = wrappedValue - self.tracking = needsProcessed ? .needsProcessed : .hasProcessed + self.value = .init(wrappedValue, needsProcessed: needsProcessed) self.isEqual = isEqual } - /// Represents whether a wrapped value has changed and needs processed or not. - enum TrackingState { + fileprivate enum TrackingState { + case hasProcessed(Value) + case needsProcessed(Value) - /// The state when nothing has changed and we've already processed the current value. - case hasProcessed + init(_ value: Value, needsProcessed: Bool) { + if needsProcessed { + self = .needsProcessed(value) + } else { + self = .hasProcessed(value) + } + } - /// The state when the value has changed and has not been processed yet. - case needsProcessed + var currentValue: Value { + switch self { + case let .hasProcessed(value): + return value + case let .needsProcessed(value): + return value + } + } + + var needsProcessed: Bool { + guard case .needsProcessed = self else { return false } + return true + } } /// Whether the value needs processed. - public var needsProcessed: Bool { - get { tracking == .needsProcessed } - set { - if newValue { - tracking = .needsProcessed - } else { - tracking = .hasProcessed - } - } + public var needsProcessed: Bool { value.needsProcessed } + + public mutating func setHasProcessed() { + value = .hasProcessed(value.currentValue) } public var projectedValue: Self { @@ -95,6 +102,5 @@ extension TrackedChanges: Hashable where Value: Hashable { public func hash(into hasher: inout Hasher) { hasher.combine(wrappedValue) - hasher.combine(needsProcessed) } } diff --git a/Sources/SensorsService/SensorsService.swift b/Sources/SensorsService/SensorsService.swift index 0f97755..5d07e79 100644 --- a/Sources/SensorsService/SensorsService.swift +++ b/Sources/SensorsService/SensorsService.swift @@ -172,7 +172,7 @@ private extension Array where Element == TemperatureAndHumiditySensor { guard let index = firstIndex(where: { $0.id == sensor.id }) else { throw SensorNotFoundError() } - self[index].needsProcessed = false + self[index].setHasProcessed() } }