120 lines
4.5 KiB
Swift
120 lines
4.5 KiB
Swift
import Foundation
|
|
|
|
struct SyncPlayPayload: Codable {
|
|
let trackID: String
|
|
let startUptime: TimeInterval
|
|
let startPosition: TimeInterval
|
|
}
|
|
|
|
struct TrackInfoPayload: Codable {
|
|
let trackID: String
|
|
let displayName: String
|
|
}
|
|
|
|
enum SessionMessage: Codable {
|
|
case hello
|
|
case libraryRequest
|
|
case trackInfo(TrackInfoPayload)
|
|
case trackRequest(String)
|
|
case play(SyncPlayPayload)
|
|
case pause
|
|
case seek(TimeInterval)
|
|
case syncRequest(TimeInterval)
|
|
case syncResponse(hostUptime: TimeInterval, peerUptime: TimeInterval)
|
|
case driftCorrection(position: TimeInterval, hostUptime: TimeInterval)
|
|
|
|
private enum CodingKeys: String, CodingKey {
|
|
case type
|
|
case payload
|
|
case position
|
|
case hostUptime
|
|
case peerUptime
|
|
case trackID
|
|
case displayName
|
|
}
|
|
|
|
private enum MessageType: String, Codable {
|
|
case hello
|
|
case libraryRequest
|
|
case trackInfo
|
|
case trackRequest
|
|
case play
|
|
case pause
|
|
case seek
|
|
case syncRequest
|
|
case syncResponse
|
|
case driftCorrection
|
|
}
|
|
|
|
init(from decoder: Decoder) throws {
|
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
|
let type = try container.decode(MessageType.self, forKey: .type)
|
|
switch type {
|
|
case .hello:
|
|
self = .hello
|
|
case .libraryRequest:
|
|
self = .libraryRequest
|
|
case .trackInfo:
|
|
let payload = try container.decode(TrackInfoPayload.self, forKey: .payload)
|
|
self = .trackInfo(payload)
|
|
case .trackRequest:
|
|
let trackID = try container.decode(String.self, forKey: .trackID)
|
|
self = .trackRequest(trackID)
|
|
case .play:
|
|
let payload = try container.decode(SyncPlayPayload.self, forKey: .payload)
|
|
self = .play(payload)
|
|
case .pause:
|
|
self = .pause
|
|
case .seek:
|
|
let position = try container.decode(TimeInterval.self, forKey: .position)
|
|
self = .seek(position)
|
|
case .syncRequest:
|
|
let hostUptime = try container.decode(TimeInterval.self, forKey: .hostUptime)
|
|
self = .syncRequest(hostUptime)
|
|
case .syncResponse:
|
|
let hostUptime = try container.decode(TimeInterval.self, forKey: .hostUptime)
|
|
let peerUptime = try container.decode(TimeInterval.self, forKey: .peerUptime)
|
|
self = .syncResponse(hostUptime: hostUptime, peerUptime: peerUptime)
|
|
case .driftCorrection:
|
|
let position = try container.decode(TimeInterval.self, forKey: .position)
|
|
let hostUptime = try container.decode(TimeInterval.self, forKey: .hostUptime)
|
|
self = .driftCorrection(position: position, hostUptime: hostUptime)
|
|
}
|
|
}
|
|
|
|
func encode(to encoder: Encoder) throws {
|
|
var container = encoder.container(keyedBy: CodingKeys.self)
|
|
switch self {
|
|
case .hello:
|
|
try container.encode(MessageType.hello, forKey: .type)
|
|
case .libraryRequest:
|
|
try container.encode(MessageType.libraryRequest, forKey: .type)
|
|
case .trackInfo(let payload):
|
|
try container.encode(MessageType.trackInfo, forKey: .type)
|
|
try container.encode(payload, forKey: .payload)
|
|
case .trackRequest(let trackID):
|
|
try container.encode(MessageType.trackRequest, forKey: .type)
|
|
try container.encode(trackID, forKey: .trackID)
|
|
case .play(let payload):
|
|
try container.encode(MessageType.play, forKey: .type)
|
|
try container.encode(payload, forKey: .payload)
|
|
case .pause:
|
|
try container.encode(MessageType.pause, forKey: .type)
|
|
case .seek(let position):
|
|
try container.encode(MessageType.seek, forKey: .type)
|
|
try container.encode(position, forKey: .position)
|
|
case .syncRequest(let hostUptime):
|
|
try container.encode(MessageType.syncRequest, forKey: .type)
|
|
try container.encode(hostUptime, forKey: .hostUptime)
|
|
case .syncResponse(let hostUptime, let peerUptime):
|
|
try container.encode(MessageType.syncResponse, forKey: .type)
|
|
try container.encode(hostUptime, forKey: .hostUptime)
|
|
try container.encode(peerUptime, forKey: .peerUptime)
|
|
case .driftCorrection(let position, let hostUptime):
|
|
try container.encode(MessageType.driftCorrection, forKey: .type)
|
|
try container.encode(position, forKey: .position)
|
|
try container.encode(hostUptime, forKey: .hostUptime)
|
|
}
|
|
}
|
|
}
|