OSDN Git Service

Optional.none を nil表記に変更
[kcd/KCD.git] / KCD / Fleet.swift
index e8fddca..c90e993 100644 (file)
 
 import Cocoa
 
-fileprivate var pDeckContext = 0
+final class DeckObserver {
+    
+    private let deck: Deck
+    private let handler: (Deck) -> Void
+    
+    private var observation: [NSKeyValueObservation] = []
+    
+    init(deck: Deck, handler: @escaping (Deck) -> Void) {
+        
+        self.deck = deck
+        self.handler = handler
+        
+        observation += [deck.observe(\Deck.ship_0, changeHandler: observeHandler)]
+        observation += [deck.observe(\Deck.ship_1, changeHandler: observeHandler)]
+        observation += [deck.observe(\Deck.ship_2, changeHandler: observeHandler)]
+        observation += [deck.observe(\Deck.ship_3, changeHandler: observeHandler)]
+        observation += [deck.observe(\Deck.ship_4, changeHandler: observeHandler)]
+        observation += [deck.observe(\Deck.ship_5, changeHandler: observeHandler)]
+        observation += [deck.observe(\Deck.ship_6, changeHandler: observeHandler)]
+        
+        handler(deck)
+    }
+    
+    private func observeHandler(_: Deck, _:NSKeyValueObservedChange<Int>) {
+        
+        handler(deck)
+    }
+}
 
-class Fleet: NSObject {
+final class Fleet: NSObject {
+    
     let fleetNumber: Int
-    private let deckObserveKeys = [
-        "selection.ship_0", "selection.ship_1", "selection.ship_2",
-        "selection.ship_3", "selection.ship_4", "selection.ship_5"
-    ]
+    
+    private var observer: DeckObserver?
+    
+    @objc dynamic private(set) var ships: [Ship] = []
+    private var deck: Deck?
+    
+    let store = ServerDataStore.default
     
     init?(number: Int) {
-        guard 1...4 ~= number
-            else {
-                print("Fleet number out of range")
-                return nil
+        
+        guard case 1...4 = number else {
+            
+            Logger.shared.log("Fleet number out of range")
+            
+            return nil
         }
+        
         fleetNumber = number
-        deckController = NSObjectController()
+        
         super.init()
         
-        deckController.entityName = Deck.entityName
-        deckController.managedObjectContext = ServerDataStore.default.context
-        deckController.fetchPredicate = NSPredicate(format: "id = %ld", number)
-        let req = NSFetchRequest<NSFetchRequestResult>()
-        req.entity = NSEntityDescription.entity(forEntityName: Deck.entityName,
-                                                in: deckController.managedObjectContext!)
-        req.predicate = deckController.fetchPredicate
-        do {
-            try deckController.fetch(with: req, merge: false)
-        } catch {
-            print("Fetch error")
-            return nil
+        if let deck = store.sync(execute: { self.store.deck(by: number) }) {
+            
+            self.setupDeck(deck: deck)
+            
+            return
+        }
+        
+        ServerDataStore.default
+            .future { _ -> Deck? in
+                
+                guard let deck = self.store.sync(execute: { self.store.deck(by: number) }) else {
+                    
+                    return nil
+                }
+                
+                return deck
+            }
+            .onSuccess { deck in
+                
+                self.setupDeck(deck: deck)
+            }
+            .onFailure { error in
+                
+                Logger.shared.log("\(error)")
         }
-        deck = deckController.content as? Deck
-        deckObserveKeys.forEach { deckController.addObserver(self, forKeyPath: $0, context: &pDeckContext) }
-    }
-    deinit {
-        deckObserveKeys.forEach { deckController.removeObserver(self, forKeyPath: $0) }
     }
     
-    dynamic private(set) var ships: [Ship] = []
-    private let deckController: NSObjectController
-    private weak var deck: Deck?
-    
-    dynamic var name: String? { return deck?.name }
-    func keyPathsForValuesAffectingName() -> Set<String> {
-        return ["deck.name"]
-    }
-    dynamic var id: NSNumber? { return deck?.id as NSNumber? }
-    func keyPathesForValuesAffectiongId() -> Set<String> {
-        return ["deck.id"]
+    subscript(_ index: Int) -> Ship? {
+        
+        return store.sync { self.deck?[index] }
     }
     
-    subscript(_ index: Int) -> Ship? { return deck?[index] }
-    
-    override func observeValue(forKeyPath keyPath: String?,
-                               of object: Any?,
-                               change: [NSKeyValueChangeKey : Any]?,
-                               context: UnsafeMutableRawPointer?) {
-        if context == &pDeckContext {
-            ships = (0..<6).flatMap { return self[$0] }
-            return
+    private func setupDeck(deck: Deck) {
+        
+        self.deck = deck
+        self.observer = DeckObserver(deck: deck) { [weak self] in
+            
+            self?.setupShips(deck: $0)
         }
-        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
+    }
+    
+    private func setupShips(deck: Deck) {
+        
+        ships = store.sync { deck[0...6] }
     }
 }