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.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
Connect4/Persistance/Sources/Persistance/Storage.swift

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
}
}