mirror of
https://github.com/somegeekintn/SimDirs.git
synced 2026-04-21 13:15:52 +00:00
154 lines
5.1 KiB
Swift
154 lines
5.1 KiB
Swift
//
|
|
// SimRuntime.swift
|
|
// SimDirs
|
|
//
|
|
// Created by Casey Fleser on 5/24/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
|
|
struct SimRuntime: 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
|
|
}
|
|
}
|
|
|
|
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 devices = [SimDevice]()
|
|
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
|
|
}
|
|
|
|
mutating func setDevices(_ devices: [SimDevice], from devTypes: [SimDeviceType]) {
|
|
self.devices = devices.map { $0.scannedDevice }
|
|
|
|
// 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 updatedDevices(from devices: [SimDevice]) -> [SimDevice] {
|
|
return devices.compactMap { device in
|
|
self.devices.first(where: { $0.udid == device.udid })?.updatedDevice(from: device)
|
|
}
|
|
}
|
|
|
|
mutating func applyDeviceUpdates(_ devices: [SimDevice]) {
|
|
for device in devices {
|
|
guard let devIdx = self.devices.firstIndex(where: { $0.udid == device.udid }) else { continue }
|
|
|
|
self.devices[devIdx] = device
|
|
}
|
|
}
|
|
}
|
|
|
|
extension SimRuntime: SourceItemData {
|
|
var title : String { return name }
|
|
var headerTitle : String { "Runtime: \(title)" }
|
|
var imageDesc : SourceImageDesc { .symbol(systemName: "shippingbox", color: isAvailable ? .green : .red) }
|
|
|
|
var optionTrait : SourceFilter.Options { isAvailable ? .runtimeInstalled : [] }
|
|
}
|
|
|
|
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) }
|
|
}
|
|
}
|