OSDN Git Service

containsを多用するArrayのうちSetに置換可能なものをSetに変更
[kcd/KCD.git] / KCD / ShipMapper.swift
index 47e84f5..64398df 100644 (file)
@@ -11,14 +11,14 @@ import SwiftyJSON
 
 final class ShipMapper: JSONMapper {
     
-    private static let ignoreKeys = ["api_gomes", "api_gomes2", "api_broken", "api_powup",
-                                     "api_voicef", "api_afterlv", "api_aftershipid", "api_backs",
-                                     "api_slotnum", "api_stype", "api_name", "api_yomi",
-                                     "api_raig", "api_luck", "api_saku", "api_raim", "api_baku",
-                                     "api_taik", "api_houg", "api_houm", "api_tyku",
-                                     "api_ndock_item", "api_star",
-                                     "api_ndock_time_str", "api_member_id",
-                                     "api_fuel_max", "api_bull_max"]
+    private static let ignoreKeys: Set<String> = ["api_gomes", "api_gomes2", "api_broken", "api_powup",
+                                                  "api_voicef", "api_afterlv", "api_aftershipid", "api_backs",
+                                                  "api_slotnum", "api_stype", "api_name", "api_yomi",
+                                                  "api_raig", "api_luck", "api_saku", "api_raim", "api_baku",
+                                                  "api_taik", "api_houg", "api_houm", "api_tyku",
+                                                  "api_ndock_item", "api_star",
+                                                  "api_ndock_time_str", "api_member_id",
+                                                  "api_fuel_max", "api_bull_max"]
     
     let apiResponse: APIResponse
     let configuration: MappingConfiguration<Ship>
@@ -26,7 +26,7 @@ final class ShipMapper: JSONMapper {
     required init(_ apiResponse: APIResponse) {
         
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entity: Ship.entity,
+        self.configuration = MappingConfiguration(entity: Ship.self,
                                                   dataKeys: ShipMapper.dataKeys(apiResponse),
                                                   editorStore: ServerDataStore.oneTimeEditor(),
                                                   ignoreKeys: ShipMapper.ignoreKeys)
@@ -36,7 +36,7 @@ final class ShipMapper: JSONMapper {
     init(forSlotDepriveUnset apiResponse: APIResponse) {
         
         self.apiResponse = apiResponse
-        self.configuration = MappingConfiguration(entity: Ship.entity,
+        self.configuration = MappingConfiguration(entity: Ship.self,
                                                   dataKeys: ["api_data", "api_ship_data", "api_unset_ship"],
                                                   editorStore: ServerDataStore.oneTimeEditor(),
                                                   ignoreKeys: ShipMapper.ignoreKeys)
@@ -52,30 +52,54 @@ final class ShipMapper: JSONMapper {
             
         case .slotDeprive: return ["api_data", "api_ship_data", "api_set_ship"]
             
-        case .ship: return ["api_data"]
+        case .ship, .ship2: return ["api_data"]
             
-        default: return Logger.shared.log("Missing API: \(apiResponse.api)", value: ["api_data"])
+        default:
+            
+            Logger.shared.log("Missing API: \(apiResponse.api)")
+            
+            return ["api_data"]
         }
     }
     
     private var registerIds: [Int] = []
     private lazy var masterShips: [MasterShip] = {
         
-        return ServerDataStore.default.sortedMasterShipsById()
+        guard let store = configuration.editorStore as? ServerDataStore else {
+            
+            return []
+        }
+        
+        return store.sortedMasterShipsById()
+        
     }()
     private lazy var slotItems: [SlotItem] = {
         
-        return ServerDataStore.default.sortedSlotItemsById()
+        guard let store = configuration.editorStore as? ServerDataStore else {
+            
+            return []
+        }
+        
+        return store.sortedSlotItemsById()
     }()
+    
     private var needsDeleteUnregisteredShip: Bool {
         
         switch apiResponse.api.endpoint {
-        case .ship3, .getShip, .shipDeck,
-             .powerup, .slotDeprive:
+            
+        case .ship3, .getShip, .shipDeck, .powerup, .slotDeprive:
+            
             return false
             
+        case .ship2:
+            // 特殊任務のクリア時にship2がapi_shipid付きでリクエストされ、その艦娘のデータしかない時があるため
+            
+            return !apiResponse.parameter["api_shipid"].valid
+            
         default:
+            
             return true
+            
         }
     }
     
@@ -94,7 +118,10 @@ final class ShipMapper: JSONMapper {
         // 取得後破棄した装備のデータを削除するため保有IDを保存
         if key == "api_id" {
             
-            guard let id = value.int else { return false }
+            guard let id = value.int else {
+                
+                return false
+            }
             
             registerIds.append(id)
             
@@ -103,7 +130,15 @@ final class ShipMapper: JSONMapper {
         
         if key == "api_ship_id" {
             
-            guard let masterId = value.int else { return false }
+            guard let masterId = value.int else {
+                
+                return false
+            }
+            
+            if ship.ship_id == masterId {
+                
+                return true
+            }
             
             setMaster(masterId, to: ship)
             
@@ -112,7 +147,15 @@ final class ShipMapper: JSONMapper {
         
         if key == "api_exp" {
             
-            guard let exp = value[0].int else { return false }
+            guard let exp = value[0].int else {
+                
+                return false
+            }
+            
+            if ship.exp == exp {
+                
+                return true
+            }
             
             ship.exp = exp
             
@@ -128,11 +171,23 @@ final class ShipMapper: JSONMapper {
         
         if key == "api_slot_ex" {
             
-            guard let ex = value.int else { return false }
+            guard let ex = value.int else {
+                
+                ship.extraItem = nil
+                
+                return false
+            }
+            
+            if ship.slot_ex == ex {
+                
+                return true
+            }
             
             setExtraSlot(ex, to: ship)
             
-            return false
+            ship.slot_ex = ex
+            
+            return true
         }
         
         return false
@@ -140,19 +195,22 @@ final class ShipMapper: JSONMapper {
     
     func finishOperating() {
         
-        if !needsDeleteUnregisteredShip { return }
+        if !needsDeleteUnregisteredShip {
+            
+            return
+        }
         
         store?.ships(exclude: registerIds).forEach { store?.delete($0) }
     }
     
     private func setMaster(_ masterId: Int, to ship: Ship) {
         
-        if ship.ship_id == masterId { return }
-        
         guard let mShip = masterShips.binarySearch(comparator: { $0.id ==? masterId }),
-            let masterShip = store?.object(of: MasterShip.entity, with: mShip.objectID) else {
+            let masterShip = store?.exchange(mShip) else {
+                
+                Logger.shared.log("Can not convert to current moc object masterShip")
                 
-                return Logger.shared.log("Can not convert to current moc object masterShip")
+                return
         }
         
         ship.master_ship = masterShip
@@ -161,24 +219,31 @@ final class ShipMapper: JSONMapper {
     
     private func setSlot(_ slotItems: JSON, to ship: Ship) {
         
-        guard let converSlotItems = slotItems.arrayObject as? [Int] else { return }
-        guard let store = store else { return }
+        guard let convertedSlotItems = slotItems.arrayObject as? [Int] else {
+            
+            return
+        }
+        guard let store = store else {
+            
+            return
+        }
         
-        let newItems: [SlotItem] =
-            converSlotItems.flatMap { item in
-                
-                if item == 0 || item == -1 { return nil }
+        let newItems: [SlotItem] = convertedSlotItems
+            .filter { $0 != 0 && $0 != -1 }
+            .compactMap { item in
                 
                 guard let found = self.slotItems.binarySearch(comparator: { $0.id ==? item }),
-                    let slotItem = store.object(of: SlotItem.entity, with: found.objectID) else {
+                    let slotItem = store.exchange(found) else {
                         
-                        let maxV = converSlotItems.last
+                        let maxV = convertedSlotItems.last
                         if maxV != nil, maxV! < item {
                             
                             Debug.print("item is maybe unregistered, so it is new ship's equipment.")
+                            
                             return nil
                         }
                         Logger.shared.log("Can not convert to current moc object slotItem")
+                        
                         return nil
                 }
                 
@@ -190,11 +255,18 @@ final class ShipMapper: JSONMapper {
     
     private func setExtraSlot(_ exSlotItem: Int, to ship: Ship) {
         
-        guard exSlotItem != -1, exSlotItem != 0 else { return }
+        guard exSlotItem != -1, exSlotItem != 0 else {
+            
+            ship.extraItem = nil
+            
+            return
+        }
         guard let found = slotItems.binarySearch(comparator: { $0.id ==? exSlotItem }),
-            let ex = store?.object(of: SlotItem.entity, with: found.objectID) else {
+            let ex = store?.exchange(found) else {
+                
+                Logger.shared.log("Can not convert to current moc object")
                 
-                return Logger.shared.log("Can not convert to current moc object")
+                return
         }
         
         ship.extraItem = ex