import Cocoa
-final class DocksViewController: MainTabVIewItemViewController {
+protocol DockInformationUpdater: class {
- deinit {
-
- [#keyPath(deck2Time), #keyPath(mission2Name),
- #keyPath(deck3Time), #keyPath(mission3Name),
- #keyPath(deck4Time), #keyPath(mission4Name)]
- .forEach { unbind($0) }
- [#keyPath(nDock1Time), #keyPath(nDock1ShipName),
- #keyPath(nDock2Time), #keyPath(nDock2ShipName),
- #keyPath(nDock3Time), #keyPath(nDock3ShipName),
- #keyPath(nDock4Time), #keyPath(nDock4ShipName)]
- .forEach { unbind($0) }
- [#keyPath(kDock1Time), #keyPath(kDock2Time), #keyPath(kDock3Time), #keyPath(kDock4Time)]
- .forEach { unbind($0) }
-
- ["selection", "selection.no", "content.battleCell"]
- .forEach {
- battleContoller.removeObserver(self, forKeyPath: $0)
- }
- }
+ func update()
+}
+
+final class DocksViewController: MainTabVIewItemViewController {
- let managedObjectContext = ServerDataStore.default.context
- let battleManagedObjectController = TemporaryDataStore.default.context
+ @objc let managedObjectContext = ServerDataStore.default.context
let questListViewController = QuestListViewController()
+ let battleInfoViewController = BattleInformationViewController()
- let missionStates = (2...4).flatMap { MissionStatus(number: $0) }
- let ndockStatus = (1...4).flatMap { NyukyoDockStatus(number: $0) }
- let kdockStatus = (1...4).flatMap { KenzoDockStatus(number: $0) }
+ private var updaters: [DockInformationUpdater] = []
- var nDock1Time: NSNumber?
- var nDock2Time: NSNumber?
- var nDock3Time: NSNumber?
- var nDock4Time: NSNumber?
+ @objc dynamic var nDock1Time: NSNumber?
+ @objc dynamic var nDock2Time: NSNumber?
+ @objc dynamic var nDock3Time: NSNumber?
+ @objc dynamic var nDock4Time: NSNumber?
- var nDock1ShipName: String?
- var nDock2ShipName: String?
- var nDock3ShipName: String?
- var nDock4ShipName: String?
+ @objc dynamic var nDock1ShipName: String?
+ @objc dynamic var nDock2ShipName: String?
+ @objc dynamic var nDock3ShipName: String?
+ @objc dynamic var nDock4ShipName: String?
- var kDock1Time: NSNumber?
- var kDock2Time: NSNumber?
- var kDock3Time: NSNumber?
- var kDock4Time: NSNumber?
+ @objc dynamic var kDock1Time: NSNumber?
+ @objc dynamic var kDock2Time: NSNumber?
+ @objc dynamic var kDock3Time: NSNumber?
+ @objc dynamic var kDock4Time: NSNumber?
- var deck2Time: NSNumber?
- var deck3Time: NSNumber?
- var deck4Time: NSNumber?
+ @objc dynamic var deck2Time: NSNumber?
+ @objc dynamic var deck3Time: NSNumber?
+ @objc dynamic var deck4Time: NSNumber?
- var mission2Name: String?
- var mission3Name: String?
- var mission4Name: String?
+ @objc dynamic var mission2Name: String?
+ @objc dynamic var mission3Name: String?
+ @objc dynamic var mission4Name: String?
- @IBOutlet var battleContoller: NSObjectController!
- @IBOutlet weak var questListViewPlaceholder: NSView!
- @IBOutlet weak var cellNumberField: NSTextField!
+ @IBOutlet private weak var battleInformationViewPlaceholder: NSView!
+ @IBOutlet private weak var questListViewPlaceholder: NSView!
- override var nibName: String! {
+ override var nibName: NSNib.Name {
- return "DocksViewController"
+ return .nibName(instanceOf: self)
}
- var battle: Battle? {
-
- return TemporaryDataStore.default.battle()
- }
-
- var cellNumber: Int {
-
- return battleContoller.value(forKeyPath: "content.no") as? Int ?? 0
- }
-
- var battleCellNumber: Int {
-
- return battleContoller.value(forKeyPath: "content.battleCell") as? Int ?? 0
- }
-
- var isBossCell: Bool {
+ override func viewDidLoad() {
- return battleContoller.value(forKeyPath: "content.isBossCell") as? Bool ?? false
- }
-
- var fleetName: String? {
+ super.viewDidLoad()
- guard let deckId = battleContoller.value(forKeyPath: "content.deckId") as? Int
- else { return nil }
+ setupStatus()
- return ServerDataStore.default.deck(by: deckId)?.name
+ replace(view: battleInformationViewPlaceholder, with: battleInfoViewController)
+ replace(view: questListViewPlaceholder, with: questListViewController)
}
- var areaNumber: String? {
-
- let mapArea: String = {
+ private func setupStatus() {
+
+ (2...4).forEach {
- guard let mapArea = battleContoller.value(forKeyPath: "content.mapArea") as? Int
- else { return "" }
+ createMissionSatusFuture(number: $0)
+ .onSuccess { status in
+
+ self.updaters += [status]
+ status.delegate = self
+ }
+ .onFailure { error in
+
+ Logger.shared.log("\(error)")
+ }
+ }
+
+ (1...4).forEach {
- if mapArea > 10 { return "E" }
+ createNyukyoDockStatusFuture(number: $0)
+ .onSuccess { status in
+
+ self.updaters += [status]
+ status.delegate = self
+ }
+ .onFailure { error in
+
+ Logger.shared.log("\(error)")
+ }
- return "\(mapArea)"
- }()
-
- guard mapArea != "" else { return nil }
-
- guard let mapInfo = battleContoller.value(forKeyPath: "content.mapInfo") as? Int
- else { return "" }
-
- return "\(mapArea)-\(mapInfo)"
- }
-
- var areaName: String? {
-
- guard let mapArea = battleContoller.value(forKeyPath: "content.mapArea") as? Int,
- let mapInfo = battleContoller.value(forKeyPath: "content.mapInfo") as? Int
- else { return nil }
+ createKenzoDockStatusFuture(number: $0)
+ .onSuccess { status in
+
+ self.updaters += [status]
+ status.delegate = self
+ }
+ .onFailure { error in
+
+ Logger.shared.log("\(error)")
+ }
+ }
- return ServerDataStore.default.mapInfo(area: mapArea, no: mapInfo)?.name
+ AppDelegate.shared.addCounterUpdate {
+
+ self.updaters.forEach { $0.update() }
+ }
}
+}
+
+extension DocksViewController: MissionStatusObserver {
- var sortieString: String? {
-
- guard let fleetName = self.fleetName,
- let areaName = self.areaName,
- let areaNumber = self.areaNumber
- else { return nil }
+ func didUpdate(state: MissionStatus) {
- if battleCellNumber == 0 {
+ switch state.number {
- let format = NSLocalizedString("%@ in sortie into %@ (%@)", comment: "Sortie")
+ case 2:
+ deck2Time = state.time.map { $0 as NSNumber }
+ mission2Name = state.name
- return String(format: format, arguments: [fleetName, areaName, areaNumber])
- }
- if isBossCell {
+ case 3:
+ deck3Time = state.time.map { $0 as NSNumber }
+ mission3Name = state.name
- let format = NSLocalizedString("%@ battle against the enemy main fleet at %@ war zone in %@ (%@) now", comment: "Sortie")
+ case 4:
+ deck4Time = state.time.map { $0 as NSNumber }
+ mission4Name = state.name
- return String(format: format, arguments: [fleetName, battleCellNumber as NSNumber, areaName, areaNumber])
- }
-
- let format = NSLocalizedString("%@ battle at %@ war zone in %@ (%@) now", comment: "Sortie")
-
- return String(format: format, arguments: [fleetName, battleCellNumber as NSNumber, areaName, areaNumber])
- }
-
- override func viewDidLoad() {
-
- super.viewDidLoad()
-
- setupStatus()
-
- AppDelegate.shared.addCounterUpdate {
+ default: ()
- self.missionStates.forEach { $0.update() }
- self.kdockStatus.forEach { $0.update() }
- self.ndockStatus.forEach { $0.update() }
}
-
- questListViewController.view.frame = questListViewPlaceholder.frame
- questListViewController.view.autoresizingMask = questListViewPlaceholder.autoresizingMask
- questListViewPlaceholder.superview?.replaceSubview(questListViewPlaceholder, with: questListViewController.view)
-
- ["selection", "selection.no", "content.battleCell"]
- .forEach {
- battleContoller.addObserver(self, forKeyPath: $0, context: nil)
- }
-
- #if DEBUG
- cellNumberField.isHidden = false
- #endif
}
+}
+
+extension DocksViewController: NyukyoDockStatusObserver {
- override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey: Any]?, context: UnsafeMutableRawPointer?) {
+ func didUpdate(state: NyukyoDockStatus) {
- if keyPath == "selection" || keyPath == "content.battleCell" {
+ switch state.number {
- notifyChangeValue(forKey: #keyPath(sortieString))
+ case 1:
+ nDock1Time = state.time.map { $0 as NSNumber }
+ nDock1ShipName = state.name
- return
- }
-
- if keyPath == "selection.no" {
+ case 2:
+ nDock2Time = state.time.map { $0 as NSNumber }
+ nDock2ShipName = state.name
+
+ case 3:
+ nDock3Time = state.time.map { $0 as NSNumber }
+ nDock3ShipName = state.name
- notifyChangeValue(forKey: #keyPath(cellNumber))
+ case 4:
+ nDock4Time = state.time.map { $0 as NSNumber }
+ nDock4ShipName = state.name
+
+ default: ()
- return
}
-
- super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
+}
+
+extension DocksViewController: KenzoDockStatusObserver {
- private func setupStatus() {
-
- let missionKeys = [
- (#keyPath(deck2Time), #keyPath(mission2Name)),
- (#keyPath(deck3Time), #keyPath(mission3Name)),
- (#keyPath(deck4Time), #keyPath(mission4Name))
- ]
- zip(missionStates, missionKeys).forEach {
-
- bind($0.1.0, to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
- bind($0.1.1, to: $0.0, withKeyPath: #keyPath(MissionStatus.name), options: nil)
- }
+ func didUpdate(state: KenzoDockStatus) {
- let ndockKeys = [
- (#keyPath(nDock1Time), #keyPath(nDock1ShipName)),
- (#keyPath(nDock2Time), #keyPath(nDock2ShipName)),
- (#keyPath(nDock3Time), #keyPath(nDock3ShipName)),
- (#keyPath(nDock4Time), #keyPath(nDock4ShipName))
- ]
- zip(ndockStatus, ndockKeys).forEach {
-
- bind($0.1.0, to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
- bind($0.1.1, to: $0.0, withKeyPath: #keyPath(MissionStatus.name), options: nil)
- }
+ switch state.number {
+
+ case 1:
+ kDock1Time = state.time.map { $0 as NSNumber }
- let kdockKeys = [#keyPath(kDock1Time), #keyPath(kDock2Time), #keyPath(kDock3Time), #keyPath(kDock4Time)]
- zip(kdockStatus, kdockKeys).forEach {
+ case 2:
+ kDock2Time = state.time.map { $0 as NSNumber }
+
+ case 3:
+ kDock3Time = state.time.map { $0 as NSNumber }
+
+ case 4:
+ kDock4Time = state.time.map { $0 as NSNumber }
+
+ default: ()
- bind($0.1, to: $0.0, withKeyPath: #keyPath(MissionStatus.time), options: nil)
}
}
-
}