-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
CoreDataStore.swift
197 lines (165 loc) · 8.37 KB
/
CoreDataStore.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
//
// CoreDataStore.swift
// Aeon Garden
//
// Created by Brad Root on 10/4/19.
// Copyright © 2019 Brad Root. All rights reserved.
//
import CoreData
import Foundation
class CoreDataStore {
static let standard: CoreDataStore = CoreDataStore()
var mainManagedObjectContext: NSManagedObjectContext
var persistentContainer: NSPersistentContainer
init() {
persistentContainer = {
let container = NSPersistentContainer(name: "AeonGarden")
container.loadPersistentStores(completionHandler: { _, error in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
mainManagedObjectContext = persistentContainer.viewContext
}
deinit {
self.saveContext()
}
func saveContext() {
if mainManagedObjectContext.hasChanges {
do {
try mainManagedObjectContext.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate.
// You should not use this function in a shipping application, although it
// may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
extension CoreDataStore: DataStoreProtocol {
// MARK: - Creature Favorites
func saveCreature(_ creature: Creature) {
fatalError()
}
func deleteCreature(_ creature: Creature) {
fatalError()
}
func getCreatures(completion: @escaping ([Creature]) -> Void) {
fatalError()
}
// MARK: - Tanks
func getTanks(completion: @escaping ([Tank]) -> Void) {
mainManagedObjectContext.perform {
do {
let fetchRequest: NSFetchRequest<ManagedTank> = ManagedTank.fetchRequest()
let managedTanks = try self.mainManagedObjectContext.fetch(fetchRequest) as [ManagedTank]
var tanks: [Tank] = []
for managedTank in managedTanks {
tanks.append(managedTank.toStruct())
}
completion(tanks)
} catch {
completion([])
}
}
}
func saveTank(_ tank: Tank) {
mainManagedObjectContext.perform {
do {
// Check for tank in storage by UUID
var storedTank: ManagedTank?
let fetchRequest: NSFetchRequest<ManagedTank> = ManagedTank.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "uuid == %@", tank.uuid.uuidString)
if let tank = try? self.mainManagedObjectContext.fetch(fetchRequest).first {
storedTank = tank
} else {
storedTank = ManagedTank(context: self.mainManagedObjectContext)
}
guard let managedTank = storedTank else {
Log.error("Could not load or create new managed tank object!")
return
}
managedTank.timestamp = Date()
managedTank.birthCount = Int16(tank.birthCount)
managedTank.deathCount = Int16(tank.deathCount)
managedTank.tankTime = tank.tankTime
managedTank.uuid = tank.uuid
var managedCreatures: [ManagedTankCreature] = []
for creature in tank.creatures {
let managedTankCreature = ManagedTankCreature(context: self.mainManagedObjectContext)
managedTankCreature.uuid = creature.uuid
managedTankCreature.firstName = creature.firstName
managedTankCreature.lastName = creature.lastName
managedTankCreature.currentHealth = creature.currentHealth
managedTankCreature.lifeTime = creature.lifeTime
managedTankCreature.isFavorite = creature.isFavorite
managedTankCreature.movementSpeed = creature.movementSpeed
managedTankCreature.turnSpeed = creature.turnSpeed
managedTankCreature.sizeModifier = creature.sizeModifier
managedTankCreature.primaryHue = creature.primaryHue
managedTankCreature.positionX = creature.positionX
managedTankCreature.positionY = creature.positionY
var managedLimbs: [ManagedLimb] = []
for limb in creature.limbs {
let managedLimb = ManagedLimb(context: self.mainManagedObjectContext)
managedLimb.shape = limb.shape.rawValue
managedLimb.hue = limb.hue
managedLimb.blend = limb.blend
managedLimb.brightness = limb.brightness
managedLimb.saturation = limb.saturation
managedLimb.limbWidth = Int16(limb.limbWidth)
managedLimb.wiggleFactor = limb.wiggleFactor
managedLimb.wiggleMoveFactor = limb.wiggleMoveFactor
managedLimb.wiggleMoveBackFactor = limb.wiggleMoveBackFactor
managedLimb.wiggleActionDuration = limb.wiggleActionDuration
managedLimb.wiggleActionBackDuration = limb.wiggleActionBackDuration
managedLimb.wiggleActionMovementDuration = limb.wiggleActionMovementDuration
managedLimb.wiggleActionMovementBackDuration = limb.wiggleActionMovementBackDuration
managedLimb.limbzRotation = limb.limbzRotation
managedLimb.positionX = limb.positionX
managedLimb.positionY = limb.positionY
managedLimbs.append(managedLimb)
}
managedTankCreature.limbs = NSSet(array: managedLimbs)
managedCreatures.append(managedTankCreature)
}
managedTank.creatures = NSSet(array: managedCreatures)
var managedBubbles: [ManagedBubble] = []
for bubble in tank.bubbles {
let managedBubble = ManagedBubble(context: self.mainManagedObjectContext)
managedBubble.positionY = bubble.positionY
managedBubble.positionX = bubble.positionX
managedBubbles.append(managedBubble)
}
managedTank.bubbles = NSSet(array: managedBubbles)
var managedFoods: [ManagedFood] = []
for food in tank.food {
let managedFood = ManagedFood(context: self.mainManagedObjectContext)
managedFood.positionY = food.positionY
managedFood.positionX = food.positionX
managedFoods.append(managedFood)
}
managedTank.food = NSSet(array: managedFoods)
let managedTankSettings = ManagedTankSettings(context: self.mainManagedObjectContext)
managedTankSettings.foodMaxAmount = Int16(tank.tankSettings.foodMaxAmount)
managedTankSettings.foodHealthRestorationBaseValue = tank.tankSettings.foodHealthRestorationBaseValue
managedTankSettings.foodSpawnRate = Int16(tank.tankSettings.foodSpawnRate)
managedTankSettings.creatureInitialAmount = Int16(tank.tankSettings.creatureInitialAmount)
managedTankSettings.creatureMinimumAmount = Int16(tank.tankSettings.creatureMinimumAmount)
managedTankSettings.creatureSpawnRate = Int16(tank.tankSettings.creatureSpawnRate)
managedTankSettings.creatureBirthSuccessRate = tank.tankSettings.creatureBirthSuccessRate
managedTankSettings.backgroundParticleBirthrate = Int16(tank.tankSettings.backgroundParticleBirthrate)
managedTankSettings.backgroundParticleLifetime = Int16(tank.tankSettings.backgroundParticleLifetime)
managedTank.tankSettings = managedTankSettings
try self.mainManagedObjectContext.save()
} catch {
Log.error("Tank failed to save to storage.")
}
}
}
}