OSDN Git Service

AppDelegateからウインドウに関する部分を分離した
[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 fileprivate extension Selector {
12     static let notifyIfNeeded = #selector(ResourceHistoryManager.notifyIfNeeded(_:))
13 }
14
15 class ResourceHistoryManager: NSObject {
16     private let periodicNotification: PeriodicNotifier
17     
18     override init() {
19         periodicNotification = PeriodicNotifier(hour: 23, minutes: 3)
20         super.init()
21         notifyIfNeeded(nil)
22         NotificationCenter.default
23         .addObserver(forName: .Periodic,
24                      object: periodicNotification,
25                      queue: nil,
26                      using: reduce)
27     }
28     
29     private var timer: Timer?
30     
31     @objc fileprivate func notifyIfNeeded(_ timer: Timer?) {
32         if timer != nil { saveResources() }
33         if let valid = timer?.isValid, valid { timer?.invalidate() }
34         
35         let now = Date()
36         var nowComp = Calendar.current
37             .dateComponents([.year, .month, .day, .hour, .minute], from: now)
38         // 現在時刻を超える最小の5分刻みの分
39         nowComp.minute = nowComp.minute
40             .flatMap { $0 + 5 }
41             .flatMap { ($0 + 2) / 5 }
42             .flatMap { $0 * 5 }
43         guard let notifyDate = Calendar.current.date(from: nowComp)
44             else { return print("ResourceHistoryManager: Can not create notify date") }
45         let notifyTime = notifyDate.timeIntervalSinceNow
46         self.timer = Timer.scheduledTimer(timeInterval: notifyTime,
47                                           target: self,
48                                           selector: .notifyIfNeeded,
49                                           userInfo: nil,
50                                           repeats: false)
51     }
52     private func saveResources() {
53         let store = ServerDataStore.default
54         guard let material = store.material()
55             else { return print("ResourceHistoryManager: Can not get Material") }
56         guard let basic = store.basic()
57             else { return print("ResourceHistoryManager: Can not get Basic") }
58         
59         let historyStore = ResourceHistoryDataStore.oneTimeEditor()
60         guard let newHistory = historyStore.cerateResource()
61             else { return print("ResourceHistoryManager: Can not create ResourceHIstory") }
62         let now = Date()
63         var nowComp = Calendar.current
64             .dateComponents([.year, .month, .day, .hour, .minute], from: now)
65         var minutes = nowComp.minute.map { ($0 + 2) / 5 } ?? 0
66         minutes *= 5
67         nowComp.minute = minutes
68         
69         newHistory.date = Calendar.current.date(from: nowComp)!
70         newHistory.minute = (minutes != 60) ? minutes : 0
71         newHistory.fuel = material.fuel
72         newHistory.bull = material.bull
73         newHistory.steel = material.steel
74         newHistory.bauxite = material.bauxite
75         newHistory.kaihatusizai = material.kaihatusizai
76         newHistory.kousokukenzo = material.kousokukenzo
77         newHistory.kousokushuhuku = material.kousokushuhuku
78         newHistory.screw = material.screw
79         newHistory.experience = basic.experience 
80     }
81     private func reduceResourceByConditions(_ store: ResourceHistoryDataStore,
82                                             _ target: [Int],
83                                             _ ago: Date) {
84         store.resources(in: target, older: ago).forEach { store.delete($0) }
85     }
86     private func dateOfMonth(_ month: Int) -> Date {
87         return Date(timeIntervalSinceNow: TimeInterval(month * 30 * 24 * 60 * 60))
88     }
89     private func reduce(_ notification: Notification) {
90         let queue = DispatchQueue(label: "ResourceHistoryManager")
91         queue.async {
92             let store = ResourceHistoryDataStore.oneTimeEditor()
93             
94             // 1 month
95             self.reduceResourceByConditions(store,
96                                             [5, 10, 20, 25, 35, 40, 50, 55],
97                                             self.dateOfMonth(-1))
98             
99             // 3 months
100             self.reduceResourceByConditions(store,
101                                             [5, 10, 15, 20, 25, 35, 40, 45, 50, 55],
102                                             self.dateOfMonth(-3))
103             
104             // 6 manths
105             self.reduceResourceByConditions(store,
106                                             [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55],
107                                             self.dateOfMonth(-6))
108         }
109     }
110 }