diff --git a/Chess/macOS/App/AppDelegate.swift b/Chess/macOS/App/AppDelegate.swift index 42bc808..406db0e 100644 --- a/Chess/macOS/App/AppDelegate.swift +++ b/Chess/macOS/App/AppDelegate.swift @@ -12,7 +12,14 @@ extension Notification.Name { } @main -class AppDelegate: NSObject, NSApplicationDelegate { +class AppDelegate: NSObject, NSApplicationDelegate, NSMenuItemValidation { + func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { + if menuItem.title == "Save" { + return NSApp.windows.contains(where: { $0.isVisible }) + } + return true + } + private var gameSavesSubscription: AnyCancellable? @IBOutlet private weak var historyClear: NSMenuItem! @IBOutlet private weak var separator: NSMenuItem! @@ -25,22 +32,25 @@ class AppDelegate: NSObject, NSApplicationDelegate { ) } @IBAction func deleteAll(_ sender: NSMenuItem) { - NotificationCenter.default.post( - name: .persistanceDeleteAll, - object: nil - ) + _ = SaveCoordinator.shared.wipe() } @IBAction func createGame(_ sender: Any) { let storyboard = NSStoryboard(name: "Main", bundle: nil) let controller = storyboard.instantiateInitialController() - (controller as! NSWindowController).showWindow(self) + let windowController = (controller as! NSWindowController) + windowController.showWindow(self) } @objc func loadGame(sender: NSMenuItem) { - NotificationCenter.default.post( - name: .persistanceLoad, - object: ["index": sender.tag] - ) + let storyboard = NSStoryboard(name: "Main", bundle: nil) + let controller = storyboard.instantiateInitialController() + let windowController = (controller as! NSWindowController) + windowController.showWindow(self) + let game = windowController.contentViewController as? GameViewController + guard let gameSave = SaveCoordinator.shared.load(index: sender.tag) else { + fatalError("Index out of bounds") + } + game?.load(save: gameSave) } private func updateItems() { let count = SaveCoordinator.shared.saveCount diff --git a/Chess/macOS/ViewControllers/GameViewController.swift b/Chess/macOS/ViewControllers/GameViewController.swift index e60acd3..a1500b4 100644 --- a/Chess/macOS/ViewControllers/GameViewController.swift +++ b/Chess/macOS/ViewControllers/GameViewController.swift @@ -22,37 +22,24 @@ class GameViewController: NSViewController, GameDelegate, NSGestureRecognizerDel private var state = GameState.initial private var last: NSPoint = .zero private func setupNotifications() { - NotificationCenter.default.publisher(for: .persistanceDeleteAll) - .sink { notification in - _ = SaveCoordinator.shared.wipe() - } - .store(in: &cancellables) NotificationCenter.default.publisher(for: .persistanceSave) .sink { [weak self] notification in guard let self else { return } - let saveState = SaveGame(creationDate: .now, state: state) - _ = SaveCoordinator.shared.save(game: saveState) - } - .store(in: &cancellables) - NotificationCenter.default.publisher(for: .persistanceLoad) - .sink { [weak self] notification in - guard let self else { return } - guard let dictionary = notification.object as? [String: Int], - let index = dictionary["index"] else { - fatalError("Incorrect type passed") - } - guard let gameSave = SaveCoordinator.shared.load(index: index) else { - fatalError("Index out of bounds") + if self.view.window?.isKeyWindow ?? false { + let saveState = SaveGame(creationDate: .now, state: state) + _ = SaveCoordinator.shared.save(game: saveState) } - state = gameSave.state - guard let device = engineView.device else { - fatalError("Device not set") - } - let builder = SceneBuilder(device: device) - engine.scene = builder.build(board: gameSave.state.board) } .store(in: &cancellables) } + func load(save gameSave: SaveGame) { + guard let device = engineView.device else { + fatalError("Device not set") + } + let builder = SceneBuilder(device: device) + engine.scene = builder.build(board: gameSave.state.board) + } + func rotateArcball(from start: SIMD3, to end: SIMD3) -> simd_quatf { let axis = cross(start, end) @@ -83,7 +70,6 @@ class GameViewController: NSViewController, GameDelegate, NSGestureRecognizerDel if (distance < 1e-3) { return } - print("s: \(start), e: \(end)") nodeInteractor.forEach(node: engine.scene.rootNode, { node in guard let node = node.data as? PNAnimatedCameraNode else { return @@ -96,7 +82,8 @@ class GameViewController: NSViewController, GameDelegate, NSGestureRecognizerDel override func viewDidLoad() { super.viewDidLoad() - let panGestureRecognizer = NSPanGestureRecognizer(target: self, action: #selector(handlePan(recognizer: ))) + let panGestureRecognizer = NSPanGestureRecognizer(target: self, + action: #selector(handlePan(recognizer: ))) panGestureRecognizer.allowedTouchTypes = [.direct] view.addGestureRecognizer(panGestureRecognizer)