OSDN Git Service

ShipSlotObserverを使用するように変更
authormasakih <masakih@users.sourceforge.jp>
Wed, 3 Jan 2018 04:49:40 +0000 (13:49 +0900)
committermasakih <masakih@users.sourceforge.jp>
Sat, 6 Jan 2018 13:00:57 +0000 (22:00 +0900)
KCD/Base.lproj/ShipDetailViewController.xib
KCD/ShipDetailViewController.swift
KCD/ShipSlotObserver.swift

index e1c4dab..11d4682 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
+<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="13771" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
     <dependencies>
         <deployment identifier="macosx"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="12121"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="13771"/>
         <capability name="box content view" minToolsVersion="7.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -11,7 +11,6 @@
             <connections>
                 <outlet property="damageView" destination="nEA-WU-NFe" id="od5-wU-CYo"/>
                 <outlet property="guardEscapedView" destination="thk-XX-zcO" id="DTR-hh-lQW"/>
-                <outlet property="shipController" destination="LyA-xZ-gxq" id="UUT-aV-NLA"/>
                 <outlet property="slot00Field" destination="9ct-MC-zEi" id="vKp-1J-o5D"/>
                 <outlet property="slot01Field" destination="WPW-1R-1aV" id="L2T-uv-b0G"/>
                 <outlet property="slot02Field" destination="4qS-ds-Fe5" id="ZbW-Id-7s4"/>
@@ -24,7 +23,7 @@
         <customObject id="-3" userLabel="Application" customClass="NSObject"/>
         <objectController mode="entity" entityName="Ship" editable="NO" automaticallyPreparesContent="YES" id="LyA-xZ-gxq">
             <connections>
-                <binding destination="-2" name="managedObjectContext" keyPath="managedObjectContext" id="5At-Ts-Skb"/>
+                <binding destination="-2" name="contentObject" keyPath="ship" id="OdW-FF-vhi"/>
             </connections>
         </objectController>
         <box autoresizesSubviews="NO" boxType="custom" borderType="line" title="Box" titlePosition="noTitle" id="SH2-fF-cTe">
index 561ec1f..614aaa1 100644 (file)
@@ -24,13 +24,6 @@ private func nibNameFor(_ type: ShipDetailViewType) -> NSNib.Name {
     }
 }
 
