main code repository.
リビジョン | 56d226ff8dd05b4a50b9e2c8d5a22b13b8c8249b (tree) |
---|---|
日時 | 2018-03-18 10:40:33 |
作者 | masakih <masakih@user...> |
コミッター | masakih |
CoreDataのスレッドを使用するように修正
@@ -22,7 +22,8 @@ final class AirCorpsChangeNameCommand: JSONCommand { | ||
22 | 22 | guard let name = parameter["api_name"].string else { return } |
23 | 23 | |
24 | 24 | let store = ServerDataStore.oneTimeEditor() |
25 | - | |
26 | - store.airBase(area: areaId, base: rId)?.name = name | |
25 | + store.async { | |
26 | + store.airBase(area: areaId, base: rId)?.name = name | |
27 | + } | |
27 | 28 | } |
28 | 29 | } |
@@ -18,37 +18,39 @@ final class AirCorpsSupplyCommand: JSONCommand { | ||
18 | 18 | override func execute() { |
19 | 19 | |
20 | 20 | let store = ServerDataStore.oneTimeEditor() |
21 | - | |
22 | - guard let areaId = parameter["api_area_id"].int else { return } | |
23 | - guard let rId = parameter["api_base_id"].int else { return } | |
24 | - guard let airBase = store.airBase(area: areaId, base: rId) else { return } | |
25 | - | |
26 | - let planeInfos = data["api_plane_info"] | |
27 | - let planes = airBase.planeInfo | |
28 | - | |
29 | - parameter["api_squadron_id"] | |
30 | - .integerArray | |
31 | - .enumerated() | |
32 | - .forEach { | |
33 | - | |
34 | - guard planes.count >= $0.element else { return } | |
35 | - guard planeInfos.count > $0.offset else { return } | |
36 | - guard let plane = planes[$0.element - 1] as? AirBasePlaneInfo else { return } | |
37 | - | |
38 | - let planeInfo = planeInfos[$0.offset] | |
39 | - | |
40 | - if let v = planeInfo["api_cond"].int { plane.cond = v } | |
41 | - if let v = planeInfo["api_slotid"].int { plane.slotid = v } | |
42 | - if let v = planeInfo["api_state"].int { plane.state = v } | |
43 | - if let v = planeInfo["api_count"].int { plane.count = v } | |
44 | - if let v = planeInfo["api_max_count"].int { plane.max_count = v } | |
21 | + store.async { | |
22 | + | |
23 | + guard let areaId = self.parameter["api_area_id"].int else { return } | |
24 | + guard let rId = self.parameter["api_base_id"].int else { return } | |
25 | + guard let airBase = store.airBase(area: areaId, base: rId) else { return } | |
26 | + | |
27 | + let planeInfos = self.data["api_plane_info"] | |
28 | + let planes = airBase.planeInfo | |
29 | + | |
30 | + self.parameter["api_squadron_id"] | |
31 | + .integerArray | |
32 | + .enumerated() | |
33 | + .forEach { | |
34 | + | |
35 | + guard planes.count >= $0.element else { return } | |
36 | + guard planeInfos.count > $0.offset else { return } | |
37 | + guard let plane = planes[$0.element - 1] as? AirBasePlaneInfo else { return } | |
38 | + | |
39 | + let planeInfo = planeInfos[$0.offset] | |
40 | + | |
41 | + if let v = planeInfo["api_cond"].int { plane.cond = v } | |
42 | + if let v = planeInfo["api_slotid"].int { plane.slotid = v } | |
43 | + if let v = planeInfo["api_state"].int { plane.state = v } | |
44 | + if let v = planeInfo["api_count"].int { plane.count = v } | |
45 | + if let v = planeInfo["api_max_count"].int { plane.max_count = v } | |
46 | + } | |
47 | + | |
48 | + if let v = self.data["api_distance"].int { airBase.distance = v } | |
49 | + | |
50 | + guard let material = store.material() else { return } | |
51 | + | |
52 | + if let v = self.data["api_after_bauxite"].int { material.bauxite = v } | |
53 | + if let v = self.data["api_after_fuel"].int { material.fuel = v } | |
45 | 54 | } |
46 | - | |
47 | - if let v = data["api_distance"].int { airBase.distance = v } | |
48 | - | |
49 | - guard let material = store.material() else { return } | |
50 | - | |
51 | - if let v = data["api_after_bauxite"].int { material.bauxite = v } | |
52 | - if let v = data["api_after_fuel"].int { material.fuel = v } | |
53 | 55 | } |
54 | 56 | } |
@@ -55,12 +55,13 @@ final class AnchorageRepairManager: NSObject { | ||
55 | 55 | |
56 | 56 | let ship = fleetManager?.fleets[fleetNumber - 1][position] |
57 | 57 | |
58 | - return ship?.master_ship.stype.id | |
58 | + return ServerDataStore.default.sync { ship?.master_ship.stype.id } | |
59 | 59 | } |
60 | 60 | |
61 | 61 | private func shipTypeId(shipId: Int) -> Int? { |
62 | 62 | |
63 | - return ServerDataStore.default.ship(by: shipId)?.master_ship.stype.id | |
63 | + let store = ServerDataStore.default | |
64 | + return store.sync { store.ship(by: shipId)?.master_ship.stype.id } | |
64 | 65 | } |
65 | 66 | |
66 | 67 | private func needsReset(info: HenseiDidChangeUserInfo) -> Bool { |
@@ -18,19 +18,22 @@ final class ApplySuppliesCommand: JSONCommand { | ||
18 | 18 | .forEach { (_, json) in |
19 | 19 | |
20 | 20 | guard let i = json["api_id"].int else { return } |
21 | - guard let ship = store.ship(by: i) else { return } | |
21 | + guard let ship = store.sync(execute: { store.ship(by: i) }) else { return } | |
22 | 22 | guard let bull = json["api_bull"].int else { return } |
23 | 23 | guard let fuel = json["api_fuel"].int else { return } |
24 | 24 | guard let slots = json["api_onslot"].arrayObject as? [Int] else { return } |
25 | 25 | guard slots.count > 4 else { return } |
26 | 26 | |
27 | - ship.bull = bull | |
28 | - ship.fuel = fuel | |
29 | - ship.onslot_0 = slots[0] | |
30 | - ship.onslot_1 = slots[1] | |
31 | - ship.onslot_2 = slots[2] | |
32 | - ship.onslot_3 = slots[3] | |
33 | - ship.onslot_4 = slots[4] | |
27 | + store.sync { | |
28 | + | |
29 | + ship.bull = bull | |
30 | + ship.fuel = fuel | |
31 | + ship.onslot_0 = slots[0] | |
32 | + ship.onslot_1 = slots[1] | |
33 | + ship.onslot_2 = slots[2] | |
34 | + ship.onslot_3 = slots[3] | |
35 | + ship.onslot_4 = slots[4] | |
36 | + } | |
34 | 37 | } |
35 | 38 | } |
36 | 39 | } |
@@ -35,11 +35,14 @@ final class BasicMapper: JSONMapper { | ||
35 | 35 | |
36 | 36 | func commit() { |
37 | 37 | |
38 | - let store = ServerDataStore.oneTimeEditor() | |
38 | + configuration.editorStore.async(execute: commintInContext) | |
39 | + } | |
40 | + private func commintInContext() { | |
39 | 41 | |
40 | - guard let basic = store.basic() ?? store.createBasic() else { | |
41 | - | |
42 | - return Logger.shared.log("Can not Get Basic") | |
42 | + guard let store = configuration.editorStore as? ServerDataStore, | |
43 | + let basic = store.basic() ?? store.createBasic() else { | |
44 | + | |
45 | + return Logger.shared.log("Can not Get Basic") | |
43 | 46 | } |
44 | 47 | |
45 | 48 | registerElement(data, to: basic) |
@@ -149,20 +149,25 @@ extension BookmarkListViewController: NSTableViewDelegate, NSTableViewDataSource | ||
149 | 149 | guard let items = info.draggingPasteboard().pasteboardItems else { return false } |
150 | 150 | |
151 | 151 | let store = BookmarkManager.shared.editorStore |
152 | - items.enumerated().forEach { | |
152 | + store.sync { | |
153 | + items.enumerated().forEach { | |
154 | + | |
155 | + guard let data = $0.element.data(forType: .bookmarkItem) else { return } | |
156 | + guard let uri = NSKeyedUnarchiver.unarchiveObject(with: data) as? URL else { return } | |
157 | + guard let oID = self.managedObjectContext.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: uri) else { return } | |
158 | + guard let bookmark = store.object(of: Bookmark.entity, with: oID) else { return } | |
159 | + | |
160 | + bookmark.order = targetOrder + $0.offset + 1 | |
161 | + } | |
153 | 162 | |
154 | - guard let data = $0.element.data(forType: .bookmarkItem) else { return } | |
155 | - guard let uri = NSKeyedUnarchiver.unarchiveObject(with: data) as? URL else { return } | |
156 | - guard let oID = managedObjectContext.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: uri) else { return } | |
157 | - guard let bookmark = store.object(of: Bookmark.entity, with: oID) else { return } | |
163 | + store.save(errorHandler: store.presentOnMainThread) | |
158 | 164 | |
159 | - bookmark.order = targetOrder + $0.offset + 1 | |
165 | + self.bookmarkController.rearrangeObjects() | |
166 | + self.reorderingBoolmarks() | |
167 | + self.bookmarkController.rearrangeObjects() | |
160 | 168 | } |
161 | 169 | |
162 | - store.save(errorHandler: store.presentOnMainThread) | |
163 | - bookmarkController.rearrangeObjects() | |
164 | - reorderingBoolmarks() | |
165 | - bookmarkController.rearrangeObjects() | |
170 | + tableView.reloadData() | |
166 | 171 | |
167 | 172 | return true |
168 | 173 | } |
@@ -51,27 +51,36 @@ final class BookmarkManager: NSObject, NSMenuDelegate { | ||
51 | 51 | return items |
52 | 52 | } |
53 | 53 | |
54 | - func createNewBookmark() -> Bookmark? { | |
54 | + func createNewBookmark(configurator: @escaping (Bookmark) -> Bool) -> Bookmark? { | |
55 | 55 | |
56 | 56 | guard let maxOrder = bookmarksController.value(forKeyPath: "arrangedObjects.@max.order") as? Int else { |
57 | 57 | |
58 | 58 | return Logger.shared.log("BookmarkManager: Can no convert max order to Int", value: nil) |
59 | 59 | } |
60 | 60 | |
61 | - guard let new = editorStore.createBookmark() else { | |
61 | + let editorStore: BookmarkDataStore = BookmarkDataStore.oneTimeEditor() | |
62 | + | |
63 | + guard let new = editorStore.sync(execute: { editorStore.createBookmark() }) else { | |
62 | 64 | |
63 | 65 | return Logger.shared.log("BookmarkManager: Can not insert BookMarkItem", value: nil) |
64 | 66 | } |
65 | 67 | |
66 | - new.identifier = String(format: "B%@", arguments: [NSDate()]) | |
67 | - new.order = maxOrder + 100 | |
68 | - | |
69 | - DispatchQueue.main.asyncAfter(deadline: .now()) { | |
68 | + return editorStore.sync { | |
69 | + | |
70 | + new.identifier = String(format: "B%@", arguments: [NSDate()]) | |
71 | + new.order = maxOrder + 100 | |
70 | 72 | |
71 | - self.editorStore.save(errorHandler: self.editorStore.presentOnMainThread) | |
73 | + if !configurator(new) { | |
74 | + | |
75 | + editorStore.delete(new) | |
76 | + | |
77 | + return nil | |
78 | + } | |
79 | + | |
80 | + editorStore.save(errorHandler: editorStore.presentOnMainThread) | |
81 | + | |
82 | + return new | |
72 | 83 | } |
73 | - | |
74 | - return new | |
75 | 84 | } |
76 | 85 | |
77 | 86 | func menuNeedsUpdate(_ menu: NSMenu) { |
@@ -194,7 +194,7 @@ extension BroserWindowController { | ||
194 | 194 | @IBAction func clearQuestList(_ sender: AnyObject?) { |
195 | 195 | |
196 | 196 | let store = ServerDataStore.oneTimeEditor() |
197 | - store.quests().forEach(store.delete) | |
197 | + store.sync { store.quests().forEach(store.delete) } | |
198 | 198 | } |
199 | 199 | |
200 | 200 | // call from menu item |
@@ -111,54 +111,65 @@ extension CalculateDamageCommand { | ||
111 | 111 | |
112 | 112 | let store = TemporaryDataStore.oneTimeEditor() |
113 | 113 | |
114 | - store.damages().forEach(store.delete) | |
114 | + store.sync { store.damages().forEach(store.delete) } | |
115 | 115 | } |
116 | 116 | |
117 | 117 | func applyDamage() { |
118 | 118 | |
119 | 119 | let store = TemporaryDataStore.oneTimeEditor() |
120 | 120 | |
121 | - let totalDamages = store.sortedDamagesById() | |
121 | + let totalDamages = store.sync { store.sortedDamagesById() } | |
122 | 122 | |
123 | - let aStore = ServerDataStore.oneTimeEditor() | |
123 | + let aStore = ServerDataStore.default | |
124 | 124 | |
125 | 125 | Debug.excute(level: .debug) { |
126 | 126 | |
127 | 127 | print("-------") |
128 | 128 | |
129 | - totalDamages.forEach { | |
130 | - | |
131 | - guard let ship = aStore.ship(by: $0.shipID) else { return } | |
132 | - | |
133 | - if ship.nowhp != $0.hp { | |
129 | + store.sync { | |
130 | + totalDamages.forEach { damage in | |
131 | + | |
132 | + let shipId = damage.shipID | |
133 | + guard let ship = aStore.sync(execute: { aStore.ship(by: shipId) }) else { return } | |
134 | 134 | |
135 | - print("\(ship.name)(\(ship.id)),HP \(ship.nowhp) -> \($0.hp)") | |
135 | + let damagedHp = damage.hp | |
136 | + aStore.sync { | |
137 | + if ship.nowhp != damagedHp { | |
138 | + | |
139 | + print("\(ship.name)(\(ship.id)),HP \(ship.nowhp) -> \(damagedHp)") | |
140 | + } | |
141 | + } | |
136 | 142 | } |
137 | 143 | } |
138 | 144 | |
139 | - | |
140 | 145 | print("------- End Battle") |
141 | 146 | } |
142 | 147 | |
143 | 148 | // 第二艦隊単独出撃で正しくデータが反映されるように逆順にして計算 |
144 | - totalDamages.reversed().forEach { | |
145 | - | |
146 | - guard let ship = aStore.ship(by: $0.shipID) else { return } | |
147 | - | |
148 | - ship.nowhp = $0.hp | |
149 | - | |
150 | - if $0.useDamageControl { removeFirstDamageControl(of: ship) } | |
149 | + store.sync { | |
150 | + totalDamages.reversed().forEach { damage in | |
151 | + | |
152 | + let shipId = damage.shipID | |
153 | + guard let ship = aStore.sync(execute: { aStore.ship(by: shipId) }) else { return } | |
154 | + | |
155 | + let damagedHp = damage.hp | |
156 | + aStore.sync { ship.nowhp = damagedHp } | |
157 | + | |
158 | + if damage.useDamageControl { self.removeFirstDamageControl(of: shipId) } | |
159 | + } | |
151 | 160 | } |
152 | - | |
153 | 161 | } |
154 | 162 | |
155 | 163 | func updateBattleCell() { |
156 | 164 | |
157 | 165 | let store = TemporaryDataStore.default |
158 | 166 | |
159 | - guard let battle = store.battle() else { return Logger.shared.log("Battle is invalid.") } | |
167 | + guard let battle = store.sync(execute: { store.battle() }) else { | |
168 | + | |
169 | + return Logger.shared.log("Battle is invalid.") | |
170 | + } | |
160 | 171 | |
161 | - battle.battleCell = (battle.no == 0 ? nil : battle.no as NSNumber) | |
172 | + store.sync { battle.battleCell = (battle.no == 0 ? nil : battle.no as NSNumber) } | |
162 | 173 | |
163 | 174 | Debug.excute(level: .debug) { |
164 | 175 |
@@ -189,22 +200,45 @@ extension CalculateDamageCommand { | ||
189 | 200 | } |
190 | 201 | } |
191 | 202 | |
192 | - func removeFirstDamageControl(of ship: Ship) { | |
203 | + func removeFirstDamageControl(of shipId: Int) { | |
193 | 204 | |
194 | - let store = ServerDataStore.default | |
195 | - | |
196 | - let (item, damageControl) = ship | |
197 | - .equippedItem | |
198 | - .lazy | |
199 | - .flatMap { $0 as? SlotItem } | |
200 | - .map { ($0, store.masterSlotItemID(by: $0.id)) } | |
201 | - .map { ($0.0, DamageControlID(rawValue: $0.1)) } | |
202 | - .filter { $0.1 != nil } | |
203 | - .first ?? (nil, nil) | |
204 | - | |
205 | - if let validDamageControl = damageControl { | |
205 | + let store = ServerDataStore.oneTimeEditor() | |
206 | + store.sync { | |
207 | + | |
208 | + guard let ship = store.ship(by: shipId) else { return } | |
209 | + | |
210 | + let (item, damageControl) = ship | |
211 | + .equippedItem | |
212 | + .lazy | |
213 | + .flatMap { $0 as? SlotItem } | |
214 | + .map { ($0, store.masterSlotItemID(by: $0.id)) } | |
215 | + .map { ($0.0, DamageControlID(rawValue: $0.1)) } | |
216 | + .filter { $0.1 != nil } | |
217 | + .first ?? (nil, nil) | |
206 | 218 | |
207 | - switch validDamageControl { | |
219 | + if let validDamageControl = damageControl { | |
220 | + | |
221 | + switch validDamageControl { | |
222 | + case .damageControl: break | |
223 | + | |
224 | + case .goddes: | |
225 | + ship.fuel = ship.maxFuel | |
226 | + ship.bull = ship.maxBull | |
227 | + } | |
228 | + | |
229 | + guard let equiped = ship.equippedItem.array as? [SlotItem] else { return } | |
230 | + | |
231 | + ship.equippedItem = NSOrderedSet(array: equiped.filter { $0 != item }) | |
232 | + | |
233 | + return | |
234 | + } | |
235 | + | |
236 | + // check extra slot | |
237 | + let exItemId = store.sync { store.masterSlotItemID(by: ship.slot_ex) } | |
238 | + | |
239 | + guard let exType = DamageControlID(rawValue: exItemId) else { return } | |
240 | + | |
241 | + switch exType { | |
208 | 242 | case .damageControl: break |
209 | 243 | |
210 | 244 | case .goddes: |
@@ -212,26 +246,7 @@ extension CalculateDamageCommand { | ||
212 | 246 | ship.bull = ship.maxBull |
213 | 247 | } |
214 | 248 | |
215 | - guard let equiped = ship.equippedItem.array as? [SlotItem] else { return } | |
216 | - | |
217 | - ship.equippedItem = NSOrderedSet(array: equiped.filter { $0 != item }) | |
218 | - | |
219 | - return | |
249 | + ship.slot_ex = -1 | |
220 | 250 | } |
221 | - | |
222 | - // check extra slot | |
223 | - let exItemId = store.masterSlotItemID(by: ship.slot_ex) | |
224 | - | |
225 | - guard let exType = DamageControlID(rawValue: exItemId) else { return } | |
226 | - | |
227 | - switch exType { | |
228 | - case .damageControl: break | |
229 | - | |
230 | - case .goddes: | |
231 | - ship.fuel = ship.maxFuel | |
232 | - ship.bull = ship.maxBull | |
233 | - } | |
234 | - | |
235 | - ship.slot_ex = -1 | |
236 | 251 | } |
237 | 252 | } |
@@ -77,8 +77,8 @@ final class ChangeHenseiCommand: JSONCommand { | ||
77 | 77 | |
78 | 78 | if shipId == -1 { |
79 | 79 | |
80 | - guard let ship = removeShip(deckNumber: deckNumber, index: shipIndex) else { return } | |
81 | - notify(type: .remove, fleetNumber: deckNumber, position: shipIndex, shipID: ship.id) | |
80 | + guard let shipId = removeShip(deckNumber: deckNumber, index: shipIndex) else { return } | |
81 | + notify(type: .remove, fleetNumber: deckNumber, position: shipIndex, shipID: shipId) | |
82 | 82 | return |
83 | 83 | } |
84 | 84 |
@@ -92,22 +92,22 @@ final class ChangeHenseiCommand: JSONCommand { | ||
92 | 92 | guard case 0..<Deck.maxShipCount = shipIndex else { return } |
93 | 93 | |
94 | 94 | let store = ServerDataStore.oneTimeEditor() |
95 | - guard let deck = store.deck(by: deckNumber) else { return } | |
95 | + guard let deck = store.sync(execute: { store.deck(by: deckNumber) }) else { return } | |
96 | 96 | |
97 | 97 | // すでに編成されているか? どこに? |
98 | 98 | let (shipDeckNumber, shipDeckIndex) = position(of: shipId) |
99 | 99 | |
100 | 100 | // 配置しようとする位置に今配置されている艦娘 |
101 | - let replaceShipId = deck[shipIndex]?.id | |
101 | + let replaceShipId = store.sync { deck[shipIndex]?.id } | |
102 | 102 | |
103 | 103 | // 艦隊に配備 |
104 | - deck.setShip(id: shipId, for: shipIndex) | |
104 | + store.sync { deck.setShip(id: shipId, for: shipIndex) } | |
105 | 105 | |
106 | 106 | // 入れ替え |
107 | 107 | if shipDeckNumber != nil { |
108 | 108 | |
109 | - let shipDeck = store.deck(by: shipDeckNumber!) | |
110 | - shipDeck?.setShip(id: replaceShipId ?? -1, for: shipDeckIndex) | |
109 | + let shipDeck = store.sync { store.deck(by: shipDeckNumber!) } | |
110 | + store.sync { shipDeck?.setShip(id: replaceShipId ?? -1, for: shipDeckIndex) } | |
111 | 111 | shipDeck.map { packFleet(store: store, deck: $0) } |
112 | 112 | } |
113 | 113 |
@@ -132,40 +132,47 @@ final class ChangeHenseiCommand: JSONCommand { | ||
132 | 132 | |
133 | 133 | private func position(of shipId: Int) -> (deckNumber: Int?, shipId: Int) { |
134 | 134 | |
135 | - return ServerDataStore.default | |
136 | - .decksSortedById() | |
137 | - .lazy | |
138 | - .enumerated() | |
139 | - .map { (idx, deck) -> (Int, [Ship]) in (idx + 1, deck[0..<Deck.maxShipCount]) } | |
140 | - .filter { $0.1.contains { $0.id == shipId } } | |
141 | - .map { (deck, ships) in (deck, ships.index(where: { $0.id == shipId })!) } | |
142 | - .first ?? (nil, -1) | |
135 | + let store = ServerDataStore.default | |
136 | + return store.sync { | |
137 | + store | |
138 | + .decksSortedById() | |
139 | + .lazy | |
140 | + .enumerated() | |
141 | + .map { (idx, deck) -> (Int, [Ship]) in (idx + 1, deck[0..<Deck.maxShipCount]) } | |
142 | + .filter { $0.1.contains { $0.id == shipId } } | |
143 | + .map { (deck, ships) in (deck, ships.index(where: { $0.id == shipId })!) } | |
144 | + .first ?? (nil, -1) | |
145 | + } | |
143 | 146 | } |
144 | 147 | |
145 | - private func removeShip(deckNumber: Int, index: Int) -> Ship? { | |
148 | + private func removeShip(deckNumber: Int, index: Int) -> Int? { | |
146 | 149 | |
147 | 150 | let store = ServerDataStore.oneTimeEditor() |
148 | 151 | |
149 | - guard let deck = store.deck(by: deckNumber) else { return Logger.shared.log("Deck not found", value: nil) } | |
152 | + guard let deck = store.sync(execute: { store.deck(by: deckNumber) }) else { | |
153 | + | |
154 | + return Logger.shared.log("Deck not found", value: nil) | |
155 | + } | |
150 | 156 | |
151 | - let shipId = deck[index]?.id ?? -1 | |
152 | - deck.setShip(id: -1, for: index) | |
157 | + let shipId = store.sync { deck[index]?.id ?? -1 } | |
158 | + store.sync { deck.setShip(id: -1, for: index) } | |
153 | 159 | |
154 | 160 | packFleet(store: store, deck: deck) |
155 | 161 | |
156 | - return ServerDataStore.default.ship(by: shipId) | |
162 | + return shipId | |
157 | 163 | } |
158 | 164 | |
159 | 165 | private func excludeShipsWithoutFlagShip(deckNumber: Int) { |
160 | 166 | |
161 | 167 | let store = ServerDataStore.oneTimeEditor() |
162 | - | |
163 | - guard let deck = store.deck(by: deckNumber) else { | |
168 | + store.sync { | |
169 | + guard let deck = store.deck(by: deckNumber) else { | |
170 | + | |
171 | + return Logger.shared.log("Deck not found") | |
172 | + } | |
164 | 173 | |
165 | - return Logger.shared.log("Deck not found") | |
174 | + (1..<Deck.maxShipCount).forEach { deck.setShip(id: -1, for: $0) } | |
166 | 175 | } |
167 | - | |
168 | - (1..<Deck.maxShipCount).forEach { deck.setShip(id: -1, for: $0) } | |
169 | 176 | } |
170 | 177 | |
171 | 178 | private func packFleet(store: ServerDataStore, deck: Deck) { |
@@ -181,7 +188,7 @@ final class ChangeHenseiCommand: JSONCommand { | ||
181 | 188 | set(newShips, at: index + 1, in: deck) |
182 | 189 | } |
183 | 190 | |
184 | - set(deck[0..<Deck.maxShipCount], at: 0, in: deck) | |
191 | + store.sync { set(deck[0..<Deck.maxShipCount], at: 0, in: deck) } | |
185 | 192 | } |
186 | 193 | |
187 | 194 | private func notify(type: ChangeHenseiType, |
@@ -36,6 +36,10 @@ protocol CoreDataProvider { | ||
36 | 36 | |
37 | 37 | protocol CoreDataAccessor: CoreDataProvider { |
38 | 38 | |
39 | + func sync(execute: () -> Void) | |
40 | + func sync<T>(execute: () -> T) -> T | |
41 | + func async(execute: @escaping () -> Void) | |
42 | + | |
39 | 43 | func insertNewObject<T>(for entity: Entity<T>) -> T? |
40 | 44 | func delete(_ object: NSManagedObject) |
41 | 45 | func object<T>(of entity: Entity<T>, with objectId: NSManagedObjectID) -> T? |
@@ -79,40 +83,50 @@ extension CoreDataProvider { | ||
79 | 83 | |
80 | 84 | func save() throws { |
81 | 85 | |
82 | - guard context.commitEditing() else { | |
83 | - | |
84 | - throw CoreDataError.couldNotSave("\(String(describing: type(of: self))) unable to commit editing before saveing") | |
85 | - } | |
86 | - | |
87 | - do { | |
86 | + var caughtError: Error? | |
87 | + context.performAndWait { | |
88 | 88 | |
89 | - try context.save() | |
90 | - | |
91 | - } catch let error as NSError { | |
92 | - | |
93 | - throw CoreDataError.couldNotSave(error.localizedDescription) | |
94 | - } | |
95 | - | |
96 | - guard let parent = context.parent else { return } | |
97 | - | |
98 | - // save parent context | |
99 | - var catchedError: NSError? = nil | |
100 | - parent.performAndWait { | |
89 | + guard context.commitEditing() else { | |
90 | + | |
91 | + caughtError = CoreDataError.couldNotSave("\(String(describing: type(of: self))) unable to commit editing before saveing") | |
92 | + return | |
93 | + } | |
101 | 94 | |
102 | 95 | do { |
103 | 96 | |
104 | - try parent.save() | |
97 | + try context.save() | |
105 | 98 | |
106 | 99 | } catch let error as NSError { |
107 | 100 | |
108 | - catchedError = error | |
101 | + caughtError = CoreDataError.couldNotSave(error.localizedDescription) | |
102 | + return | |
103 | + } | |
104 | + | |
105 | + guard let parent = context.parent else { return } | |
106 | + | |
107 | + // save parent context | |
108 | + var catchedError: NSError? = nil | |
109 | + parent.performAndWait { | |
110 | + | |
111 | + do { | |
112 | + | |
113 | + try parent.save() | |
114 | + | |
115 | + } catch let error as NSError { | |
116 | + | |
117 | + catchedError = error | |
118 | + } | |
119 | + } | |
120 | + | |
121 | + if let error = catchedError { | |
122 | + | |
123 | + caughtError = CoreDataError.couldNotSave(error.localizedDescription) | |
109 | 124 | } |
110 | 125 | } |
111 | 126 | |
112 | - if let error = catchedError { | |
113 | - | |
114 | - throw CoreDataError.couldNotSave(error.localizedDescription) | |
127 | + if let error = caughtError { | |
115 | 128 | |
129 | + throw error | |
116 | 130 | } |
117 | 131 | } |
118 | 132 |
@@ -134,6 +148,25 @@ extension CoreDataProvider { | ||
134 | 148 | |
135 | 149 | extension CoreDataAccessor { |
136 | 150 | |
151 | + func sync(execute work: () -> Void) { | |
152 | + | |
153 | + self.context.performAndWait(work) | |
154 | + } | |
155 | + | |
156 | + func sync<T>(execute work: () -> T) -> T { | |
157 | + | |
158 | + var value: T! | |
159 | + sync { | |
160 | + value = work() | |
161 | + } | |
162 | + return value | |
163 | + } | |
164 | + | |
165 | + func async(execute work: @escaping () -> Void) { | |
166 | + | |
167 | + self.context.perform(work) | |
168 | + } | |
169 | + | |
137 | 170 | func insertNewObject<T>(for entity: Entity<T>) -> T? { |
138 | 171 | |
139 | 172 | return NSEntityDescription.insertNewObject(forEntityName: entity.name, into: context) as? T |
@@ -155,11 +188,31 @@ extension CoreDataAccessor { | ||
155 | 188 | req.sortDescriptors = sortDescriptors |
156 | 189 | req.predicate = predicate |
157 | 190 | |
158 | - return try context.fetch(req) | |
191 | + var result: [T]? | |
192 | + var caughtError: Error? | |
193 | + sync { | |
194 | + do { | |
195 | + | |
196 | + result = try self.context.fetch(req) | |
197 | + } catch { | |
198 | + | |
199 | + caughtError = error | |
200 | + } | |
201 | + } | |
202 | + if let error = caughtError { | |
203 | + | |
204 | + throw error | |
205 | + } | |
206 | + | |
207 | + return result ?? [] | |
159 | 208 | } |
160 | 209 | |
161 | 210 | func object(with objectId: NSManagedObjectID) -> NSManagedObject { |
162 | 211 | |
163 | - return context.object(with: objectId) | |
212 | + var result: NSManagedObject? | |
213 | + sync { | |
214 | + result = self.context.object(with: objectId) | |
215 | + } | |
216 | + return result! | |
164 | 217 | } |
165 | 218 | } |
@@ -31,29 +31,53 @@ final class CreateShipCommand: JSONCommand { | ||
31 | 31 | |
32 | 32 | let store = ServerDataStore.default |
33 | 33 | |
34 | - guard let kenzoDock = store.kenzoDock(by: dockId), | |
35 | - let flagShip = store.deck(by: 1)?[0], | |
36 | - let basic = store.basic() else { | |
37 | - | |
38 | - return Logger.shared.log("CreateShipCommand: CoreData is wrong") | |
34 | + let storedInfos: KenzoMarkCommand.KenzoDockInfo? = store.sync { | |
35 | + | |
36 | + guard let kenzoDock = store.kenzoDock(by: dockId) else { | |
37 | + | |
38 | + return nil | |
39 | + } | |
40 | + | |
41 | + return KenzoMarkCommand.KenzoDockInfo(dockId: kenzoDock.id, | |
42 | + shipId: kenzoDock.created_ship_id, | |
43 | + fuel: kenzoDock.item1, | |
44 | + bull: kenzoDock.item2, | |
45 | + steel: kenzoDock.item3, | |
46 | + bauxite: kenzoDock.item4, | |
47 | + kaihatusizai: kenzoDock.item5) | |
39 | 48 | } |
40 | 49 | |
41 | - let localStore = LocalDataStore.oneTimeEditor() | |
50 | + guard let infos = storedInfos else { | |
51 | + | |
52 | + return Logger.shared.log("Can not load KenzoDeck") | |
53 | + } | |
42 | 54 | |
43 | - guard let newMark = localStore.kenzoMark(byDockId: dockId) ?? localStore.createKenzoMark() else { | |
55 | + guard let flagShip = store.sync(execute: { store.deck(by: 1)?[0] }) else { | |
44 | 56 | |
45 | - return Logger.shared.log("Can not create KenzoMark") | |
57 | + return Logger.shared.log("Can not load deck") | |
58 | + } | |
59 | + guard let commanderLv = store.sync(execute: { store.basic()?.level }) else { | |
60 | + | |
61 | + return Logger.shared.log("Can not load basic") | |
46 | 62 | } |
47 | 63 | |
48 | - newMark.fuel = kenzoDock.item1 | |
49 | - newMark.bull = kenzoDock.item2 | |
50 | - newMark.steel = kenzoDock.item3 | |
51 | - newMark.bauxite = kenzoDock.item4 | |
52 | - newMark.kaihatusizai = kenzoDock.item5 | |
53 | - newMark.created_ship_id = kenzoDock.created_ship_id | |
54 | - newMark.flagShipName = flagShip.name | |
55 | - newMark.flagShipLv = flagShip.lv | |
56 | - newMark.commanderLv = basic.level | |
57 | - newMark.kDockId = dockId | |
64 | + let localStore = LocalDataStore.oneTimeEditor() | |
65 | + localStore.sync { | |
66 | + guard let newMark = localStore.kenzoMark(byDockId: dockId) ?? localStore.createKenzoMark() else { | |
67 | + | |
68 | + return Logger.shared.log("Can not create KenzoMark") | |
69 | + } | |
70 | + | |
71 | + newMark.fuel = infos.fuel | |
72 | + newMark.bull = infos.bull | |
73 | + newMark.steel = infos.steel | |
74 | + newMark.bauxite = infos.bauxite | |
75 | + newMark.kaihatusizai = infos.kaihatusizai | |
76 | + newMark.created_ship_id = infos.shipId | |
77 | + newMark.flagShipName = store.sync { flagShip.name } | |
78 | + newMark.flagShipLv = store.sync { flagShip.lv } | |
79 | + newMark.commanderLv = commanderLv | |
80 | + newMark.kDockId = dockId | |
81 | + } | |
58 | 82 | } |
59 | 83 | } |
@@ -34,48 +34,60 @@ extension DamageCalculator { | ||
34 | 34 | |
35 | 35 | func calculateBattle() { |
36 | 36 | |
37 | - calcKouku() | |
38 | - calcOpeningTaisen() | |
39 | - calcOpeningAttack() | |
40 | - calcHougeki1() | |
41 | - calcHougeki2() | |
42 | - calcHougeki3() | |
43 | - calcRaigeki() | |
37 | + store.sync { | |
38 | + | |
39 | + self.calcKouku() | |
40 | + self.calcOpeningTaisen() | |
41 | + self.calcOpeningAttack() | |
42 | + self.calcHougeki1() | |
43 | + self.calcHougeki2() | |
44 | + self.calcHougeki3() | |
45 | + self.calcRaigeki() | |
46 | + } | |
44 | 47 | } |
45 | 48 | |
46 | 49 | func calcCombinedBattleAir() { |
47 | 50 | |
48 | - calcKouku() | |
49 | - calcOpeningTaisen() | |
50 | - calcOpeningAttack() | |
51 | - calcHougeki1() | |
52 | - calcRaigeki() | |
53 | - calcHougeki2() | |
54 | - calcHougeki3() | |
51 | + store.sync { | |
52 | + | |
53 | + self.calcKouku() | |
54 | + self.calcOpeningTaisen() | |
55 | + self.calcOpeningAttack() | |
56 | + self.calcHougeki1() | |
57 | + self.calcRaigeki() | |
58 | + self.calcHougeki2() | |
59 | + self.calcHougeki3() | |
60 | + } | |
55 | 61 | } |
56 | 62 | |
57 | 63 | func calcEachBattleAir() { |
58 | 64 | |
59 | - calcKouku() | |
60 | - calcOpeningTaisen() | |
61 | - calcOpeningAttack() | |
62 | - calcHougeki1() | |
63 | - calcHougeki2() | |
64 | - calcRaigeki() | |
65 | - calcHougeki3() | |
65 | + store.sync { | |
66 | + | |
67 | + self.calcKouku() | |
68 | + self.calcOpeningTaisen() | |
69 | + self.calcOpeningAttack() | |
70 | + self.calcHougeki1() | |
71 | + self.calcHougeki2() | |
72 | + self.calcRaigeki() | |
73 | + self.calcHougeki3() | |
74 | + } | |
66 | 75 | } |
67 | 76 | |
68 | 77 | func calcEachNightToDay() { |
69 | 78 | |
70 | - calcNightHogeki1() | |
71 | - calcNightHogeki2() | |
72 | - calcKouku() | |
73 | - calcOpeningTaisen() | |
74 | - calcOpeningAttack() | |
75 | - calcHougeki1() | |
76 | - calcHougeki2() | |
77 | - calcRaigeki() | |
78 | - calcHougeki3() | |
79 | + store.sync { | |
80 | + | |
81 | + self.calcNightHogeki1() | |
82 | + self.calcNightHogeki2() | |
83 | + self.calcKouku() | |
84 | + self.calcOpeningTaisen() | |
85 | + self.calcOpeningAttack() | |
86 | + self.calcHougeki1() | |
87 | + self.calcHougeki2() | |
88 | + self.calcRaigeki() | |
89 | + self.calcHougeki3() | |
90 | + } | |
79 | 91 | } |
80 | 92 | |
81 | 93 | func calcEnemyCombinedBattle() { |
@@ -86,7 +98,10 @@ extension DamageCalculator { | ||
86 | 98 | |
87 | 99 | func calcMidnight() { |
88 | 100 | |
89 | - calculateMidnightBattle() | |
101 | + store.sync { | |
102 | + | |
103 | + self.calculateMidnightBattle() | |
104 | + } | |
90 | 105 | } |
91 | 106 | } |
92 | 107 |
@@ -212,12 +227,14 @@ extension DamageCalculator { | ||
212 | 227 | |
213 | 228 | func setShip(_ ship: Ship, into damage: Damage) { |
214 | 229 | |
215 | - damage.shipID = ship.id | |
216 | - damage.hp = ship.nowhp | |
230 | + let sStore = ServerDataStore.default | |
231 | + | |
232 | + damage.shipID = sStore.sync { ship.id } | |
233 | + damage.hp = sStore.sync { ship.nowhp } | |
217 | 234 | |
218 | 235 | Debug.excute(level: .debug) { |
219 | - | |
220 | - print("add Damage entity of \(ship.name) at \(damage.id)") | |
236 | + let name = sStore.sync { ship.name } | |
237 | + print("add Damage entity of \(name) at \(damage.id)") | |
221 | 238 | } |
222 | 239 | } |
223 | 240 |
@@ -235,13 +252,15 @@ extension DamageCalculator { | ||
235 | 252 | |
236 | 253 | guard let battle = store.battle() else { return Logger.shared.log("Battle is invalid.") } |
237 | 254 | |
255 | + let sStore = ServerDataStore.default | |
238 | 256 | // 第一艦隊 |
239 | - let firstFleetShips = ServerDataStore.default.ships(byDeckId: battle.deckId) | |
257 | + let deckId = battle.deckId | |
258 | + let firstFleetShips = sStore.sync { sStore.ships(byDeckId: deckId) } | |
240 | 259 | |
241 | 260 | // 第二艦隊 |
242 | 261 | if isCombinedBattle { |
243 | 262 | |
244 | - let secondFleetShips = ServerDataStore.default.ships(byDeckId: 2) | |
263 | + let secondFleetShips = sStore.sync { sStore.ships(byDeckId: 2) } | |
245 | 264 | buildDamages(first: firstFleetShips, second: secondFleetShips) |
246 | 265 | } else { |
247 | 266 |
@@ -298,9 +317,10 @@ extension DamageCalculator { | ||
298 | 317 | |
299 | 318 | Debug.excute(level: .debug) { |
300 | 319 | |
301 | - if receive != 0, let ship = ServerDataStore.default.ship(by: damage.shipID) { | |
320 | + let store = ServerDataStore.default | |
321 | + if receive != 0, let shipName = store.sync(execute: { store.ship(by: damage.shipID)?.name }) { | |
302 | 322 | |
303 | - print("\(ship.name) recieve Damage \(receive)") | |
323 | + print("\(shipName) recieve Damage \(receive)") | |
304 | 324 | } |
305 | 325 | } |
306 | 326 |
@@ -308,7 +328,8 @@ extension DamageCalculator { | ||
308 | 328 | |
309 | 329 | if damage.hp > 0 { return } |
310 | 330 | |
311 | - guard let ship = ServerDataStore.default.ship(by: damage.shipID) else { return } | |
331 | + let sStore = ServerDataStore.default | |
332 | + guard let ship = sStore.sync(execute: { sStore.ship(by: damage.shipID) }) else { return } | |
312 | 333 | |
313 | 334 | damage.hp = damageControlIfPossible(ship: ship) |
314 | 335 | damage.useDamageControl = (damage.hp != 0) |
@@ -408,18 +429,34 @@ extension DamageCalculator { | ||
408 | 429 | private func damageControlIfPossible(ship: Ship) -> Int { |
409 | 430 | |
410 | 431 | let store = ServerDataStore.default |
411 | - | |
412 | - let damageControl = ship | |
413 | - .equippedItem | |
414 | - .lazy | |
415 | - .flatMap { $0 as? SlotItem } | |
416 | - .map { store.masterSlotItemID(by: $0.id) } | |
417 | - .flatMap { DamageControlID(rawValue: $0) } | |
418 | - .first | |
419 | - | |
420 | - if let validDamageControl = damageControl { | |
432 | + return store.sync { | |
433 | + let damageControl = ship | |
434 | + .equippedItem | |
435 | + .lazy | |
436 | + .flatMap { $0 as? SlotItem } | |
437 | + .map { store.masterSlotItemID(by: $0.id) } | |
438 | + .flatMap { DamageControlID(rawValue: $0) } | |
439 | + .first | |
440 | + | |
441 | + if let validDamageControl = damageControl { | |
442 | + | |
443 | + switch validDamageControl { | |
444 | + case .damageControl: | |
445 | + Debug.print("Damage Control", level: .debug) | |
446 | + return Int(Double(ship.maxhp) * 0.2) | |
447 | + | |
448 | + case .goddes: | |
449 | + Debug.print("Goddes", level: .debug) | |
450 | + return ship.maxhp | |
451 | + } | |
452 | + } | |
453 | + | |
454 | + // check extra slot | |
455 | + let exItemId = store.masterSlotItemID(by: ship.slot_ex) | |
421 | 456 | |
422 | - switch validDamageControl { | |
457 | + guard let exType = DamageControlID(rawValue: exItemId) else { return 0 } | |
458 | + | |
459 | + switch exType { | |
423 | 460 | case .damageControl: |
424 | 461 | Debug.print("Damage Control", level: .debug) |
425 | 462 | return Int(Double(ship.maxhp) * 0.2) |
@@ -429,20 +466,5 @@ extension DamageCalculator { | ||
429 | 466 | return ship.maxhp |
430 | 467 | } |
431 | 468 | } |
432 | - | |
433 | - // check extra slot | |
434 | - let exItemId = store.masterSlotItemID(by: ship.slot_ex) | |
435 | - | |
436 | - guard let exType = DamageControlID(rawValue: exItemId) else { return 0 } | |
437 | - | |
438 | - switch exType { | |
439 | - case .damageControl: | |
440 | - Debug.print("Damage Control", level: .debug) | |
441 | - return Int(Double(ship.maxhp) * 0.2) | |
442 | - | |
443 | - case .goddes: | |
444 | - Debug.print("Goddes", level: .debug) | |
445 | - return ship.maxhp | |
446 | - } | |
447 | 469 | } |
448 | 470 | } |
@@ -19,9 +19,9 @@ final class DestroyItem2Command: JSONCommand { | ||
19 | 19 | |
20 | 20 | let store = ServerDataStore.oneTimeEditor() |
21 | 21 | |
22 | - store.slotItems(in: parameter["api_slotitem_ids"].integerArray).forEach(store.delete) | |
22 | + store.sync { store.slotItems(in: self.parameter["api_slotitem_ids"].integerArray).forEach(store.delete) } | |
23 | 23 | |
24 | - guard let material = store.material() else { | |
24 | + guard let material = store.sync(execute: { store.material() }) else { | |
25 | 25 | |
26 | 26 | return Logger.shared.log("Material is not found") |
27 | 27 | } |
@@ -31,9 +31,12 @@ final class DestroyItem2Command: JSONCommand { | ||
31 | 31 | return Logger.shared.log("api_get_material is wrong") |
32 | 32 | } |
33 | 33 | |
34 | - material.fuel += getMaterials[0] | |
35 | - material.bull += getMaterials[1] | |
36 | - material.steel += getMaterials[2] | |
37 | - material.bauxite += getMaterials[3] | |
34 | + store.sync { | |
35 | + | |
36 | + material.fuel += getMaterials[0] | |
37 | + material.bull += getMaterials[1] | |
38 | + material.steel += getMaterials[2] | |
39 | + material.bauxite += getMaterials[3] | |
40 | + } | |
38 | 41 | } |
39 | 42 | } |
@@ -22,48 +22,54 @@ final class DropShipHistoryCommand: JSONCommand { | ||
22 | 22 | guard let shipName = data["api_get_ship"]["api_ship_name"].string else { return } |
23 | 23 | guard let winRank = data["api_win_rank"].string else { return } |
24 | 24 | |
25 | - guard let battle = TemporaryDataStore.default.battle() else { | |
25 | + let tempStore = TemporaryDataStore.default | |
26 | + guard let battle = tempStore.sync(execute: { tempStore.battle() }) else { | |
26 | 27 | |
27 | 28 | return Logger.shared.log("Can not get Battle") |
28 | 29 | } |
29 | 30 | |
30 | - let mapAreaId = battle.mapArea | |
31 | + let mapAreaId = tempStore.sync { battle.mapArea } | |
32 | + let mapInfoId = tempStore.sync { battle.mapInfo } | |
31 | 33 | |
32 | 34 | let store = ServerDataStore.default |
33 | 35 | |
34 | - guard let mapInfo = store.mapInfo(area: mapAreaId, no: battle.mapInfo) else { | |
36 | + guard let mapInfoName = store.sync(execute: { store.mapInfo(area: mapAreaId, no: mapInfoId)?.name }) else { | |
35 | 37 | |
36 | 38 | return Logger.shared.log("KCMasterMapInfo is not found") |
37 | 39 | } |
38 | 40 | |
39 | - guard let mapArea = store.mapArea(by: mapAreaId) else { | |
41 | + guard let mapAreaName = store.sync(execute: { store.mapArea(by: mapAreaId)?.name }) else { | |
40 | 42 | |
41 | 43 | return Logger.shared.log("KCMasterMapArea is not found") |
42 | 44 | } |
43 | 45 | |
44 | 46 | |
45 | 47 | let localStore = LocalDataStore.oneTimeEditor() |
46 | - guard let new = localStore.createHiddenDropShipHistory() else { | |
48 | + localStore.sync { | |
47 | 49 | |
48 | - return Logger.shared.log("Can not create HiddenDropShipHistory") | |
50 | + guard let new = localStore.createHiddenDropShipHistory() else { | |
51 | + | |
52 | + return Logger.shared.log("Can not create HiddenDropShipHistory") | |
53 | + } | |
54 | + | |
55 | + new.shipName = shipName | |
56 | + new.mapArea = "\(mapAreaId)" | |
57 | + new.mapAreaName = mapAreaName | |
58 | + new.mapInfo = tempStore.sync { battle.mapInfo } | |
59 | + new.mapInfoName = mapInfoName | |
60 | + new.mapCell = tempStore.sync { battle.no } | |
61 | + new.winRank = winRank | |
62 | + new.date = Date() | |
49 | 63 | } |
50 | - | |
51 | - new.shipName = shipName | |
52 | - new.mapArea = "\(mapAreaId)" | |
53 | - new.mapAreaName = mapArea.name | |
54 | - new.mapInfo = battle.mapInfo | |
55 | - new.mapInfoName = mapInfo.name | |
56 | - new.mapCell = battle.no | |
57 | - new.winRank = winRank | |
58 | - new.date = Date() | |
59 | 64 | } |
60 | 65 | |
61 | 66 | private func storeToVisible() { |
62 | 67 | |
63 | 68 | let store = LocalDataStore.oneTimeEditor() |
64 | - | |
65 | - let hidden = store.hiddenDropShipHistories() | |
66 | - _ = hidden.map(store.createDropShipHistory(from:)) | |
67 | - hidden.forEach(store.delete) | |
69 | + store.sync { | |
70 | + let hidden = store.hiddenDropShipHistories() | |
71 | + _ = hidden.map(store.createDropShipHistory(from:)) | |
72 | + hidden.forEach(store.delete) | |
73 | + } | |
68 | 74 | } |
69 | 75 | } |
@@ -39,16 +39,14 @@ final class DummyShipCommand: JSONCommand { | ||
39 | 39 | guard DummyShipCommand.needsEnterDummy else { return } |
40 | 40 | |
41 | 41 | let store = ServerDataStore.oneTimeEditor() |
42 | - | |
43 | - store.createShip()?.id = -2 | |
42 | + store.sync { store.createShip()?.id = -2 } | |
44 | 43 | DummyShipCommand.needsEnterDummy = false |
45 | 44 | } |
46 | 45 | |
47 | 46 | private func removeDummy() { |
48 | 47 | |
49 | 48 | let store = ServerDataStore.oneTimeEditor() |
50 | - | |
51 | - store.ships(by: -2).forEach(store.delete) | |
49 | + store.sync { store.ships(by: -2).forEach(store.delete) } | |
52 | 50 | DummyShipCommand.needsEnterDummy = false |
53 | 51 | } |
54 | 52 | } |
@@ -235,15 +235,18 @@ extension ExternalBrowserWindowController { | ||
235 | 235 | @IBAction func addBookmark(_ sender: AnyObject?) { |
236 | 236 | |
237 | 237 | guard let window = window else { return } |
238 | - guard let bookmark = BookmarkManager.shared.createNewBookmark() else { return } | |
239 | - | |
240 | - bookmark.name = window.title | |
241 | - bookmark.urlString = webView.mainFrameURL | |
242 | - bookmark.windowContentSize = windowContentSize | |
243 | - bookmark.contentVisibleRect = contentVisibleRect | |
244 | - bookmark.canResize = canResize | |
245 | - bookmark.canScroll = canScroll | |
246 | - bookmark.scrollDelay = 0.5 | |
238 | + _ = BookmarkManager.shared.createNewBookmark { bookmark in | |
239 | + | |
240 | + bookmark.name = window.title | |
241 | + bookmark.urlString = self.webView.mainFrameURL | |
242 | + bookmark.windowContentSize = self.windowContentSize | |
243 | + bookmark.contentVisibleRect = self.contentVisibleRect | |
244 | + bookmark.canResize = self.canResize | |
245 | + bookmark.canScroll = self.canScroll | |
246 | + bookmark.scrollDelay = 0.5 | |
247 | + | |
248 | + return true | |
249 | + } | |
247 | 250 | } |
248 | 251 | |
249 | 252 | @IBAction func showBookmark(_ sender: AnyObject?) { |
@@ -46,6 +46,8 @@ final class Fleet: NSObject { | ||
46 | 46 | @objc dynamic private(set) var ships: [Ship] = [] |
47 | 47 | private var deck: Deck? |
48 | 48 | |
49 | + let store = ServerDataStore.default | |
50 | + | |
49 | 51 | init?(number: Int) { |
50 | 52 | |
51 | 53 | guard case 1...4 = number else { |
@@ -58,7 +60,7 @@ final class Fleet: NSObject { | ||
58 | 60 | |
59 | 61 | super.init() |
60 | 62 | |
61 | - if let deck = ServerDataStore.default.deck(by: number) { | |
63 | + if let deck = store.sync(execute: { self.store.deck(by: number) }) { | |
62 | 64 | |
63 | 65 | self.setupDeck(deck: deck) |
64 | 66 |
@@ -68,7 +70,7 @@ final class Fleet: NSObject { | ||
68 | 70 | ServerDataStore.default |
69 | 71 | .future { _ -> Deck? in |
70 | 72 | |
71 | - guard let deck = ServerDataStore.default.deck(by: number) else { return .none } | |
73 | + guard let deck = self.store.sync(execute: { self.store.deck(by: number) }) else { return .none } | |
72 | 74 | |
73 | 75 | return deck |
74 | 76 | } |
@@ -82,7 +84,7 @@ final class Fleet: NSObject { | ||
82 | 84 | } |
83 | 85 | } |
84 | 86 | |
85 | - subscript(_ index: Int) -> Ship? { return deck?[index] } | |
87 | + subscript(_ index: Int) -> Ship? { return store.sync { self.deck?[index] } } | |
86 | 88 | |
87 | 89 | private func setupDeck(deck: Deck) { |
88 | 90 |
@@ -95,6 +97,6 @@ final class Fleet: NSObject { | ||
95 | 97 | |
96 | 98 | private func setupShips(deck: Deck) { |
97 | 99 | |
98 | - ships = deck[0...6] | |
100 | + ships = store.sync { deck[0...6] } | |
99 | 101 | } |
100 | 102 | } |
@@ -64,16 +64,18 @@ final class FleetManager: NSObject { | ||
64 | 64 | private func setNewFleetNumberToShip() { |
65 | 65 | |
66 | 66 | let store = ServerDataStore.oneTimeEditor() |
67 | - | |
68 | - // clear all | |
69 | - store.shipsInFleet().forEach { $0.fleet = 0 as NSNumber } | |
70 | - | |
71 | - // set | |
72 | - fleets.enumerated().forEach { (index, fleet) in | |
67 | + store.sync { | |
73 | 68 | |
74 | - fleet.ships.forEach { | |
69 | + // clear all | |
70 | + store.shipsInFleet().forEach { $0.fleet = 0 as NSNumber } | |
71 | + | |
72 | + // set | |
73 | + self.fleets.enumerated().forEach { index, fleet in | |
75 | 74 | |
76 | - store.ship(by: $0.id)?.fleet = (index + 1) as NSNumber | |
75 | + fleet.ships.forEach { ship in | |
76 | + | |
77 | + store.ship(by: ship.id)?.fleet = (index + 1) as NSNumber | |
78 | + } | |
77 | 79 | } |
78 | 80 | } |
79 | 81 | } |
@@ -42,19 +42,20 @@ final class GuardShelterCommand: JSONCommand { | ||
42 | 42 | |
43 | 43 | private func damagedShipId(damagedPos: Int) -> Int? { |
44 | 44 | |
45 | - let firstDeckId = TemporaryDataStore.default.battle()?.deckId ?? 1 | |
45 | + let tempStore = TemporaryDataStore.default | |
46 | + let firstDeckId = tempStore.sync { tempStore.battle()?.deckId ?? 1 } | |
46 | 47 | |
47 | 48 | let store = ServerDataStore.default |
48 | 49 | |
49 | 50 | switch firstDeckId { |
50 | 51 | case 1: |
51 | 52 | switch damagedPos { |
52 | - case 1...6: return store.deck(by: 1)?.shipId(of: damagedPos - 1) | |
53 | - case 7...12: return store.deck(by: 2)?.shipId(of: damagedPos - 6 - 1) | |
53 | + case 1...6: return store.sync { store.deck(by: 1)?.shipId(of: damagedPos - 1) } | |
54 | + case 7...12: return store.sync { store.deck(by: 2)?.shipId(of: damagedPos - 6 - 1) } | |
54 | 55 | default: return nil |
55 | 56 | } |
56 | 57 | case 3: |
57 | - return store.deck(by: 3)?.shipId(of: damagedPos - 1) | |
58 | + return store.sync { store.deck(by: 3)?.shipId(of: damagedPos - 1) } | |
58 | 59 | default: |
59 | 60 | return nil |
60 | 61 | } |
@@ -71,40 +72,44 @@ final class GuardShelterCommand: JSONCommand { | ||
71 | 72 | } |
72 | 73 | |
73 | 74 | let store = TemporaryDataStore.oneTimeEditor() |
74 | - | |
75 | - guard let damaged = store.createGuardEscaped() else { | |
75 | + store.sync { | |
76 | 76 | |
77 | - return Logger.shared.log("Can not create GuardEscaped for damaged") | |
78 | - } | |
79 | - | |
80 | - damaged.shipID = damagedId | |
81 | - damaged.ensured = false | |
82 | - | |
83 | - // store guardian if needs | |
84 | - guard let guardianPos = escape["api_tow_idx"][0].int else { return } | |
85 | - | |
86 | - let fixedGuardianPos = guardianPos - 6 - 1 | |
87 | - | |
88 | - guard let guardianId = ServerDataStore.default.deck(by: 2)?.shipId(of: fixedGuardianPos) else { | |
77 | + guard let damaged = store.createGuardEscaped() else { | |
78 | + | |
79 | + return Logger.shared.log("Can not create GuardEscaped for damaged") | |
80 | + } | |
89 | 81 | |
90 | - return Logger.shared.log("guardianPos is wrong") | |
91 | - } | |
92 | - | |
93 | - guard let guardian = store.createGuardEscaped() else { | |
82 | + damaged.shipID = damagedId | |
83 | + damaged.ensured = false | |
84 | + | |
85 | + // store guardian if needs | |
86 | + guard let guardianPos = escape["api_tow_idx"][0].int else { return } | |
87 | + | |
88 | + let fixedGuardianPos = guardianPos - 6 - 1 | |
94 | 89 | |
95 | - return Logger.shared.log("Can not create GuardEscaped for guardinan") | |
90 | + let sStore = ServerDataStore.default | |
91 | + guard let guardianId = sStore.sync(execute: { sStore.deck(by: 2)?.shipId(of: fixedGuardianPos) }) else { | |
92 | + | |
93 | + return Logger.shared.log("guardianPos is wrong") | |
94 | + } | |
95 | + | |
96 | + guard let guardian = store.createGuardEscaped() else { | |
97 | + | |
98 | + return Logger.shared.log("Can not create GuardEscaped for guardinan") | |
99 | + } | |
100 | + | |
101 | + guardian.shipID = guardianId | |
102 | + guardian.ensured = false | |
96 | 103 | } |
97 | - | |
98 | - guardian.shipID = guardianId | |
99 | - guardian.ensured = false | |
100 | 104 | } |
101 | 105 | |
102 | 106 | private func removeInvalidEntry() { |
103 | 107 | |
104 | 108 | let store = TemporaryDataStore.oneTimeEditor() |
105 | - | |
106 | - store.notEnsuredGuardEscaped().forEach(store.delete) | |
107 | - store.save(errorHandler: store.presentOnMainThread) | |
109 | + store.sync { | |
110 | + store.notEnsuredGuardEscaped().forEach(store.delete) | |
111 | + store.save(errorHandler: store.presentOnMainThread) | |
112 | + } | |
108 | 113 | Thread.sleep(forTimeInterval: 0.1) |
109 | 114 | notify() |
110 | 115 | } |
@@ -112,9 +117,10 @@ final class GuardShelterCommand: JSONCommand { | ||
112 | 117 | private func removeAllEntry() { |
113 | 118 | |
114 | 119 | let store = TemporaryDataStore.oneTimeEditor() |
115 | - | |
116 | - store.guardEscaped().forEach(store.delete) | |
117 | - store.save(errorHandler: store.presentOnMainThread) | |
120 | + store.sync { | |
121 | + store.guardEscaped().forEach(store.delete) | |
122 | + store.save(errorHandler: store.presentOnMainThread) | |
123 | + } | |
118 | 124 | Thread.sleep(forTimeInterval: 0.1) |
119 | 125 | notify() |
120 | 126 | } |
@@ -122,9 +128,10 @@ final class GuardShelterCommand: JSONCommand { | ||
122 | 128 | private func ensureGuardShelter() { |
123 | 129 | |
124 | 130 | let store = TemporaryDataStore.oneTimeEditor() |
125 | - | |
126 | - store.guardEscaped().forEach { $0.ensured = true } | |
127 | - store.save(errorHandler: store.presentOnMainThread) | |
131 | + store.sync { | |
132 | + store.guardEscaped().forEach { $0.ensured = true } | |
133 | + store.save(errorHandler: store.presentOnMainThread) | |
134 | + } | |
128 | 135 | Thread.sleep(forTimeInterval: 0.1) |
129 | 136 | notify() |
130 | 137 | } |
@@ -15,10 +15,13 @@ final class HistoryItemCleaner { | ||
15 | 15 | guard UserDefaults.standard[.cleanOldHistoryItems] else { return } |
16 | 16 | |
17 | 17 | let store = LocalDataStore.oneTimeEditor() |
18 | - let cleanSinceDays = UserDefaults.standard[.cleanSinceDays] | |
19 | - | |
20 | - store.unmarkedKaihatuHistories(befor: cleanSinceDays).forEach(store.delete) | |
21 | - store.unmarkedKenzoHistories(befor: cleanSinceDays).forEach(store.delete) | |
22 | - store.unmarkedDropShipHistories(befor: cleanSinceDays).forEach(store.delete) | |
18 | + store.sync { | |
19 | + | |
20 | + let cleanSinceDays = UserDefaults.standard[.cleanSinceDays] | |
21 | + | |
22 | + store.unmarkedKaihatuHistories(befor: cleanSinceDays).forEach(store.delete) | |
23 | + store.unmarkedKenzoHistories(befor: cleanSinceDays).forEach(store.delete) | |
24 | + store.unmarkedDropShipHistories(befor: cleanSinceDays).forEach(store.delete) | |
25 | + } | |
23 | 26 | } |
24 | 27 | } |
@@ -49,10 +49,12 @@ class HistoryTableViewController: NSViewController { | ||
49 | 49 | guard let selection = controller.selectedObjects as? [NSManagedObject] else { return } |
50 | 50 | |
51 | 51 | let selectedIndex = controller.selectionIndex |
52 | - selection | |
53 | - .map { $0.objectID } | |
54 | - .map(store.object(with:)) | |
55 | - .forEach(store.delete) | |
52 | + store.sync { | |
53 | + selection | |
54 | + .map { $0.objectID } | |
55 | + .map(store.object(with:)) | |
56 | + .forEach(store.delete) | |
57 | + } | |
56 | 58 | |
57 | 59 | if selectedIndex > 1 { |
58 | 60 |
@@ -70,14 +72,16 @@ class HistoryTableViewController: NSViewController { | ||
70 | 72 | let predicate = NSPredicate(#keyPath(KenzoMark.date), equal: clickedObject.date) |
71 | 73 | |
72 | 74 | let store = LocalDataStore.oneTimeEditor() |
73 | - | |
74 | - if let items = try? objects(of: predicate, in: store), | |
75 | - var history = items.first as? Markable { | |
75 | + store.sync { | |
76 | + | |
77 | + if let items = try? self.objects(of: predicate, in: store), | |
78 | + var history = items.first as? Markable { | |
79 | + | |
80 | + history.mark = !history.mark | |
81 | + } | |
76 | 82 | |
77 | - history.mark = !history.mark | |
83 | + store.save(errorHandler: store.presentOnMainThread) | |
78 | 84 | } |
79 | - | |
80 | - store.save(errorHandler: store.presentOnMainThread) | |
81 | 85 | } |
82 | 86 | |
83 | 87 | override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool { |
@@ -144,7 +144,7 @@ extension JSONMapper { | ||
144 | 144 | } |
145 | 145 | } |
146 | 146 | |
147 | - func commit() { | |
147 | + private func commintInContext() { | |
148 | 148 | |
149 | 149 | let store = configuration.editorStore |
150 | 150 |
@@ -174,6 +174,14 @@ extension JSONMapper { | ||
174 | 174 | store.save(errorHandler: store.presentOnMainThread) |
175 | 175 | } |
176 | 176 | |
177 | + func commit() { | |
178 | + | |
179 | + configuration.editorStore | |
180 | + .sync { | |
181 | + self.commintInContext() | |
182 | + } | |
183 | + } | |
184 | + | |
177 | 185 | func beginRegister(_ object: ObjectType) {} |
178 | 186 | |
179 | 187 | func handleExtraValue(_ value: JSON, forKey key: String, to object: ObjectType) -> Bool { |
@@ -28,6 +28,6 @@ final class KaisouLockCommand: JSONCommand { | ||
28 | 28 | |
29 | 29 | let store = ServerDataStore.oneTimeEditor() |
30 | 30 | |
31 | - store.slotItem(by: slotId)?.locked = (locked != 0) | |
31 | + store.sync { store.slotItem(by: slotId)?.locked = (locked != 0) } | |
32 | 32 | } |
33 | 33 | } |
@@ -10,48 +10,69 @@ import Cocoa | ||
10 | 10 | |
11 | 11 | final class KenzoMarkCommand: JSONCommand { |
12 | 12 | |
13 | + struct KenzoDockInfo { | |
14 | + let dockId: Int | |
15 | + let shipId: Int | |
16 | + let fuel: Int | |
17 | + let bull: Int | |
18 | + let steel: Int | |
19 | + let bauxite: Int | |
20 | + let kaihatusizai: Int | |
21 | + } | |
22 | + | |
13 | 23 | override func execute() { |
14 | 24 | |
25 | + let store = LocalDataStore.oneTimeEditor() | |
26 | + store.sync { | |
27 | + self.executeInContext(localStore: store) | |
28 | + } | |
29 | + } | |
30 | + | |
31 | + private func executeInContext(localStore: LocalDataStore) { | |
32 | + | |
15 | 33 | guard let kdockId = parameter["api_kdock_id"].int else { |
16 | 34 | |
17 | 35 | return Logger.shared.log("api_kdock_id is wrong") |
18 | 36 | } |
19 | 37 | |
20 | 38 | let store = ServerDataStore.default |
21 | - | |
22 | - guard let kenzoDock = store.kenzoDock(by: kdockId) else { | |
39 | + guard let kenzoDock = store.sync(execute: { store.kenzoDock(by: kdockId) }) else { | |
23 | 40 | |
24 | - return Logger.shared.log("KenzoDock is not fount") | |
41 | + return Logger.shared.log("KenzoDock is not found") | |
25 | 42 | } |
26 | - | |
27 | - guard let flagShip = store.masterShip(by: kenzoDock.created_ship_id) else { | |
43 | + let kenzoDockInfo = store.sync { | |
44 | + KenzoDockInfo(dockId: kenzoDock.id, | |
45 | + shipId: kenzoDock.created_ship_id, | |
46 | + fuel: kenzoDock.item1, | |
47 | + bull: kenzoDock.item2, | |
48 | + steel: kenzoDock.item3, | |
49 | + bauxite: kenzoDock.item4, | |
50 | + kaihatusizai: kenzoDock.item5) | |
51 | + } | |
52 | + guard let flagShip = store.sync(execute: { store.masterShip(by: kenzoDock.created_ship_id) }) else { | |
28 | 53 | |
29 | 54 | return Logger.shared.log("MasterShip is not found") |
30 | 55 | } |
31 | 56 | |
32 | - let localStore = LocalDataStore.oneTimeEditor() | |
33 | 57 | guard let new = localStore.createKenzoHistory() else { |
34 | 58 | |
35 | 59 | return Logger.shared.log("Can not create KenzoHistory") |
36 | 60 | } |
37 | 61 | |
38 | - new.name = flagShip.name | |
39 | - new.sTypeId = flagShip.stype.id | |
40 | - new.fuel = kenzoDock.item1 | |
41 | - new.bull = kenzoDock.item2 | |
42 | - new.steel = kenzoDock.item3 | |
43 | - new.bauxite = kenzoDock.item4 | |
44 | - new.kaihatusizai = kenzoDock.item5 | |
62 | + new.name = store.sync { flagShip.name } | |
63 | + new.sTypeId = store.sync { flagShip.stype.id } | |
64 | + new.fuel = kenzoDockInfo.fuel | |
65 | + new.bull = kenzoDockInfo.bull | |
66 | + new.steel = kenzoDockInfo.steel | |
67 | + new.bauxite = kenzoDockInfo.bauxite | |
68 | + new.kaihatusizai = kenzoDockInfo.kaihatusizai | |
45 | 69 | new.date = Date() |
46 | - (new.flagShipLv, new.flagShipName, new.commanderLv) = markedValues(kenzoDock: kenzoDock, kdockId: kdockId) | |
70 | + (new.flagShipLv, new.flagShipName, new.commanderLv) = markedValues(docInfo: kenzoDockInfo, in: localStore) | |
47 | 71 | } |
48 | 72 | |
49 | - private func markedValues(kenzoDock: KenzoDock, kdockId: Int) -> (Int, String, Int) { | |
50 | - | |
51 | - let store = LocalDataStore.default | |
73 | + private func markedValues(docInfo: KenzoDockInfo, in store: LocalDataStore) -> (Int, String, Int) { | |
52 | 74 | |
53 | - if let kenzoMark = store.kenzoMark(kenzoDock: kenzoDock, | |
54 | - kDockId: kdockId) { | |
75 | + if let kenzoMark = store.kenzoMark(docInfo: docInfo) { | |
55 | 76 | |
56 | 77 | return (kenzoMark.flagShipLv, kenzoMark.flagShipName, kenzoMark.commanderLv) |
57 | 78 | } |
@@ -80,16 +80,16 @@ extension LocalDataStore { | ||
80 | 80 | return kenzoMarks.first |
81 | 81 | } |
82 | 82 | |
83 | - func kenzoMark(kenzoDock: KenzoDock, kDockId: Int) -> KenzoMark? { | |
83 | + func kenzoMark(docInfo: KenzoMarkCommand.KenzoDockInfo) -> KenzoMark? { | |
84 | 84 | |
85 | 85 | let predicate = NSPredicate.empty |
86 | - .and(NSPredicate(#keyPath(KenzoMark.fuel), equal: kenzoDock.item1)) | |
87 | - .and(NSPredicate(#keyPath(KenzoMark.bull), equal: kenzoDock.item2)) | |
88 | - .and(NSPredicate(#keyPath(KenzoMark.steel), equal: kenzoDock.item3)) | |
89 | - .and(NSPredicate(#keyPath(KenzoMark.bauxite), equal: kenzoDock.item4)) | |
90 | - .and(NSPredicate(#keyPath(KenzoMark.kaihatusizai), equal: kenzoDock.item5)) | |
91 | - .and(NSPredicate(#keyPath(KenzoMark.created_ship_id), equal: kenzoDock.created_ship_id)) | |
92 | - .and(NSPredicate(#keyPath(KenzoMark.kDockId), equal: kDockId)) | |
86 | + .and(NSPredicate(#keyPath(KenzoMark.kDockId), equal: docInfo.dockId)) | |
87 | + .and(NSPredicate(#keyPath(KenzoMark.fuel), equal: docInfo.fuel)) | |
88 | + .and(NSPredicate(#keyPath(KenzoMark.bull), equal: docInfo.bull)) | |
89 | + .and(NSPredicate(#keyPath(KenzoMark.steel), equal: docInfo.steel)) | |
90 | + .and(NSPredicate(#keyPath(KenzoMark.bauxite), equal: docInfo.bauxite)) | |
91 | + .and(NSPredicate(#keyPath(KenzoMark.kaihatusizai), equal: docInfo.kaihatusizai)) | |
92 | + .and(NSPredicate(#keyPath(KenzoMark.created_ship_id), equal: docInfo.shipId)) | |
93 | 93 | |
94 | 94 | guard let kenzoMarks = try? objects(of: KenzoMark.entity, predicate: predicate) else { return nil } |
95 | 95 |
@@ -18,9 +18,10 @@ final class MapInfoCommand: JSONCommand { | ||
18 | 18 | override func execute() { |
19 | 19 | |
20 | 20 | let store = ServerDataStore.oneTimeEditor() |
21 | - | |
22 | - store.airBases().forEach(store.delete) | |
23 | - store.save(errorHandler: store.presentOnMainThread) | |
21 | + store.sync { | |
22 | + store.airBases().forEach(store.delete) | |
23 | + store.save(errorHandler: store.presentOnMainThread) | |
24 | + } | |
24 | 25 | |
25 | 26 | AirBaseMapper(apiResponse).commit() |
26 | 27 | } |
@@ -34,7 +34,7 @@ final class MapStartCommand: JSONCommand { | ||
34 | 34 | |
35 | 35 | private func startBattle() { |
36 | 36 | |
37 | - store.battles().forEach(store.delete) | |
37 | + store.sync { self.store.battles().forEach(self.store.delete) } | |
38 | 38 | |
39 | 39 | guard let deckId = parameter["api_deck_id"].int, |
40 | 40 | let mapArea = parameter["api_maparea_id"].int, |
@@ -48,18 +48,21 @@ final class MapStartCommand: JSONCommand { | ||
48 | 48 | return Logger.shared.log("startBattle JSON is wrong") |
49 | 49 | } |
50 | 50 | |
51 | - guard let battle = store.createBattle() else { | |
51 | + guard let battle = store.sync(execute: { self.store.createBattle() }) else { | |
52 | 52 | |
53 | 53 | return Logger.shared.log("Can not create Battle") |
54 | 54 | } |
55 | 55 | |
56 | 56 | let kcd = ServerDataStore.default |
57 | 57 | |
58 | - battle.deckId = deckId | |
59 | - battle.mapArea = mapArea | |
60 | - battle.mapInfo = mapInfo | |
61 | - battle.no = no | |
62 | - battle.firstFleetShipsCount = kcd.ships(byDeckId: deckId).count | |
58 | + store.sync { | |
59 | + | |
60 | + battle.deckId = deckId | |
61 | + battle.mapArea = mapArea | |
62 | + battle.mapInfo = mapInfo | |
63 | + battle.no = no | |
64 | + battle.firstFleetShipsCount = kcd.sync { kcd.ships(byDeckId: deckId).count } | |
65 | + } | |
63 | 66 | } |
64 | 67 | |
65 | 68 | private func nextCell() { |
@@ -70,14 +73,23 @@ final class MapStartCommand: JSONCommand { | ||
70 | 73 | return Logger.shared.log("updateBattleCell JSON is wrong") |
71 | 74 | } |
72 | 75 | |
73 | - guard let battle = store.battle() else { return Logger.shared.log("Battle is invalid.") } | |
76 | + guard let battle = store.sync(execute: { self.store.battle() }) else { | |
77 | + | |
78 | + return Logger.shared.log("Battle is invalid.") | |
79 | + } | |
74 | 80 | |
75 | - battle.no = cellNumber | |
76 | - battle.isBossCell = (eventId == 5) | |
81 | + store.sync { | |
82 | + | |
83 | + battle.no = cellNumber | |
84 | + battle.isBossCell = (eventId == 5) | |
85 | + } | |
77 | 86 | } |
78 | 87 | |
79 | 88 | private func updateBattleCell() { |
80 | 89 | |
81 | - store.battle().map { $0.battleCell = nil } | |
90 | + store.sync { | |
91 | + | |
92 | + self.store.battle().map { $0.battleCell = nil } | |
93 | + } | |
82 | 94 | } |
83 | 95 | } |
@@ -23,7 +23,9 @@ final class MasterShipMapper: JSONMapper { | ||
23 | 23 | |
24 | 24 | private lazy var masterSTypes: [MasterSType] = { |
25 | 25 | |
26 | - return ServerDataStore.default.sortedMasterSTypesById() | |
26 | + guard let store = configuration.editorStore as? ServerDataStore else { return [] } | |
27 | + | |
28 | + return store.sortedMasterSTypesById() | |
27 | 29 | }() |
28 | 30 | |
29 | 31 | func handleExtraValue(_ value: JSON, forKey key: String, to masterShip: MasterShip) -> Bool { |
@@ -43,6 +43,10 @@ final class MaterialMapper: JSONMapper { | ||
43 | 43 | |
44 | 44 | func commit() { |
45 | 45 | |
46 | + configuration.editorStore.sync(execute: commintInContext) | |
47 | + } | |
48 | + private func commintInContext() { | |
49 | + | |
46 | 50 | guard let store = configuration.editorStore as? ServerDataStore, |
47 | 51 | let material = store.material() ?? store.createMaterial() else { |
48 | 52 |
@@ -18,13 +18,14 @@ final class NyukyoSpeedChangeCommand: JSONCommand { | ||
18 | 18 | override func execute() { |
19 | 19 | |
20 | 20 | let store = ServerDataStore.oneTimeEditor() |
21 | - | |
22 | - let nDock = parameter["api_ndock_id"].int.flatMap(store.nyukyoDock(by:)) | |
23 | - | |
24 | - nDock.flatMap { $0.ship_id }.flatMap(store.ship(by:)).map { $0.nowhp = $0.maxhp } | |
25 | - nDock?.ship_id = 0 | |
26 | - nDock?.state = 0 | |
27 | - | |
28 | - store.material().map { $0.kousokushuhuku = $0.kousokushuhuku - 1 } | |
21 | + store.sync { | |
22 | + let nDock = self.parameter["api_ndock_id"].int.flatMap(store.nyukyoDock(by:)) | |
23 | + | |
24 | + nDock.flatMap { $0.ship_id }.flatMap(store.ship(by:)).map { $0.nowhp = $0.maxhp } | |
25 | + nDock?.ship_id = 0 | |
26 | + nDock?.state = 0 | |
27 | + | |
28 | + store.material().map { $0.kousokushuhuku = $0.kousokushuhuku - 1 } | |
29 | + } | |
29 | 30 | } |
30 | 31 | } |
@@ -20,13 +20,14 @@ final class NyukyoStartCommand: JSONCommand { | ||
20 | 20 | guard let hi = parameter["api_highspeed"].int, hi != 0 else { return } |
21 | 21 | |
22 | 22 | let store = ServerDataStore.oneTimeEditor() |
23 | - | |
24 | - parameter["api_ship_id"] | |
25 | - .int | |
26 | - .flatMap(store.ship(by:)) | |
27 | - .map { $0.nowhp = $0.maxhp } | |
28 | - | |
29 | - store.material() | |
30 | - .map { $0.kousokushuhuku = $0.kousokushuhuku - 1 } | |
23 | + store.sync { | |
24 | + self.parameter["api_ship_id"] | |
25 | + .int | |
26 | + .flatMap(store.ship(by:)) | |
27 | + .map { $0.nowhp = $0.maxhp } | |
28 | + | |
29 | + store.material() | |
30 | + .map { $0.kousokushuhuku = $0.kousokushuhuku - 1 } | |
31 | + } | |
31 | 32 | } |
32 | 33 | } |
@@ -36,31 +36,36 @@ final class QuestListCommand: JSONCommand { | ||
36 | 36 | let lastQuestNumber = questNumberList?.last ?? 9999 |
37 | 37 | let minNo = (page == 1) ? 0 : firstQuestNumber |
38 | 38 | let maxNo = (page == pageCount) ? 9999 : lastQuestNumber |
39 | - store.quests(in: minNo...maxNo).forEach { $0.state = 1 } | |
39 | + store.sync { store.quests(in: minNo...maxNo).forEach { $0.state = 1 } } | |
40 | 40 | |
41 | 41 | // 新しいデータ投入 |
42 | - let quests = store.sortedQuestByNo() | |
42 | + let quests = store.sync { store.sortedQuestByNo() } | |
43 | 43 | questList.forEach { _, quest in |
44 | 44 | |
45 | 45 | guard let no = quest["api_no"].int else { return } |
46 | 46 | |
47 | - let t = quests.binarySearch { $0.no ==? no } | |
47 | + let t = store.sync { quests.binarySearch { $0.no ==? no } } | |
48 | 48 | |
49 | - guard let new = t ?? store.createQuest() else { return Logger.shared.log("Can not create Quest") } | |
49 | + guard let new = t ?? store.sync(execute: { store.createQuest() }) else { | |
50 | + | |
51 | + return Logger.shared.log("Can not create Quest") | |
52 | + } | |
50 | 53 | |
51 | - new.bonus_flag = quest["api_bonus_flag"].int.map { $0 != 0 } ?? false | |
52 | - new.category = quest["api_category"].int ?? 0 | |
53 | - new.detail = quest["api_detail"].string ?? "" | |
54 | -// new.get_material_0 = questData["api_get_material_0"] as? Int ?? 0 | |
55 | -// new.get_material_1 = questData["api_get_material_1"] as? Int ?? 0 | |
56 | -// new.get_material_2 = questData["api_get_material_2"] as? Int ?? 0 | |
57 | -// new.get_material_3 = questData["api_get_material_3"] as? Int ?? 0 | |
58 | - new.invalid_flag = quest["api_invalid_flag"].int ?? 0 | |
59 | - new.no = quest["api_no"].int ?? 0 | |
60 | - new.progress_flag = quest["api_progress_flag"].int ?? 0 | |
61 | - new.state = quest["api_state"].int ?? 0 | |
62 | - new.title = quest["api_title"].string ?? "" | |
63 | - new.type = quest["api_type"].int ?? 0 | |
54 | + store.sync { | |
55 | + new.bonus_flag = quest["api_bonus_flag"].int.map { $0 != 0 } ?? false | |
56 | + new.category = quest["api_category"].int ?? 0 | |
57 | + new.detail = quest["api_detail"].string ?? "" | |
58 | +// new.get_material_0 = questData["api_get_material_0"] as? Int ?? 0 | |
59 | +// new.get_material_1 = questData["api_get_material_1"] as? Int ?? 0 | |
60 | +// new.get_material_2 = questData["api_get_material_2"] as? Int ?? 0 | |
61 | +// new.get_material_3 = questData["api_get_material_3"] as? Int ?? 0 | |
62 | + new.invalid_flag = quest["api_invalid_flag"].int ?? 0 | |
63 | + new.no = quest["api_no"].int ?? 0 | |
64 | + new.progress_flag = quest["api_progress_flag"].int ?? 0 | |
65 | + new.state = quest["api_state"].int ?? 0 | |
66 | + new.title = quest["api_title"].string ?? "" | |
67 | + new.type = quest["api_type"].int ?? 0 | |
68 | + } | |
64 | 69 | } |
65 | 70 | } |
66 | 71 | } |
@@ -13,21 +13,23 @@ final class RealDestroyShipCommand: JSONCommand { | ||
13 | 13 | override func execute() { |
14 | 14 | |
15 | 15 | let store = ServerDataStore.oneTimeEditor() |
16 | - | |
17 | - let ships = parameter["api_ship_id"] | |
18 | - .integerArray | |
19 | - .flatMap(store.ship(by:)) | |
20 | - | |
21 | - if parameter["api_slot_dest_flag"].int == 0 { | |
16 | + store.sync { | |
17 | + | |
18 | + let ships = self.parameter["api_ship_id"] | |
19 | + .integerArray | |
20 | + .flatMap(store.ship(by:)) | |
22 | 21 | |
23 | - // remove allEquipment | |
24 | - ships.forEach { | |
22 | + if self.parameter["api_slot_dest_flag"].int == 0 { | |
23 | + | |
24 | + // remove allEquipment | |
25 | + ships.forEach { | |
25 | 26 | $0.equippedItem = [] |
26 | 27 | $0.extraItem = nil |
28 | + } | |
27 | 29 | } |
30 | + | |
31 | + // destory ships | |
32 | + ships.forEach(store.delete) | |
28 | 33 | } |
29 | - | |
30 | - // destory ships | |
31 | - ships.forEach(store.delete) | |
32 | 34 | } |
33 | 35 | } |
@@ -13,10 +13,11 @@ final class RealPowerUpCommand: JSONCommand { | ||
13 | 13 | override func execute() { |
14 | 14 | |
15 | 15 | let store = ServerDataStore.oneTimeEditor() |
16 | - | |
17 | - parameter["api_id_items"] | |
18 | - .integerArray | |
19 | - .flatMap(store.ship(by:)) | |
20 | - .forEach(store.delete) | |
16 | + store.sync { | |
17 | + self.parameter["api_id_items"] | |
18 | + .integerArray | |
19 | + .flatMap(store.ship(by:)) | |
20 | + .forEach(store.delete) | |
21 | + } | |
21 | 22 | } |
22 | 23 | } |
@@ -20,32 +20,33 @@ final class RemodelSlotItemCommand: JSONCommand { | ||
20 | 20 | |
21 | 21 | let afterSlot = data["api_after_slot"] |
22 | 22 | let store = ServerDataStore.oneTimeEditor() |
23 | - | |
24 | - guard let slotItem = store.slotItem(by: slotItemId) else { | |
23 | + store.sync { | |
24 | + guard let slotItem = store.slotItem(by: slotItemId) else { | |
25 | + | |
26 | + return Logger.shared.log("SlotItem not found") | |
27 | + } | |
25 | 28 | |
26 | - return Logger.shared.log("SlotItem not found") | |
27 | - } | |
28 | - | |
29 | - if let locked = afterSlot["api_locked"].int { | |
30 | - | |
31 | - slotItem.locked = (locked != 0) | |
32 | - } | |
33 | - if let masterSlotItemId = afterSlot["api_slotitem_id"].int, | |
34 | - masterSlotItemId != slotItem.slotitem_id, | |
35 | - let masterSlotItem = store.masterSlotItem(by: slotItemId) { | |
29 | + if let locked = afterSlot["api_locked"].int { | |
30 | + | |
31 | + slotItem.locked = (locked != 0) | |
32 | + } | |
33 | + if let masterSlotItemId = afterSlot["api_slotitem_id"].int, | |
34 | + masterSlotItemId != slotItem.slotitem_id, | |
35 | + let masterSlotItem = store.masterSlotItem(by: slotItemId) { | |
36 | + | |
37 | + slotItem.master_slotItem = masterSlotItem | |
38 | + slotItem.slotitem_id = slotItemId | |
39 | + | |
40 | + } | |
41 | + if let level = afterSlot["api_level"].int { | |
42 | + | |
43 | + slotItem.level = level | |
44 | + } | |
36 | 45 | |
37 | - slotItem.master_slotItem = masterSlotItem | |
38 | - slotItem.slotitem_id = slotItemId | |
46 | + // remove used slot items. | |
47 | + guard let useSlot = self.data["api_use_slot_id"].arrayObject as? [Int] else { return } | |
39 | 48 | |
49 | + store.slotItems(in: useSlot).forEach(store.delete) | |
40 | 50 | } |
41 | - if let level = afterSlot["api_level"].int { | |
42 | - | |
43 | - slotItem.level = level | |
44 | - } | |
45 | - | |
46 | - // remove used slot items. | |
47 | - guard let useSlot = data["api_use_slot_id"].arrayObject as? [Int] else { return } | |
48 | - | |
49 | - store.slotItems(in: useSlot).forEach(store.delete) | |
50 | 51 | } |
51 | 52 | } |
@@ -14,6 +14,6 @@ final class ResetSortie { | ||
14 | 14 | |
15 | 15 | let store = TemporaryDataStore.oneTimeEditor() |
16 | 16 | |
17 | - store.battles().forEach(store.delete) | |
17 | + store.sync { store.battles().forEach(store.delete) } | |
18 | 18 | } |
19 | 19 | } |
@@ -63,40 +63,41 @@ final class ResourceHistoryManager: NSObject { | ||
63 | 63 | return Logger.shared.log("ResourceHistoryManager: Can not get Material") |
64 | 64 | } |
65 | 65 | |
66 | - guard let basic = store.basic() else { | |
66 | + guard let experience = store.sync(execute: { store.basic()?.experience }) else { | |
67 | 67 | |
68 | 68 | return Logger.shared.log("ResourceHistoryManager: Can not get Basic") |
69 | 69 | } |
70 | 70 | |
71 | 71 | let historyStore = ResourceHistoryDataStore.oneTimeEditor() |
72 | - | |
73 | - guard let newHistory = historyStore.createResource() else { | |
72 | + historyStore.sync { | |
73 | + guard let newHistory = historyStore.createResource() else { | |
74 | + | |
75 | + return Logger.shared.log("ResourceHistoryManager: Can not create ResourceHIstory") | |
76 | + } | |
77 | + | |
78 | + let now = Date() | |
79 | + var nowComp = Calendar.current | |
80 | + .dateComponents([.year, .month, .day, .hour, .minute], from: now) | |
81 | + let minutes = nowComp.minute.map { ($0 + 2) / 5 } ?? 0 | |
82 | + nowComp.minute = minutes * 5 | |
74 | 83 | |
75 | - return Logger.shared.log("ResourceHistoryManager: Can not create ResourceHIstory") | |
84 | + newHistory.date = Calendar.current.date(from: nowComp)! | |
85 | + newHistory.minute = (minutes != 60) ? minutes : 0 | |
86 | + newHistory.fuel = store.sync { material.fuel } | |
87 | + newHistory.bull = store.sync { material.bull } | |
88 | + newHistory.steel = store.sync { material.steel } | |
89 | + newHistory.bauxite = store.sync { material.bauxite } | |
90 | + newHistory.kaihatusizai = store.sync { material.kaihatusizai } | |
91 | + newHistory.kousokukenzo = store.sync { material.kousokukenzo } | |
92 | + newHistory.kousokushuhuku = store.sync { material.kousokushuhuku } | |
93 | + newHistory.screw = store.sync { material.screw } | |
94 | + newHistory.experience = experience | |
76 | 95 | } |
77 | - | |
78 | - let now = Date() | |
79 | - var nowComp = Calendar.current | |
80 | - .dateComponents([.year, .month, .day, .hour, .minute], from: now) | |
81 | - let minutes = nowComp.minute.map { ($0 + 2) / 5 } ?? 0 | |
82 | - nowComp.minute = minutes * 5 | |
83 | - | |
84 | - newHistory.date = Calendar.current.date(from: nowComp)! | |
85 | - newHistory.minute = (minutes != 60) ? minutes : 0 | |
86 | - newHistory.fuel = material.fuel | |
87 | - newHistory.bull = material.bull | |
88 | - newHistory.steel = material.steel | |
89 | - newHistory.bauxite = material.bauxite | |
90 | - newHistory.kaihatusizai = material.kaihatusizai | |
91 | - newHistory.kousokukenzo = material.kousokukenzo | |
92 | - newHistory.kousokushuhuku = material.kousokushuhuku | |
93 | - newHistory.screw = material.screw | |
94 | - newHistory.experience = basic.experience | |
95 | 96 | } |
96 | 97 | |
97 | 98 | private func reduceResourceByConditions(_ store: ResourceHistoryDataStore, _ target: [Int], _ ago: Date) { |
98 | 99 | |
99 | - store.resources(in: target, older: ago).forEach(store.delete) | |
100 | + store.sync { store.resources(in: target, older: ago).forEach(store.delete) } | |
100 | 101 | } |
101 | 102 | |
102 | 103 | private func dateOfMonth(_ month: Int) -> Date { |
@@ -27,10 +27,11 @@ final class SetActionCommand: JSONCommand { | ||
27 | 27 | if rIds.count != actions.count { print("missmatch count") } |
28 | 28 | |
29 | 29 | let store = ServerDataStore.oneTimeEditor() |
30 | - | |
31 | - zip(rIds, actions).forEach { (rId, action) in | |
32 | - | |
33 | - store.airBase(area: areaId, base: rId)?.action_kind = action | |
30 | + store.sync { | |
31 | + zip(rIds, actions).forEach { rId, action in | |
32 | + | |
33 | + store.airBase(area: areaId, base: rId)?.action_kind = action | |
34 | + } | |
34 | 35 | } |
35 | 36 | } |
36 | 37 | } |
@@ -37,29 +37,31 @@ final class SetPlaneCommand: JSONCommand { | ||
37 | 37 | } |
38 | 38 | |
39 | 39 | let store = ServerDataStore.oneTimeEditor() |
40 | - | |
41 | - guard let airbase = store.airBase(area: areaId, base: rId) else { | |
40 | + store.sync { | |
42 | 41 | |
43 | - return Logger.shared.log("AirBase is not found") | |
44 | - } | |
45 | - | |
46 | - let planes = airbase.planeInfo | |
47 | - | |
48 | - guard planes.count >= squadronId, | |
49 | - let plane = planes[squadronId - 1] as? AirBasePlaneInfo else { | |
42 | + guard let airbase = store.airBase(area: areaId, base: rId) else { | |
50 | 43 | |
51 | - return Logger.shared.log("AirBase is wrong") | |
44 | + return Logger.shared.log("AirBase is not found") | |
45 | + } | |
46 | + | |
47 | + let planes = airbase.planeInfo | |
48 | + | |
49 | + guard planes.count >= squadronId, | |
50 | + let plane = planes[squadronId - 1] as? AirBasePlaneInfo else { | |
51 | + | |
52 | + return Logger.shared.log("AirBase is wrong") | |
53 | + } | |
54 | + | |
55 | + // TODO: state が 2 の時のみ cond, count, max_count がnilであることを許すようにする | |
56 | + plane.cond = planInfo["api_cond"].int ?? 0 | |
57 | + plane.slotid = slotid | |
58 | + plane.state = state | |
59 | + plane.count = planInfo["api_count"].int ?? 0 | |
60 | + plane.max_count = planInfo["api_max_count"].int ?? 0 | |
61 | + | |
62 | + airbase.distance = distance | |
63 | + | |
64 | + self.data["api_after_bauxite"].int.map { store.material()?.bauxite = $0 } | |
52 | 65 | } |
53 | - | |
54 | - // TODO: state が 2 の時のみ cond, count, max_count がnilであることを許すようにする | |
55 | - plane.cond = planInfo["api_cond"].int ?? 0 | |
56 | - plane.slotid = slotid | |
57 | - plane.state = state | |
58 | - plane.count = planInfo["api_count"].int ?? 0 | |
59 | - plane.max_count = planInfo["api_max_count"].int ?? 0 | |
60 | - | |
61 | - airbase.distance = distance | |
62 | - | |
63 | - data["api_after_bauxite"].int.map { store.material()?.bauxite = $0 } | |
64 | 66 | } |
65 | 67 | } |
@@ -61,12 +61,18 @@ final class ShipMapper: JSONMapper { | ||
61 | 61 | private var registerIds: [Int] = [] |
62 | 62 | private lazy var masterShips: [MasterShip] = { |
63 | 63 | |
64 | - return ServerDataStore.default.sortedMasterShipsById() | |
64 | + guard let store = configuration.editorStore as? ServerDataStore else { return [] } | |
65 | + | |
66 | + return store.sortedMasterShipsById() | |
67 | + | |
65 | 68 | }() |
66 | 69 | private lazy var slotItems: [SlotItem] = { |
67 | 70 | |
68 | - return ServerDataStore.default.sortedSlotItemsById() | |
71 | + guard let store = configuration.editorStore as? ServerDataStore else { return [] } | |
72 | + | |
73 | + return store.sortedSlotItemsById() | |
69 | 74 | }() |
75 | + | |
70 | 76 | private var needsDeleteUnregisteredShip: Bool { |
71 | 77 | |
72 | 78 | switch apiResponse.api.endpoint { |
@@ -68,30 +68,31 @@ final class ShipMasterDetailWindowController: NSWindowController { | ||
68 | 68 | @IBAction func applySally(_ sender: AnyObject?) { |
69 | 69 | |
70 | 70 | let store = ServerDataStore.oneTimeEditor() |
71 | - | |
72 | - guard let i = selectedShip?.objectID else { return } | |
73 | - guard let ship = store.object(of: Ship.entity, with: i) else { return } | |
74 | -// | |
75 | -// ship.sally_area = sally.integerValue as NSNumber | |
76 | - | |
77 | - let eq = ship.equippedItem.array | |
78 | - let slotId = sally.integerValue | |
79 | - | |
80 | - let pos = min(4, eq.count) | |
81 | - | |
82 | - if eq.count > 4 { | |
71 | + store.sync { | |
72 | + guard let i = self.selectedShip?.objectID else { return } | |
73 | + guard let ship = store.object(of: Ship.entity, with: i) else { return } | |
74 | + // | |
75 | + // ship.sally_area = sally.integerValue as NSNumber | |
83 | 76 | |
84 | - ship.equippedItem = NSOrderedSet(array: Array(eq.dropLast())) | |
85 | - } | |
86 | - | |
87 | - if let slotItem = store.slotItem(by: slotId) { | |
77 | + let eq = ship.equippedItem.array | |
78 | + let slotId = self.sally.integerValue | |
79 | + | |
80 | + let pos = min(4, eq.count) | |
88 | 81 | |
89 | - ship.setItem(slotId, to: pos) | |
82 | + if eq.count > 4 { | |
83 | + | |
84 | + ship.equippedItem = NSOrderedSet(array: Array(eq.dropLast())) | |
85 | + } | |
90 | 86 | |
91 | - ship.equippedItem = NSOrderedSet(array: ship.equippedItem.array + [slotItem]) | |
87 | + if let slotItem = store.slotItem(by: slotId) { | |
88 | + | |
89 | + ship.setItem(slotId, to: pos) | |
90 | + | |
91 | + ship.equippedItem = NSOrderedSet(array: ship.equippedItem.array + [slotItem]) | |
92 | + } | |
93 | + | |
94 | + store.save(errorHandler: {_ in}) | |
92 | 95 | } |
93 | - | |
94 | - store.save(errorHandler: {_ in}) | |
95 | 96 | } |
96 | 97 | } |
97 | 98 |
@@ -38,7 +38,10 @@ final class SlotItemMapper: JSONMapper { | ||
38 | 38 | |
39 | 39 | private var registerIds: [Int] = [] |
40 | 40 | private lazy var masterSlotItems: [MasterSlotItem] = { |
41 | - return ServerDataStore.default.sortedMasterSlotItemsById() | |
41 | + | |
42 | + guard let store = configuration.editorStore as? ServerDataStore else { return [] } | |
43 | + | |
44 | + return store.sortedMasterSlotItemsById() | |
42 | 45 | }() |
43 | 46 | |
44 | 47 | func beginRegister(_ slotItem: SlotItem) { |
@@ -18,31 +18,33 @@ final class SlotResetCommand: JSONCommand { | ||
18 | 18 | override func execute() { |
19 | 19 | |
20 | 20 | let store = ServerDataStore.oneTimeEditor() |
21 | - | |
22 | - guard let ship = parameter["api_id"].int.flatMap(store.ship(by:)) else { | |
23 | - | |
24 | - return Logger.shared.log("api_id is wrong") | |
25 | - } | |
26 | - guard let slotItems = data["api_slot"].arrayObject as? [Int] else { | |
21 | + store.sync { | |
27 | 22 | |
28 | - return Logger.shared.log("Can not parse api_data.api_slot") | |
29 | - } | |
30 | - | |
31 | - zip(slotItems, 0...).forEach(ship.setItem) | |
32 | - | |
33 | - let storedSlotItems = store.sortedSlotItemsById() | |
34 | - let newSet = slotItems | |
35 | - .flatMap { slotItem -> SlotItem? in | |
23 | + guard let ship = self.parameter["api_id"].int.flatMap(store.ship(by:)) else { | |
36 | 24 | |
37 | - guard slotItem > 0 else { return nil } | |
25 | + return Logger.shared.log("api_id is wrong") | |
26 | + } | |
27 | + guard let slotItems = self.data["api_slot"].arrayObject as? [Int] else { | |
38 | 28 | |
39 | - let found = storedSlotItems.binarySearch { $0.id ==? slotItem } | |
40 | - if let item = found { return item } | |
41 | - print("Item \(slotItem) is not found") | |
42 | - | |
43 | - return nil | |
29 | + return Logger.shared.log("Can not parse api_data.api_slot") | |
30 | + } | |
31 | + | |
32 | + zip(slotItems, 0...).forEach(ship.setItem) | |
33 | + | |
34 | + let storedSlotItems = store.sortedSlotItemsById() | |
35 | + let newSet = slotItems | |
36 | + .flatMap { slotItem -> SlotItem? in | |
37 | + | |
38 | + guard slotItem > 0 else { return nil } | |
39 | + | |
40 | + let found = storedSlotItems.binarySearch { $0.id ==? slotItem } | |
41 | + if let item = found { return item } | |
42 | + print("Item \(slotItem) is not found") | |
43 | + | |
44 | + return nil | |
45 | + } | |
46 | + | |
47 | + ship.equippedItem = NSOrderedSet(array: newSet) | |
44 | 48 | } |
45 | - | |
46 | - ship.equippedItem = NSOrderedSet(array: newSet) | |
47 | 49 | } |
48 | 50 | } |
@@ -26,31 +26,35 @@ final class StoreCreateSlotItemHistoryCommand: JSONCommand { | ||
26 | 26 | let numberOfUsedKaihatuSizai = (success != 0 ? 1 : 0) |
27 | 27 | |
28 | 28 | let store = ServerDataStore.default |
29 | - | |
30 | - guard let flagShip = store.deck(by: 1)?[0] else { | |
29 | + guard let flagShip = store.sync(execute: { store.deck(by: 1)?[0] }) else { | |
31 | 30 | |
32 | 31 | return Logger.shared.log("Flagship is not found") |
33 | 32 | } |
34 | 33 | |
35 | - guard let basic = store.basic() else { return print("Basic is wrong") } | |
34 | + guard let commanderLv = store.sync(execute: { store.basic()?.level }) else { | |
35 | + | |
36 | + return print("Basic is wrong") | |
37 | + } | |
36 | 38 | |
37 | 39 | let localStore = LocalDataStore.oneTimeEditor() |
38 | - | |
39 | - guard let newHistory = localStore.createKaihatuHistory() else { | |
40 | + guard let newHistory = localStore.sync(execute: { localStore.createKaihatuHistory() }) else { | |
40 | 41 | |
41 | 42 | return Logger.shared.log("Can not create new KaihatuHistory entry") |
42 | 43 | } |
43 | 44 | |
44 | - newHistory.name = name | |
45 | - newHistory.fuel = fuel | |
46 | - newHistory.bull = bull | |
47 | - newHistory.steel = steel | |
48 | - newHistory.bauxite = bauxite | |
49 | - newHistory.kaihatusizai = numberOfUsedKaihatuSizai | |
50 | - newHistory.flagShipLv = flagShip.lv | |
51 | - newHistory.flagShipName = flagShip.name | |
52 | - newHistory.commanderLv = basic.level | |
53 | - newHistory.date = Date() | |
45 | + localStore.sync { | |
46 | + | |
47 | + newHistory.name = name | |
48 | + newHistory.fuel = fuel | |
49 | + newHistory.bull = bull | |
50 | + newHistory.steel = steel | |
51 | + newHistory.bauxite = bauxite | |
52 | + newHistory.kaihatusizai = numberOfUsedKaihatuSizai | |
53 | + newHistory.flagShipLv = store.sync { flagShip.lv } | |
54 | + newHistory.flagShipName = store.sync { flagShip.name } | |
55 | + newHistory.commanderLv = commanderLv | |
56 | + newHistory.date = Date() | |
57 | + } | |
54 | 58 | } |
55 | 59 | |
56 | 60 | private func masterSlotItemName(sccess: Int, data: JSON) -> String { |
@@ -65,6 +69,7 @@ final class StoreCreateSlotItemHistoryCommand: JSONCommand { | ||
65 | 69 | return Logger.shared.log("api_slotitem_id is wrong", value: "") |
66 | 70 | } |
67 | 71 | |
68 | - return ServerDataStore.default.masterSlotItem(by: slotItemId)?.name ?? "" | |
72 | + let store = ServerDataStore.default | |
73 | + return store.sync { store.masterSlotItem(by: slotItemId)?.name ?? "" } | |
69 | 74 | } |
70 | 75 | } |
@@ -95,10 +95,17 @@ final class TSVSupport { | ||
95 | 95 | |
96 | 96 | guard $0 == .OK else { return } |
97 | 97 | guard let url = panel.url else { return } |
98 | - guard let kaihatuHistory = self.dataOfKaihatuHistory() else { return } | |
99 | - guard let kenzoHistory = self.dataOfKenzoHistory() else { return } | |
100 | - guard let kenzoMark = self.dataOfKenzoMark() else { return } | |
101 | - guard let dropShipHistory = self.dataOfDropShipHistory() else { return } | |
98 | + | |
99 | + let data = self.store.sync { () -> (Data, Data, Data, Data)? in | |
100 | + | |
101 | + guard let kaihatuHistory = self.dataOfKaihatuHistory() else { return nil } | |
102 | + guard let kenzoHistory = self.dataOfKenzoHistory() else { return nil } | |
103 | + guard let kenzoMark = self.dataOfKenzoMark() else { return nil } | |
104 | + guard let dropShipHistory = self.dataOfDropShipHistory() else { return nil } | |
105 | + | |
106 | + return (kaihatuHistory, kenzoHistory, kenzoMark, dropShipHistory) | |
107 | + } | |
108 | + guard let (kaihatuHistory, kenzoHistory, kenzoMark, dropShipHistory) = data else { return } | |
102 | 109 | |
103 | 110 | let fileW = FileWrapper(directoryWithFileWrappers: [:]) |
104 | 111 | fileW.addRegularFile(withContents: kaihatuHistory, preferredFilename: "kaihatu.tsv") |
@@ -217,7 +224,6 @@ final class TSVSupport { | ||
217 | 224 | private func registerKaihatuHistory(_ data: Data) { |
218 | 225 | |
219 | 226 | let array = String(data: data, encoding: .utf8)?.components(separatedBy: "\n") |
220 | - let store = LocalDataStore.oneTimeEditor() | |
221 | 227 | array?.forEach { |
222 | 228 | |
223 | 229 | let attr = $0.components(separatedBy: "\t") |
@@ -254,7 +260,6 @@ final class TSVSupport { | ||
254 | 260 | private func registerKenzoHistory(_ data: Data) { |
255 | 261 | |
256 | 262 | let array = String(data: data, encoding: .utf8)?.components(separatedBy: "\n") |
257 | - let store = LocalDataStore.oneTimeEditor() | |
258 | 263 | |
259 | 264 | array?.forEach { |
260 | 265 |
@@ -294,7 +299,6 @@ final class TSVSupport { | ||
294 | 299 | private func registerKenzoMark( _ data: Data) { |
295 | 300 | |
296 | 301 | let array = String(data: data, encoding: .utf8)?.components(separatedBy: "\n") |
297 | - let store = LocalDataStore.oneTimeEditor() | |
298 | 302 | |
299 | 303 | array?.forEach { |
300 | 304 |
@@ -335,7 +339,6 @@ final class TSVSupport { | ||
335 | 339 | private func registerDropShipHistory( _ data: Data) { |
336 | 340 | |
337 | 341 | let array = String(data: data, encoding: .utf8)?.components(separatedBy: "\n") |
338 | - let store = LocalDataStore.oneTimeEditor() | |
339 | 342 | |
340 | 343 | array?.forEach { |
341 | 344 |
@@ -13,13 +13,14 @@ final class UpdateQuestListCommand: JSONCommand { | ||
13 | 13 | override func execute() { |
14 | 14 | |
15 | 15 | let store = ServerDataStore.oneTimeEditor() |
16 | - | |
17 | - parameter["api_quest_id"] | |
18 | - .int | |
19 | - .flatMap(store.quest(by:)) | |
20 | - .map { | |
21 | - $0.progress_flag = 0 | |
22 | - $0.state = 1 | |
16 | + store.sync { | |
17 | + self.parameter["api_quest_id"] | |
18 | + .int | |
19 | + .flatMap(store.quest(by:)) | |
20 | + .map { | |
21 | + $0.progress_flag = 0 | |
22 | + $0.state = 1 | |
23 | + } | |
23 | 24 | } |
24 | 25 | } |
25 | 26 | } |
@@ -23,17 +23,19 @@ final class UpdateSlotItemCommand: JSONCommand { | ||
23 | 23 | |
24 | 24 | let store = ServerDataStore.oneTimeEditor() |
25 | 25 | |
26 | - guard let masterSlotItem = store.masterSlotItem(by: slotItemId) else { | |
26 | + guard let masterSlotItem = store.sync(execute: { store.masterSlotItem(by: slotItemId) }) else { | |
27 | 27 | |
28 | 28 | return Logger.shared.log("MasterSlotItem is not found") |
29 | 29 | } |
30 | 30 | |
31 | - guard let new = store.createSlotItem() else { | |
31 | + guard let new = store.sync(execute: { store.createSlotItem() }) else { | |
32 | 32 | |
33 | 33 | return Logger.shared.log("Can not create new SlotItem") |
34 | 34 | } |
35 | 35 | |
36 | - new.id = newSlotItemId | |
37 | - new.master_slotItem = masterSlotItem | |
36 | + store.sync { | |
37 | + new.id = newSlotItemId | |
38 | + new.master_slotItem = masterSlotItem | |
39 | + } | |
38 | 40 | } |
39 | 41 | } |