mirror of
https://github.com/somegeekintn/SimDirs.git
synced 2026-03-25 08:55:54 +00:00
153 lines
5.1 KiB
Swift
153 lines
5.1 KiB
Swift
//
|
|
// SimRuntime.swift
|
|
// SimDirs
|
|
//
|
|
// Created by Casey Fleser on 5/24/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
class SimRuntime: ObservableObject, Comparable, Decodable {
|
|
enum CodingKeys: String, CodingKey {
|
|
case availabilityError
|
|
case bundlePath
|
|
case buildversion
|
|
case identifier
|
|
case isAvailable
|
|
case isInternal
|
|
case name
|
|
case platform
|
|
case runtimeRoot
|
|
case supportedDeviceTypes
|
|
case version
|
|
}
|
|
|
|
struct DeviceType: Decodable {
|
|
let name : String
|
|
let bundlePath : String
|
|
let identifier : String
|
|
let productFamily : SimProductFamily
|
|
|
|
init(canonical: SimDeviceType) {
|
|
name = canonical.name
|
|
bundlePath = canonical.bundlePath
|
|
identifier = canonical.identifier
|
|
productFamily = canonical.productFamily
|
|
}
|
|
}
|
|
|
|
@Published var devices = [SimDevice]()
|
|
|
|
let name : String
|
|
let version : String
|
|
let identifier : String
|
|
let platform : SimPlatform
|
|
|
|
let bundlePath : String
|
|
let buildversion : String
|
|
let runtimeRoot : String
|
|
let isInternal : Bool
|
|
let isAvailable : Bool
|
|
var supportedDeviceTypes : [DeviceType]
|
|
let availabilityError : String?
|
|
|
|
var isPlaceholder = false
|
|
|
|
static func < (lhs: SimRuntime, rhs: SimRuntime) -> Bool {
|
|
return lhs.name < rhs.name
|
|
}
|
|
|
|
static func == (lhs: SimRuntime, rhs: SimRuntime) -> Bool {
|
|
return lhs.identifier == rhs.identifier
|
|
}
|
|
|
|
init(platformID: String) throws {
|
|
guard let lastComponent = platformID.split(separator: ".").last else { throw SimError.deviceParsingFailure }
|
|
let vComps = lastComponent.split(separator: "-")
|
|
|
|
if vComps.count == 3 {
|
|
guard let compPlatform = SimPlatform(rawValue: String(vComps[0])) else { throw SimError.deviceParsingFailure }
|
|
guard let major = Int(vComps[1]) else { throw SimError.deviceParsingFailure }
|
|
guard let minor = Int(vComps[2]) else { throw SimError.deviceParsingFailure }
|
|
|
|
platform = compPlatform
|
|
version = "\(major).\(minor)"
|
|
name = "\(platform) \(version)"
|
|
identifier = platformID
|
|
|
|
bundlePath = ""
|
|
buildversion = ""
|
|
runtimeRoot = ""
|
|
isInternal = false
|
|
isAvailable = false
|
|
supportedDeviceTypes = []
|
|
availabilityError = "Missing runtime"
|
|
isPlaceholder = true
|
|
}
|
|
else {
|
|
throw SimError.deviceParsingFailure
|
|
}
|
|
}
|
|
|
|
func supports(deviceType: SimDeviceType) -> Bool {
|
|
return supportedDeviceTypes.contains { $0.identifier == deviceType.identifier }
|
|
}
|
|
|
|
func supports(platform: SimPlatform) -> Bool {
|
|
return self.platform == platform
|
|
}
|
|
|
|
func setDevices(_ devices: [SimDevice], from devTypes: [SimDeviceType]) {
|
|
self.devices = devices
|
|
|
|
// If this runtime is a placeholder it will be missing supported device types
|
|
// create device type stubs based on the devices being added using supplied
|
|
// fully described device types
|
|
|
|
if isPlaceholder {
|
|
let devTypeIDs = Set(devices.map({ $0.deviceTypeIdentifier }))
|
|
|
|
self.supportedDeviceTypes = devTypeIDs.compactMap { devTypeID in
|
|
devTypes.first(where: { $0.identifier == devTypeID }).map({ SimRuntime.DeviceType(canonical: $0) })
|
|
}
|
|
}
|
|
}
|
|
|
|
func reconcileDevices(_ curDevices: [SimDevice], forTypes deviceTypes: [SimDeviceType]) -> SimModel.Update? {
|
|
let curDevIDs = curDevices.map { $0.udid }
|
|
let ourDevIDs = devices.map { $0.udid }
|
|
let additions = curDevices.filter { !ourDevIDs.contains($0.udid) }
|
|
let removals = devices.filter { !curDevIDs.contains($0.udid) }
|
|
var result : SimModel.Update? = nil
|
|
|
|
if !additions.isEmpty || !removals.isEmpty {
|
|
let idsToRemove = removals.map { $0.udid }
|
|
|
|
additions.completeSetup(with: deviceTypes)
|
|
devices.removeAll(where: { idsToRemove.contains($0.udid) })
|
|
devices.append(contentsOf: additions)
|
|
|
|
result = SimModel.Update(runtime: self, additions: additions, removals: removals)
|
|
}
|
|
|
|
return result
|
|
}
|
|
}
|
|
|
|
extension Array where Element == SimRuntime {
|
|
mutating func indexOfMatchedOrCreated(identifier: String) throws -> Index {
|
|
return try firstIndex { $0.identifier == identifier } ?? {
|
|
try self.append(SimRuntime(platformID: identifier))
|
|
|
|
return self.endIndex - 1
|
|
}()
|
|
}
|
|
|
|
func supporting(deviceType: SimDeviceType) -> Self {
|
|
filter { $0.supports(deviceType: deviceType) }
|
|
}
|
|
|
|
func supporting(platform: SimPlatform) -> Self {
|
|
filter { $0.supports(platform: platform) }
|
|
}
|
|
}
|