OSDN Git Service

Doutakuを導入
[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.entity,
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: return Logger.shared.log("Missing API: \(apiResponse.api)", value: ["api_data"])
36         }
37     }
38     
39     private var registerIds: [Int] = []
40     private lazy var masterSlotItems: [MasterSlotItem] = {
41         
42         guard let store = configuration.editorStore as? ServerDataStore else { return [] }
43         
44         return store.sortedMasterSlotItemsById()
45     }()
46     
47     func beginRegister(_ slotItem: SlotItem) {
48         
49         slotItem.alv = 0
50     }
51     
52     func handleExtraValue(_ value: JSON, forKey key: String, to object: SlotItem) -> Bool {
53         
54         // 取得後破棄した装備のデータを削除するため保有IDを保存
55         if key == "api_id" {
56             
57             guard let id = value.int else { return false }
58             
59             registerIds.append(id)
60             
61             return false
62         }
63         
64         if key == "api_slotitem_id" {
65             
66             guard let id = value.int else { return false }
67             
68             setMaster(id, to: object)
69             
70             return true
71         }
72         
73         return false
74     }
75     
76     func finishOperating() {
77         
78         // getshipの時は取得した艦娘の装備のみのデータのため無視
79         if apiResponse.api.endpoint == .getShip {
80             
81             return
82         }
83         
84         guard let store = configuration.editorStore as? ServerDataStore else { return }
85         
86         store.slotItems(exclude: registerIds).forEach(store.delete)
87     }
88     
89     private func setMaster(_ masterId: Int, to slotItem: SlotItem?) {
90         
91         guard let slotItem = slotItem else { return }
92         
93         if slotItem.slotitem_id == masterId { return }
94         
95         guard let mSlotItem = masterSlotItems.binarySearch(comparator: { $0.id ==? masterId }) else {
96             
97             return Logger.shared.log("Can not find MasterSlotItem")
98         }
99         
100         // FUCK: 型推論がバカなのでダウンキャストしてるんだ!!!
101         guard let masterSlotItem = configuration.editorStore.exchange(mSlotItem) as? MasterSlotItem else {
102                 
103                 return Logger.shared.log("Can not convert to current moc object")
104         }
105         
106         slotItem.master_slotItem = masterSlotItem
107         slotItem.slotitem_id = masterId
108     }
109 }