You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.3 KiB
62 lines
2.3 KiB
import Foundation
|
|
import Model
|
|
|
|
@available(macOS 13.0, *)
|
|
public struct Storage {
|
|
private static let gameDirectory = try! URL(for: .applicationDirectory, in: .userDomainMask).appending(path: "Connect4")
|
|
private static let unfinishedGame = gameDirectory.appending(path: "unfinished.json")
|
|
private static let finishedGameDirectory = gameDirectory.appending(path: "finished")
|
|
|
|
/* func hasUnfinishedGame() -> Bool {
|
|
return FileManager.default.fileExists(atPath: unfinishedGameDirectory.path)
|
|
} */
|
|
|
|
public static func loadUnfinishedGame(callbackFactory: @escaping (_ name: String, _ type: PieceType) -> MoveCallback) async throws -> Game? {
|
|
// Will read the file asynchronously
|
|
let content = await Task {
|
|
if FileManager.default.fileExists(atPath: unfinishedGame.path) {
|
|
return FileManager.default.contents(atPath: unfinishedGame.path)
|
|
} else {
|
|
return nil
|
|
}
|
|
}.value
|
|
guard let content = content else { return nil }
|
|
|
|
let decoder = JSONDecoder()
|
|
decoder.userInfo[.gameDecodingContext] = CodableContext(creatingCallbacks: callbackFactory)
|
|
|
|
return (try decoder.decode(CodableGameWrapper.self, from: content)).game
|
|
}
|
|
|
|
public static func save(game: Game, finished: Bool) async throws {
|
|
let (directory, file) = if finished {
|
|
(
|
|
finishedGameDirectory.path,
|
|
finishedGameDirectory
|
|
.appending(path: "\(Date())")
|
|
.appendingPathExtension(".json")
|
|
)
|
|
} else {
|
|
(gameDirectory.path, unfinishedGame)
|
|
}
|
|
|
|
let encoder = JSONEncoder()
|
|
encoder.outputFormatting = .prettyPrinted
|
|
encoder.userInfo[.gameDecodingContext] = CodableContext()
|
|
|
|
let data = try encoder.encode(CodableGameWrapper(of: game))
|
|
|
|
// Does Swift have true async IO natively???
|
|
try await Task {
|
|
try FileManager.default.createDirectory(atPath: directory, withIntermediateDirectories: true)
|
|
try data.write(to: file)
|
|
}.value
|
|
}
|
|
|
|
public static func clearUnfinished() async throws {
|
|
try await Task {
|
|
try FileManager.default.removeItem(at: unfinishedGame)
|
|
}.value
|
|
}
|
|
}
|