OSDN Git Service

staticプロパティをインスタンスプロパティに変更
[kcd/KCD.git] / KCD / NyukyoDockStatus.swift
1 //
2 //  NyukyoDockStatus.swift
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2017/01/23.
6 //  Copyright © 2017年 Hori,Masaki. All rights reserved.
7 //
8
9 import Cocoa
10
11 protocol NyukyoDockStatusObserver: class {
12     
13     func didUpdate(state: NyukyoDockStatus)
14 }
15
16 protocol NyukyoDockObserverDelegate: class {
17     
18     func didChangeState(dock: NyukyoDock)
19 }
20
21 final class NyukyoDockObserver {
22     
23     private let dock: NyukyoDock
24     private var observation: NSKeyValueObservation?
25     
26     weak var delegate: NyukyoDockObserverDelegate? {
27         
28         didSet {
29             delegate?.didChangeState(dock: dock)
30         }
31     }
32     
33     init(dock: NyukyoDock) {
34         
35         self.dock = dock
36         
37         observation = dock.observe(\NyukyoDock.state) { _, _ in
38             
39             self.delegate?.didChangeState(dock: self.dock)
40         }
41     }
42 }
43
44 final class NyukyoDockStatus: NSObject {
45     
46     private enum DockState: Int {
47         
48         case empty = 0
49         
50         case hasShip = 1
51         
52         case unknown = 999999
53     }
54     
55     static func valid(number: Int) -> Bool {
56         
57         return  1...4 ~= number
58     }
59
60     let number: Int
61     private let observer: NyukyoDockObserver
62     
63     private(set) var name: String?
64     private(set) var time: TimeInterval?
65     
66     private var state: DockState = .unknown
67     
68     private var rawState: Int = 0 {
69         
70         didSet {
71             
72             state = DockState(rawValue: rawState) ?? .unknown
73         }
74     }
75     private var shipId: Int = 0
76     private var completeTime: Int = 0
77     
78     private var didNotify = false
79     
80     weak var delegate: NyukyoDockStatusObserver?
81     
82     /// CAUTION: 初回起動時/マスタ更新時にはデータがないので失敗する
83     init?(number: Int) {
84         
85         guard NyukyoDockStatus.valid(number: number) else {
86             
87             return nil
88         }
89         
90         self.number = number
91         
92         guard let dock = ServerDataStore.default.nyukyoDock(by: number) else {
93             
94             return nil
95         }
96         
97         self.observer = NyukyoDockObserver(dock: dock)
98         
99         super.init()
100                 
101         observer.delegate = self
102     }
103     
104     private func updateState() {
105         
106         switch state {
107             
108         case .empty:
109             didNotify = false
110             name = nil
111             time = nil
112             
113         case .hasShip:
114             name = ServerDataStore.default.ship(by: shipId)?.name ?? "Unknown"
115             
116         case .unknown:
117             Logger.shared.log("unknown State")
118             
119         }
120         
121         delegate?.didUpdate(state: self)
122     }
123 }
124
125 extension NyukyoDockStatus: DockInformationUpdater {
126     
127     func update() {
128         
129         defer {
130             
131             delegate?.didUpdate(state: self)
132         }
133         
134         guard let name = name else {
135             
136             return
137         }
138         
139         let compTime = TimeInterval(Int(completeTime / 1_000))
140         let diff = compTime - Date().timeIntervalSince1970
141         
142         // set to 0. if diff is less than 0.
143         time = max(0, diff)
144         
145         // notify UserNotification.
146         if didNotify {
147             
148             return
149         }
150         if diff >= 1 * 60 {
151             
152             return
153         }
154         
155         let notification = NSUserNotification()
156         let format = LocalizedStrings.dockingWillFinish.string
157         notification.title = String(format: format, name)
158         notification.informativeText = notification.title
159         
160         if UserDefaults.standard[.playFinishNyukyoSound] {
161             
162             notification.soundName = NSUserNotificationDefaultSoundName
163         }
164         
165         NSUserNotificationCenter.default.deliver(notification)
166         
167         didNotify = true
168     }
169 }
170
171 extension NyukyoDockStatus: NyukyoDockObserverDelegate {
172     
173     func didChangeState(dock: NyukyoDock) {
174         
175         rawState = dock.state
176         shipId = dock.ship_id
177         completeTime = dock.complete_time
178         
179         updateState()
180     }
181 }