131 lines
4.3 KiB
Swift
131 lines
4.3 KiB
Swift
import ComposableArchitecture
|
|
import Foundation
|
|
import SharedModels
|
|
|
|
/// Holds onto shared values for several of the views in this feature.
|
|
@dynamicMemberLookup
|
|
public struct SharedPressureEstimationState: Equatable, Sendable {
|
|
public var budgets: BudgetedPercentEnvelope?
|
|
public var equipmentMeasurement: EquipmentMeasurement?
|
|
public var equipmentMetadata: EquipmentMetadata
|
|
public var flaggedEquipmentMeasurement: EquipmentMeasurement.FlaggedMeasurement?
|
|
public var flaggedEstimations: IdentifiedArrayOf<FlaggedEstimationContainer>
|
|
public var heatingCapacity: Double?
|
|
public var manufacturersIncludedFilterPressureDrop: Double?
|
|
|
|
public init(
|
|
budgets: BudgetedPercentEnvelope? = nil,
|
|
equipmentMeasurement: EquipmentMeasurement? = nil,
|
|
equipmentMetadata: EquipmentMetadata = .init(),
|
|
flaggedEquipmentMeasurement: EquipmentMeasurement.FlaggedMeasurement? = nil,
|
|
flaggedEstimations: IdentifiedArrayOf<FlaggedEstimationContainer> = [],
|
|
heatingCapacity: Double? = nil,
|
|
manufacturersIncludedFilterPressureDrop: Double? = nil
|
|
) {
|
|
self.budgets = budgets
|
|
self.equipmentMeasurement = equipmentMeasurement
|
|
self.equipmentMetadata = equipmentMetadata
|
|
self.flaggedEquipmentMeasurement = flaggedEquipmentMeasurement
|
|
self.flaggedEstimations = flaggedEstimations
|
|
self.heatingCapacity = heatingCapacity
|
|
self.manufacturersIncludedFilterPressureDrop = manufacturersIncludedFilterPressureDrop
|
|
}
|
|
|
|
public subscript<T>(dynamicMember keyPath: WritableKeyPath<EquipmentMetadata, T>) -> T {
|
|
get { equipmentMetadata[keyPath: keyPath] }
|
|
set { equipmentMetadata[keyPath: keyPath] = newValue }
|
|
}
|
|
|
|
@dynamicMemberLookup
|
|
public struct FlaggedEstimationContainer: Equatable, Identifiable, Sendable {
|
|
public let id: UUID
|
|
public var estimationState: EstimationState
|
|
public var flaggedMeasurement: EquipmentMeasurement.FlaggedMeasurement
|
|
|
|
public init(
|
|
id: UUID,
|
|
estimationState: EstimationState,
|
|
flaggedMeasurement: EquipmentMeasurement.FlaggedMeasurement
|
|
) {
|
|
self.id = id
|
|
self.estimationState = estimationState
|
|
self.flaggedMeasurement = flaggedMeasurement
|
|
}
|
|
|
|
public subscript<T>(dynamicMember keyPath: WritableKeyPath<EstimationState, T>) -> T {
|
|
get { estimationState[keyPath: keyPath] }
|
|
set { estimationState[keyPath: keyPath] = newValue }
|
|
}
|
|
|
|
public subscript<T>(dynamicMember keyPath: KeyPath<EstimationState, T>) -> T {
|
|
get { estimationState[keyPath: keyPath] }
|
|
}
|
|
|
|
public struct EstimationState: Equatable, Sendable {
|
|
public var cfm: CFMContainer
|
|
public var filterPressureDrop: Double?
|
|
public var name: String?
|
|
|
|
public init(
|
|
cfm: CFMContainer,
|
|
filterPressureDrop: Double? = nil,
|
|
name: String? = nil
|
|
) {
|
|
self.cfm = cfm
|
|
self.filterPressureDrop = filterPressureDrop
|
|
self.name = name
|
|
}
|
|
|
|
internal init(state: EstimationForm.State) {
|
|
self.init(
|
|
cfm: .init(state: state),
|
|
filterPressureDrop: state.filterPressureDrop,
|
|
name: state.name.isEmpty ? nil : state.name
|
|
)
|
|
}
|
|
|
|
var displayName: String {
|
|
guard let name else {
|
|
return "@\(Int(cfm.airflow)) CFM"
|
|
}
|
|
return name
|
|
}
|
|
|
|
// Compare relevant values on if two states have changes.
|
|
func hasChanges(_ other: Self) -> Bool {
|
|
cfm != other.cfm || filterPressureDrop != other.filterPressureDrop
|
|
}
|
|
|
|
public enum CFMContainer: Equatable, Sendable {
|
|
case cfm(Int)
|
|
case cfmPerTon(Int, EquipmentMetadata.CoolingCapacity)
|
|
|
|
init(state: EstimationForm.State) {
|
|
switch state.airflowSelection {
|
|
case .cfmPerTon:
|
|
self = .cfmPerTon(state.cfmTextField ?? 0, state.coolingCapacity)
|
|
case .cfm:
|
|
self = .cfm(state.cfmTextField ?? 0)
|
|
}
|
|
}
|
|
|
|
var airflow: Double {
|
|
switch self {
|
|
case let .cfm(cfm):
|
|
return Double(cfm)
|
|
case let .cfmPerTon(cfmPerTon, capacity):
|
|
return Double(cfmPerTon) * capacity.rawValue
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
extension PersistenceReaderKey where Self == InMemoryKey<SharedPressureEstimationState> {
|
|
static var sharedPressureEstimationSettings: Self {
|
|
.inMemory("sharedPressureEstimationSettings")
|
|
}
|
|
}
|