OSDN Git Service

Optional.none を nil表記に変更
[kcd/KCD.git] / KCD / Fleet.swift
index 430147c..c90e993 100644 (file)
@@ -8,23 +8,52 @@
 
 import Cocoa
 
-private 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)
+    }
+}
 
 final class Fleet: NSObject {
     
     let fleetNumber: Int
-    private let deckController = NSObjectController()
     
-    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 case 1...4 = number else {
             
-            print("Fleet number out of range")
+            Logger.shared.log("Fleet number out of range")
+            
             return nil
         }
         
@@ -32,64 +61,49 @@ final class Fleet: NSObject {
         
         super.init()
         
-        deckController.entityName = Deck.entityName
-        deckController.managedObjectContext = ServerDataStore.default.context
-        deckController.fetchPredicate = NSPredicate(#keyPath(Deck.id), equal: 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)
+        if let deck = store.sync(execute: { self.store.deck(by: number) }) {
             
-        } catch {
-            
-            print("Fetch error")
-            return nil
+            self.setupDeck(deck: deck)
             
+            return
         }
         
-        deck = deckController.content as? Deck
-        deckObserveKeys.forEach { deckController.addObserver(self, forKeyPath: $0, context: &pDeckContext) }
+        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)")
+        }
     }
     
-    deinit {
-        
-        deckObserveKeys.forEach { deckController.removeObserver(self, forKeyPath: $0) }
+    subscript(_ index: Int) -> Ship? {
         
+        return store.sync { self.deck?[index] }
     }
     
-    @objc override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
+    private func setupDeck(deck: Deck) {
         
-        switch key {
-            
-        case #keyPath(name): return ["deck.name"]
+        self.deck = deck
+        self.observer = DeckObserver(deck: deck) { [weak self] in
             
-        case #keyPath(id): return ["deck.id"]
-            
-        default: return []
+            self?.setupShips(deck: $0)
         }
     }
     
-    @objc dynamic private(set) var ships: [Ship] = []
-    @objc weak var deck: Deck?
-    
-    @objc dynamic var name: String? { return deck?.name }
-    @objc dynamic var id: NSNumber? { return deck?.id as NSNumber? }
-    
-    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 setupShips(deck: Deck) {
         
-        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
+        ships = store.sync { deck[0...6] }
     }
 }