-private var shipContext: Int = 0
-private var equippedItem0Context: Int = 0
-private var equippedItem1Context: Int = 0
-private var equippedItem2Context: Int = 0
-private var equippedItem3Context: Int = 0
-private var equippedItem4Context: Int = 0
-
 final class ShipDetailViewController: NSViewController {
     
     let type: ShipDetailViewType
@@ -46,9 +39,7 @@ final class ShipDetailViewController: NSViewController {
             .default
             .addObserver(forName: .DidUpdateGuardEscape, object: nil, queue: nil) { [weak self] _ in
                 
-                guard let `self` = self else { return }
-                
-                self.guardEscaped = self.ship?.guardEscaped ?? false
+                self?.guardEscaped = self?.ship?.guardEscaped ?? false
         }
     }
     
@@ -61,32 +52,8 @@ final class ShipDetailViewController: NSViewController {
         
         NotificationCenter.default.removeObserver(self)
         damageView.unbind(NSBindingName(#keyPath(DamageView.damageType)))
-        supply.unbind(NSBindingName(#keyPath(SuppliesView.ship)))
         [slot00Field, slot01Field, slot02Field, slot03Field]
             .forEach { $0?.unbind(NSBindingName(#keyPath(SlotItemLevelView.slotItemID))) }
-        
-        shipController.removeObserver(self, forKeyPath: "selection")
-        
-        shipController.removeObserver(self, forKeyPath: "selection.slot_0")
-        shipController.removeObserver(self, forKeyPath: "selection.onslot_0")
-        shipController.removeObserver(self, forKeyPath: "selection.master_ship.maxeq_0")
-        
-        shipController.removeObserver(self, forKeyPath: "selection.slot_1")
-        shipController.removeObserver(self, forKeyPath: "selection.onslot_1")
-        shipController.removeObserver(self, forKeyPath: "selection.master_ship.maxeq_1")
-
-        shipController.removeObserver(self, forKeyPath: "selection.slot_2")
-        shipController.removeObserver(self, forKeyPath: "selection.onslot_2")
-        shipController.removeObserver(self, forKeyPath: "selection.master_ship.maxeq_2")
-        
-        shipController.removeObserver(self, forKeyPath: "selection.slot_3")
-        shipController.removeObserver(self, forKeyPath: "selection.onslot_3")
-        shipController.removeObserver(self, forKeyPath: "selection.master_ship.maxeq_3")
-        
-        shipController.removeObserver(self, forKeyPath: "selection.slot_4")
-        shipController.removeObserver(self, forKeyPath: "selection.onslot_4")
-        shipController.removeObserver(self, forKeyPath: "selection.master_ship.maxeq_4")
-
     }
     
     
@@ -97,7 +64,8 @@ final class ShipDetailViewController: NSViewController {
     @IBOutlet weak var slot01Field: SlotItemLevelView!
     @IBOutlet weak var slot02Field: SlotItemLevelView!
     @IBOutlet weak var slot03Field: SlotItemLevelView!
-    @IBOutlet var shipController: NSObjectController!
+    
+    var observer: ShipSlotObserver?
     
     @objc dynamic var guardEscaped: Bool = false {
         
@@ -108,9 +76,47 @@ final class ShipDetailViewController: NSViewController {
     
     @objc dynamic var ship: Ship? {
         
-        get { return shipController.content as? Ship }
-        set {
-            shipController.fetchPredicate = NSPredicate(#keyPath(Ship.id), equal: newValue?.id ?? 0)
+        didSet {
+            
+            defer {
+                didChangeSlot0()
+                didChangeSlot1()
+                didChangeSlot2()
+                didChangeSlot3()
+                didChangeSlot4()
+            }
+            
+            supply.ship = ship
+            
+            observer = ship.map { ship in
+                
+                let observer  = ShipSlotObserver(ship: ship)
+                observer.delegate = self
+                
+                return observer
+            }
+            
+            // slot の lv, alv の反映のため
+            let fields = [slot00Field, slot01Field, slot02Field, slot03Field]
+            fields.forEach { $0?.unbind(NSBindingName(#keyPath(SlotItemLevelView.slotItemID))) }
+            
+            damageView.unbind(NSBindingName(#keyPath(DamageView.damageType)))
+            
+            if let ship = ship {
+                
+                zip(fields, [#keyPath(Ship.slot_0), #keyPath(Ship.slot_1), #keyPath(Ship.slot_2), #keyPath(Ship.slot_3)])
+                    .forEach { feild, keyPath in
+                        feild?.bind(NSBindingName(#keyPath(SlotItemLevelView.slotItemID)), to: ship, withKeyPath: keyPath)
+                }
+                
+                damageView.bind(NSBindingName(#keyPath(DamageView.damageType)), to: ship, withKeyPath: #keyPath(Ship.status))
+                
+            } else {
+                
+                fields.forEach { $0?.slotItemID = nil }
+                
+                damageView.damageType = 0
+            }
         }
     }
     
@@ -120,13 +126,6 @@ final class ShipDetailViewController: NSViewController {
         
         damageView.setFrameOrigin(.zero)
         view.addSubview(damageView)
-        damageView.bind(NSBindingName(#keyPath(DamageView.damageType)),
-                        to: shipController,
-                        withKeyPath: "selection.status", options: nil)
-        
-        supply.bind(NSBindingName(#keyPath(SuppliesView.ship)),
-                    to: shipController,
-                    withKeyPath: "selection.self", options: nil)
         
         guardEscapedView.setFrameOrigin(.zero)
         view.addSubview(guardEscapedView)
@@ -137,99 +136,43 @@ final class ShipDetailViewController: NSViewController {
         default: break
         }
         
-        let fields = [slot00Field, slot01Field, slot02Field, slot03Field]
-        let keypath = ["selection.slot_0", "selection.slot_1", "selection.slot_2", "selection.slot_3"]
-        zip(fields, keypath).forEach {
-            
-            $0.0?.bind(NSBindingName(#keyPath(SlotItemLevelView.slotItemID)), to: shipController, withKeyPath: $0.1, options: nil)
-        }
-        
-        // observe slotitems count
-        shipController.addObserver(self, forKeyPath: "selection", context: &shipContext)
-        
-        shipController.addObserver(self, forKeyPath: "selection.slot_0", context: &equippedItem0Context)
-        shipController.addObserver(self, forKeyPath: "selection.onslot_0", context: &equippedItem0Context)
-        shipController.addObserver(self, forKeyPath: "selection.master_ship.maxeq_0", context: &equippedItem0Context)
-        
-        shipController.addObserver(self, forKeyPath: "selection.slot_1", context: &equippedItem1Context)
-        shipController.addObserver(self, forKeyPath: "selection.onslot_1", context: &equippedItem1Context)
-        shipController.addObserver(self, forKeyPath: "selection.master_ship.maxeq_1", context: &equippedItem1Context)
-        
-        shipController.addObserver(self, forKeyPath: "selection.slot_2", context: &equippedItem2Context)
-        shipController.addObserver(self, forKeyPath: "selection.onslot_2", context: &equippedItem2Context)
-        shipController.addObserver(self, forKeyPath: "selection.master_ship.maxeq_2", context: &equippedItem2Context)
+    }
+}
+
+extension ShipDetailViewController: ShipSlotObserverDelegate {
+    
+    func didChangeSlot0() {
         
-        shipController.addObserver(self, forKeyPath: "selection.slot_3", context: &equippedItem3Context)
-        shipController.addObserver(self, forKeyPath: "selection.onslot_3", context: &equippedItem3Context)
-        shipController.addObserver(self, forKeyPath: "selection.master_ship.maxeq_3", context: &equippedItem3Context)
+        notifyChangeValue(forKey: #keyPath(planeString0))
+        notifyChangeValue(forKey: #keyPath(planeString0Color))
+    }
+    
+    func didChangeSlot1() {
         
-        shipController.addObserver(self, forKeyPath: "selection.slot_4", context: &equippedItem4Context)
-        shipController.addObserver(self, forKeyPath: "selection.onslot_4", context: &equippedItem4Context)
-        shipController.addObserver(self, forKeyPath: "selection.master_ship.maxeq_4", context: &equippedItem4Context)
+        notifyChangeValue(forKey: #keyPath(planeString1))
+        notifyChangeValue(forKey: #keyPath(planeString1Color))
+    }
+    
+    func didChangeSlot2() {
         
+        notifyChangeValue(forKey: #keyPath(planeString2))
+        notifyChangeValue(forKey: #keyPath(planeString2Color))
     }
     
-    override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
+    func didChangeSlot3() {
         
-        if context == &shipContext {
-            
-            notifyChangeValue(forKey: #keyPath(planeString0))
-            notifyChangeValue(forKey: #keyPath(planeString0Color))
-            notifyChangeValue(forKey: #keyPath(planeString1))
-            notifyChangeValue(forKey: #keyPath(planeString1Color))
-            notifyChangeValue(forKey: #keyPath(planeString2))
-            notifyChangeValue(forKey: #keyPath(planeString2Color))
-            notifyChangeValue(forKey: #keyPath(planeString3))
-            notifyChangeValue(forKey: #keyPath(planeString3Color))
-            notifyChangeValue(forKey: #keyPath(planeString4))
-            notifyChangeValue(forKey: #keyPath(planeString4Color))
-            
-            return
-        }
-        if context == &equippedItem0Context {
-            
-            notifyChangeValue(forKey: #keyPath(planeString0))
-            notifyChangeValue(forKey: #keyPath(planeString0Color))
-            
-            return
-        }
-        if context == &equippedItem1Context {
-            
-            notifyChangeValue(forKey: #keyPath(planeString1))
-            notifyChangeValue(forKey: #keyPath(planeString1Color))
-            
-            return
-        }
-        if context == &equippedItem2Context {
-            
-            notifyChangeValue(forKey: #keyPath(planeString2))
-            notifyChangeValue(forKey: #keyPath(planeString2Color))
-            
-            return
-        }
-        if context == &equippedItem3Context {
-            
-            notifyChangeValue(forKey: #keyPath(planeString3))
-            notifyChangeValue(forKey: #keyPath(planeString3Color))
-            
-            return
-        }
-        if context == &equippedItem4Context {
-            
-            notifyChangeValue(forKey: #keyPath(planeString4))
-            notifyChangeValue(forKey: #keyPath(planeString4Color))
-            
-            return
-        }
+        notifyChangeValue(forKey: #keyPath(planeString3))
+        notifyChangeValue(forKey: #keyPath(planeString3Color))
+    }
+    
+    func didChangeSlot4() {
         
-        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
+        notifyChangeValue(forKey: #keyPath(planeString4))
+        notifyChangeValue(forKey: #keyPath(planeString4Color))
     }
 }
 
-
 private let allPlaneTypes: [Int] = [6, 7, 8, 9, 10, 11, 25, 26, 41, 45, 56, 57, 58, 59]
-
-
 extension ShipDetailViewController {
     
     // MARK: - Plane count strings
@@ -262,23 +205,16 @@ extension ShipDetailViewController {
     private func planeString(_ index: Int) -> String? {
         
         switch planState(index) {
-        case .cannotEquip:
-            return nil
-        case .notEquip(let max):
-            return "\(max)"
-        case .equiped(let count, let max):
-            return "\(count)/\(max)"
+        case .cannotEquip: return nil
+        case .notEquip(let max): return "\(max)"
+        case .equiped(let count, let max): return "\(count)/\(max)"
         }
     }
     
     @objc dynamic var planeString0: String? { return planeString(0) }
-    
     @objc dynamic var planeString1: String? { return planeString(1) }
-    
     @objc dynamic var planeString2: String? { return planeString(2) }
-    
     @objc dynamic var planeString3: String? { return planeString(3) }
-    
     @objc dynamic var planeString4: String? { return planeString(4) }
     
     // MARK: - Plane count string color
@@ -292,13 +228,9 @@ extension ShipDetailViewController {
     }
     
     @objc dynamic var planeString0Color: NSColor { return planeStringColor(0) }
-    
     @objc dynamic var planeString1Color: NSColor { return planeStringColor(1) }
-    
     @objc dynamic var planeString2Color: NSColor { return planeStringColor(2) }
-    
     @objc dynamic var planeString3Color: NSColor { return planeStringColor(3) }
-    
     @objc dynamic var planeString4Color: NSColor { return planeStringColor(4) }
 }
 
index 179bfdf..a59f27a 100644 (file)
@@ -8,22 +8,30 @@
 
 import Cocoa
 
-protocol ShipSlotObserving: class {
+protocol ShipSlotObserverDelegate: class {
     
-    func didCangeSlot0()
-    func didCangeSlot1()
-    func didCangeSlot2()
-    func didCangeSlot3()
-    func didCangeSlot4()
+    func didChangeSlot0()
+    func didChangeSlot1()
+    func didChangeSlot2()
+    func didChangeSlot3()
+    func didChangeSlot4()
 }
 
 class ShipSlotObserver: NSObject {
     
-    let ship: Ship
+    private enum SlotPosition {
+        case first
+        case second
+        case third
+        case fourth
+        case fifth
+    }
+    
+    private let ship: Ship
     
-    weak var delegate: ShipSlotObserving?
+    weak var delegate: ShipSlotObserverDelegate?
     
-    var observations: [NSKeyValueObservation] = []
+    private var observations: [NSKeyValueObservation] = []
     
     init(ship: Ship) {
         
@@ -31,68 +39,43 @@ class ShipSlotObserver: NSObject {
         
         super.init()
         
-        let s0 = ship.observe(\.slot_0) { (_, _) in
-            
-            self.delegate?.didCangeSlot0()
-        }
-        observations.append(s0)
-        
-        let s1 = ship.observe(\.slot_1) { (_, _) in
-            
-            self.delegate?.didCangeSlot1()
-        }
-        observations.append(s1)
-        
-        let s2 = ship.observe(\.slot_2) { (_, _) in
-            
-            self.delegate?.didCangeSlot2()
-        }
-        observations.append(s2)
-        
-        let s3 = ship.observe(\.slot_3) { (_, _) in
-            
-            self.delegate?.didCangeSlot3()
-        }
-        observations.append(s3)
-        
-        let s4 = ship.observe(\.slot_4) { (_, _) in
-            
-            self.delegate?.didCangeSlot4()
-        }
-        observations.append(s4)
-        
+        observeSlot()
+        observeOnSlot()
+    }
+    
+    private func observeSlot() {
         
-        let o0 = ship.observe(\.onslot_0) { (_, _) in
-            
-            self.delegate?.didCangeSlot0()
-        }
-        observations.append(o0)
+        let keyPaths = [\Ship.slot_0, \Ship.slot_1, \Ship.slot_2, \Ship.slot_3, \Ship.slot_4]
+        observe(keyPaths: keyPaths)
+    }
+    
+    private func observeOnSlot() {
         
-        let o1 = ship.observe(\.onslot_1) { (_, _) in
-            
-            self.delegate?.didCangeSlot1()
-        }
-        observations.append(o1)
+        let keyPaths = [\Ship.onslot_0, \Ship.onslot_1, \Ship.onslot_2, \Ship.onslot_3, \Ship.onslot_4]
+        observe(keyPaths: keyPaths)
+    }
+    
+    private func observe(keyPaths: [KeyPath<Ship, Int>]) {
         
-        let o2 = ship.observe(\.onslot_2) { (_, _) in
-            
-            self.delegate?.didCangeSlot2()
-        }
-        observations.append(o2)
+        let positions: [SlotPosition] = [.first, .second, .third, .fourth, .fifth]
         
-        let o3 = ship.observe(\.onslot_3) { (_, _) in
-            
-            self.delegate?.didCangeSlot3()
+        observations += zip(keyPaths, positions)
+            .map { [weak self] keyPath, position in
+                ship.observe(keyPath) { _, _ in
+                    self?.notifyChange(on: position)
+                }
         }
-        observations.append(o3)
+    }
+    
+    private func notifyChange(on position: SlotPosition) {
         
-        let o4 = ship.observe(\.onslot_4) { (_, _) in
+        switch position {
             
-            self.delegate?.didCangeSlot4()
+        case .first: delegate?.didChangeSlot0()
+        case .second: delegate?.didChangeSlot1()
+        case .third: delegate?.didChangeSlot2()
+        case .fourth: delegate?.didChangeSlot3()
+        case .fifth: delegate?.didChangeSlot4()
         }
-        observations.append(o4)
-        
     }
-
-    
 }