OSDN Git Service

d6ec349d84f7861ab88395477809b5c09c6209c8
[kcd/KCD.git] / KCD / ResourceHistoryManager.swift
1 //
2 //  ResourceHistoryManager.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/22.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 private extension Selector {
12     
13     static let notifyIfNeeded = #selector(ResourceHistoryManager.notifyIfNeeded(_:))
14 }
15
16 final class ResourceHistoryManager: NSObject {
17     
18     private let periodicNotification: PeriodicNotifier
19     
20     override init() {
21         
22         periodicNotification = PeriodicNotifier(hour: 23, minutes: 3)
23         
24         super.init()
25         
26         notifyIfNeeded(nil)
27         NotificationCenter.default
28             .addObserver(forName: .Periodic,
29                          object: periodicNotification,
30                          queue: nil,
31                          using: reduce)
32     }
33     
34     private var timer: Timer?
35     
36     @objc fileprivate func notifyIfNeeded(_ timer: Timer?) {
37         
38         if timer != nil { saveResources() }
39         if let valid = timer?.isValid, valid { timer?.invalidate() }
40         
41         let now = Date()
42         var nowComp = Calendar.current
43             .dateComponents([.year, .month, .day, .hour, .minute], from: now)
44         // 現在時刻を超える最小の5分刻みの分
45         nowComp.minute = nowComp.minute
46             .flatMap { $0 + 5 }
47             .flatMap { ($0 + 2) / 5 }
48             .flatMap { $0 * 5 }
49         
50         guard let notifyDate = Calendar.current.date(from: nowComp) else {
51             
52             print("ResourceHistoryManager: Can not create notify date")
53             return
54         }
55         
56         let notifyTime = notifyDate.timeIntervalSinceNow
57         self.timer = Timer.scheduledTimer(timeInterval: notifyTime,
58                                           target: self,
59                                           selector: .notifyIfNeeded,
60                                           userInfo: nil,
61                                           repeats: false)
62     }
63     
64     private func saveResources() {
65         
66         let store = ServerDataStore.default
67         
68         guard let material = store.material() else {
69             
70             print("ResourceHistoryManager: Can not get Material")
71             return
72         }
73         
74         guard let basic = store.basic() else {
75             
76             print("ResourceHistoryManager: Can not get Basic")
77             return
78         }
79         
80         let historyStore = ResourceHistoryDataStore.oneTimeEditor()
81         
82         guard let newHistory = historyStore.cerateResource() else {
83             
84             print("ResourceHistoryManager: Can not create ResourceHIstory")
85             return
86         }
87         
88         let now = Date()
89         var nowComp = Calendar.current
90             .dateComponents([.year, .month, .day, .hour, .minute], from: now)
91         var minutes = nowComp.minute.map { ($0 + 2) / 5 } ?? 0
92         minutes *= 5
93         nowComp.minute = minutes
94         
95         newHistory.date = Calendar.current.date(from: nowComp)!
96         newHistory.minute = (minutes != 60) ? minutes : 0
97         newHistory.fuel = material.fuel
98         newHistory.bull = material.bull
99         newHistory.steel = material.steel
100         newHistory.bauxite = material.bauxite
101         newHistory.kaihatusizai = material.kaihatusizai
102         newHistory.kousokukenzo = material.kousokukenzo
103         newHistory.kousokushuhuku = material.kousokushuhuku
104         newHistory.screw = material.screw
105         newHistory.experience = basic.experience
106     }
107     
108     private func reduceResourceByConditions(_ store: ResourceHistoryDataStore, _ target: [Int], _ ago: Date) {
109         
110         store.resources(in: target, older: ago).forEach { store.delete($0) }
111     }
112     
113     private func dateOfMonth(_ month: Int) -> Date {
114         
115         return Date(timeIntervalSinceNow: TimeInterval(month * 30 * 24 * 60 * 60))
116     }
117     
118     private func reduce(_ notification: Notification) {
119         
120         let queue = DispatchQueue(label: "ResourceHistoryManager")
121         queue.async {
122             
123             let store = ResourceHistoryDataStore.oneTimeEditor()
124             
125             // 1 month
126             self.reduceResourceByConditions(store,
127                                             [5, 10, 20, 25, 35, 40, 50, 55],
128                                             self.dateOfMonth(-1))
129             
130             // 3 months
131             self.reduceResourceByConditions(store,
132                                             [5, 10, 15, 20, 25, 35, 40, 45, 50, 55],
133                                             self.dateOfMonth(-3))
134             
135             // 6 manths
136             self.reduceResourceByConditions(store,
137                                             [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55],
138                                             self.dateOfMonth(-6))
139         }
140     }
141 }