OSDN Git Service

Doutaku を 1.0 にアップデート
[kcd/KCD.git] / KCD / SlotItemMapper.swift
1 //
2 //  SlotItemMapper.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/02/25.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10 import SwiftyJSON
11
12 final class SlotItemMapper: JSONMapper {
13         
14     let apiResponse: APIResponse
15     let configuration: MappingConfiguration<SlotItem>
16     
17     required init(_ apiResponse: APIResponse) {
18         
19         self.apiResponse = apiResponse
20         self.configuration = MappingConfiguration(entity: SlotItem.self,
21                                                   dataKeys: SlotItemMapper.dataKeys(apiResponse),
22                                                   editorStore: ServerDataStore.oneTimeEditor())
23     }
24     
25     private class func dataKeys(_ apiResponse: APIResponse) -> [String] {
26         
27         switch apiResponse.api.endpoint {
28             
29         case .getShip: return ["api_data", "api_slotitem"]
30             
31         case .requireInfo: return ["api_data", "api_slot_item"]
32             
33         case .slotItem: return ["api_data"]
34             
35         default:
36             
37             Logger.shared.log("Missing API: \(apiResponse.api)")
38             
39             return ["api_data"]
40             
41         }
42     }
43     
44     private var registerIds: [Int] = []
45     private lazy var masterSlotItems: [MasterSlotItem] = {
46         
47         guard let store = configuration.editorStore as? ServerDataStore else {
48             
49             return []
50         }
51         
52         return store.sortedMasterSlotItemsById()
53     }()
54     
55     func beginRegister(_ slotItem: SlotItem) {
56         
57         slotItem.alv = 0
58     }
59     
60     func handleExtraValue(_ value: JSON, forKey key: String, to object: SlotItem) -> Bool {
61         
62         // 取得後破棄した装備のデータを削除するため保有IDを保存
63         if key == "api_id" {
64             
65             guard let id = value.int else {
66                 
67                 return false
68             }
69             
70             registerIds.append(id)
71             
72             return false
73         }
74         
75         if key == "api_slotitem_id" {
76             
77             guard let id = value.int else {
78                 
79                 return false
80             }
81             
82             setMaster(id, to: object)
83             
84             return true
85         }
86         
87         return false
88     }
89     
90     func finishOperating() {
91         
92         // getshipの時は取得した艦娘の装備のみのデータのため無視
93         if apiResponse.api.endpoint == .getShip {
94             
95             return
96         }
97         
98         guard let store = configuration.editorStore as? ServerDataStore else {
99             
100             return
101         }
102         
103         store.slotItems(exclude: registerIds).forEach(store.delete)
104     }
105     
106     private func setMaster(_ masterId: Int, to slotItem: SlotItem?) {
107         
108         guard let slotItem = slotItem else {
109             
110             return
111         }
112         
113         if slotItem.slotitem_id == masterId {
114             
115             return
116         }
117         
118         guard let mSlotItem = masterSlotItems.binarySearch(comparator: { $0.id ==? masterId }) else {
119             
120             Logger.shared.log("Can not find MasterSlotItem")
121             
122             return
123         }
124         
125         // FUCK: 型推論がバカなのでダウンキャストしてるんだ!!!
126         guard let masterSlotItem = configuration.editorStore.exchange(mSlotItem) as? MasterSlotItem else {
127             
128             Logger.shared.log("Can not convert to current moc object")
129             
130             return
131         }
132         
133         slotItem.master_slotItem = masterSlotItem
134         slotItem.slotitem_id = masterId
135     }
136 }