Skip to content

Commit

Permalink
Merge pull request #15 from amiantos/remove-notification-center
Browse files Browse the repository at this point in the history
Remove use of NotificationCenter
  • Loading branch information
amiantos authored Jan 31, 2022
2 parents bcf8fe8 + 2a32660 commit 28f203e
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 100 deletions.
172 changes: 87 additions & 85 deletions Shared/Scene/Animations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,56 +37,104 @@ class Animation {
animationType = animation
}

public func actions(clocks: [ClockNode], clusters: [ClusterNode]) -> SKAction {
public func actions(clocks: [ClockNode], clusters: [ClusterNode], completionHandler: @escaping () -> Void, timeSetCompletionHandler: @escaping (String) -> Void) -> SKAction {

switch animationType {
case .spinBothHands:
return spinBothHands(clocks: clocks)
return spinBothHands(clocks: clocks, completionHandler: completionHandler)
case .currentTimePrint:
return currentTimePrint(clusters: clusters)
return currentTimePrint(clusters: clusters, completionHandler: completionHandler, timeSetCompletionHandler: timeSetCompletionHandler)
case .currentTimeClock:
return currentTimeClock(clocks: clocks)
return currentTimeClock(clocks: clocks, completionHandler: completionHandler)
case .wait:
return wait(clocks: clocks)
return wait(clocks: clocks, completionHandler: completionHandler)
case .positionBothHands:
return positionBothHands(clocks: clocks)
return positionBothHands(clocks: clocks, completionHandler: completionHandler)
case .spinBothHandsWithDelay:
return spinBothHandsWithDelay(clusters: clusters)
return spinBothHandsWithDelay(clusters: clusters, completionHandler: completionHandler)
case .displayPattern:
return displayPattern(clusters: clusters)
return displayPattern(clusters: clusters, completionHandler: completionHandler)
case .print:
return print(clusters: clusters)
return print(clusters: clusters, completionHandler: completionHandler)
}

}

// Static methods for queuing animations

static func spinBothHands(by degrees: CGFloat) -> Animation {
let animation = Animation(animation: .spinBothHands)
animation.degrees = degrees
return animation
}

static func printString(string: String) -> Animation {
let animation = Animation(animation: .print)
animation.string = string
return animation
}

static func currentTimePrint() -> Animation {
return Animation(animation: .currentTimePrint)
}

static func currentTimeClock() -> Animation {
return Animation(animation: .currentTimeClock)
}

static func wait(duration: TimeInterval) -> Animation {
let animation = Animation(animation: .wait)
animation.duration = duration
return animation
}

static func positionBothHands(minuteDegrees: CGFloat, hourDegrees: CGFloat) -> Animation {
let animation = Animation(animation: .positionBothHands)
animation.minuteDegrees = minuteDegrees
animation.hourDegrees = hourDegrees
return animation
}

static func spinBothHandsWithDelay(by degrees: CGFloat, delay: TimeInterval) -> Animation {
let animation = Animation(animation: .spinBothHandsWithDelay)
animation.degrees = degrees
animation.delay = delay
return animation
}

static func display(pattern: [Int: [(CGFloat, CGFloat)]]) -> Animation {
let animation = Animation(animation: .displayPattern)
animation.pattern = pattern
return animation
}

// Animations

private func wait(clocks: [ClockNode]) -> SKAction {
private func wait(clocks: [ClockNode], completionHandler: @escaping () -> Void) -> SKAction {
Log.debug("Waiting for \(self.duration) seconds...")
var actions: [SKAction] = []
clocks.forEach { clock in
actions.append(SKAction.run {
let action = SKAction.wait(forDuration: self.duration)
clock.run(action) {
NotificationCenter.default.post(name: NSNotification.Name("AnimationComplete"), object: nil)
NotificationCenter.default.post(name: NSNotification.Name("AnimationComplete"), object: nil)
completionHandler()
completionHandler()
}
})
}
return SKAction.group(actions)
}

private func positionBothHands(clocks: [ClockNode]) -> SKAction {
private func positionBothHands(clocks: [ClockNode], completionHandler: @escaping () -> Void) -> SKAction {
Log.debug("Positioning minute hands to \(self.minuteDegrees), hour hands to \(self.hourDegrees)...")
var actions: [SKAction] = []
clocks.forEach { clock in
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: self.minuteDegrees, hourDegrees: self.hourDegrees))
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: self.minuteDegrees, hourDegrees: self.hourDegrees, completionHandler: completionHandler))
}
return SKAction.group(actions)
}

private func print(clusters: [ClusterNode]) -> SKAction {
private func print(clusters: [ClusterNode], completionHandler: @escaping () -> Void) -> SKAction {
var actions: [SKAction] = []

let array = string.map(String.init)
Expand All @@ -95,7 +143,7 @@ class Animation {
if let numberConfig = numberConfigs[Int(array[index])!] {
for (index, item) in numberConfig.enumerated() {
let clock = cluster.clocks[index]
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: item.1, hourDegrees: item.0))
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: item.1, hourDegrees: item.0, completionHandler: completionHandler))
}
}

Expand All @@ -104,7 +152,7 @@ class Animation {
return SKAction.group(actions)
}

private func currentTimePrint(clusters: [ClusterNode]) -> SKAction {
private func currentTimePrint(clusters: [ClusterNode], completionHandler: @escaping () -> Void, timeSetCompletionHandler: @escaping (String) -> Void) -> SKAction {
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "hhmm"
Expand All @@ -122,18 +170,18 @@ class Animation {
if let numberConfig = numberConfigs[Int(array[index])!] {
for (index, item) in numberConfig.enumerated() {
let clock = cluster.clocks[index]
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: item.1, hourDegrees: item.0))
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: item.1, hourDegrees: item.0, completionHandler: completionHandler))
}
}

}

NotificationCenter.default.post(name: NSNotification.Name("SetCurrentTime"), object: nil, userInfo: ["time": timeString])
timeSetCompletionHandler(timeString)

return SKAction.group(actions)
}

private func currentTimeClock(clocks: [ClockNode]) -> SKAction {
private func currentTimeClock(clocks: [ClockNode], completionHandler: @escaping () -> Void) -> SKAction {
Log.debug("Displaying current time as clocks...")
let date = Date()
let minute = Int(date.get(.minute))!
Expand All @@ -145,31 +193,31 @@ class Animation {

var actions: [SKAction] = []
clocks.forEach { clock in
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: -CGFloat(((360/60)*minute)), hourDegrees: -CGFloat(((360/12)*hourFloat))))
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: -CGFloat(((360/60)*minute)), hourDegrees: -CGFloat(((360/12)*hourFloat)), completionHandler: completionHandler))
}
return SKAction.group(actions)
}

private func spinBothHands(clocks: [ClockNode]) -> SKAction {
private func spinBothHands(clocks: [ClockNode], completionHandler: @escaping () -> Void) -> SKAction {
Log.debug("Spinning all hands \(self.degrees) degrees...")
var actions: [SKAction] = []
clocks.forEach { clock in
actions.append(getActionGroupForSpin(clock: clock, degrees: self.degrees))
actions.append(getActionGroupForSpin(clock: clock, degrees: self.degrees, completionHandler: completionHandler))
}
return SKAction.group(actions)
}

private func spinBothHandsWithDelay(clusters: [ClusterNode]) -> SKAction {
private func spinBothHandsWithDelay(clusters: [ClusterNode], completionHandler: @escaping () -> Void) -> SKAction {
Log.debug("Spinning all hands \(self.degrees) degrees, with \(self.delay) seconds delay...")
var actions: [SKAction] = []
var currentDelay: TimeInterval = 0

clusters.forEach { cluster in

var clockActions: [SKAction] = []
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[0], degrees: self.degrees))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[2], degrees: self.degrees))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[4], degrees: self.degrees))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[0], degrees: self.degrees, completionHandler: completionHandler))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[2], degrees: self.degrees, completionHandler: completionHandler))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[4], degrees: self.degrees, completionHandler: completionHandler))

actions.append(SKAction.sequence([
SKAction.wait(forDuration: currentDelay),
Expand All @@ -180,9 +228,9 @@ class Animation {

clockActions.removeAll()

clockActions.append(getActionGroupForSpin(clock: cluster.clocks[1], degrees: self.degrees))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[3], degrees: self.degrees))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[5], degrees: self.degrees))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[1], degrees: self.degrees, completionHandler: completionHandler))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[3], degrees: self.degrees, completionHandler: completionHandler))
clockActions.append(getActionGroupForSpin(clock: cluster.clocks[5], degrees: self.degrees, completionHandler: completionHandler))

actions.append(SKAction.sequence([
SKAction.wait(forDuration: currentDelay),
Expand All @@ -194,7 +242,7 @@ class Animation {
return SKAction.group(actions)
}

private func displayPattern(clusters: [ClusterNode]) -> SKAction {
private func displayPattern(clusters: [ClusterNode], completionHandler: @escaping () -> Void) -> SKAction {
Log.debug("Displaying pattern...")

var actions: [SKAction] = []
Expand All @@ -203,7 +251,7 @@ class Animation {
if let patternConfig = self.pattern[index] {
for (index, item) in patternConfig.enumerated() {
let clock = cluster.clocks[index]
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: item.1, hourDegrees: item.0))
actions.append(getActionGroupForPosition(clock: clock, minuteDegrees: item.1, hourDegrees: item.0, completionHandler: completionHandler))
}
}

Expand All @@ -214,14 +262,14 @@ class Animation {

// Utils

private func getActionGroupForPosition(clock: ClockNode, minuteDegrees: CGFloat, hourDegrees: CGFloat) -> SKAction {
private func getActionGroupForPosition(clock: ClockNode, minuteDegrees: CGFloat, hourDegrees: CGFloat, completionHandler: @escaping () -> Void) -> SKAction {
let radianDifference = getRadianDifference(startDegrees: clock.minuteHandNode.zRotation.radiansToDegrees(), endDegrees: -minuteDegrees)
let duration = radianDifference / movementSpeed

let minuteHandAction = SKAction.run {
let action = SKAction.rotate(byAngle: -radianDifference, duration: duration)
clock.minuteHandNode.run(action) {
NotificationCenter.default.post(name: NSNotification.Name("AnimationComplete"), object: nil)
completionHandler()
}
}

Expand All @@ -231,27 +279,27 @@ class Animation {
let hourHandAction = SKAction.run {
let action = SKAction.rotate(byAngle: -radianDifferenceHour, duration: durationHour)
clock.hourHandNode.run(action) {
NotificationCenter.default.post(name: NSNotification.Name("AnimationComplete"), object: nil)
completionHandler()
}
}

return SKAction.group([minuteHandAction, hourHandAction])
}

private func getActionGroupForSpin(clock: ClockNode, degrees: CGFloat) -> SKAction {
private func getActionGroupForSpin(clock: ClockNode, degrees: CGFloat, completionHandler: @escaping () -> Void) -> SKAction {
let radians = degrees.degreesToRadians()
let minuteHandAction = SKAction.run {
let action = SKAction.rotate(byAngle: -radians, duration: radians / self.movementSpeed)

clock.minuteHandNode.run(action) {
NotificationCenter.default.post(name: NSNotification.Name("AnimationComplete"), object: nil)
completionHandler()
}
}
let hourHandAction = SKAction.run {
let action = SKAction.rotate(byAngle: -radians, duration: radians / self.movementSpeed)

clock.hourHandNode.run(action) {
NotificationCenter.default.post(name: NSNotification.Name("AnimationComplete"), object: nil)
completionHandler()
}
}
return SKAction.group([minuteHandAction, hourHandAction])
Expand All @@ -273,53 +321,7 @@ class Animation {
return distanceInDegrees.degreesToRadians()
}

// Static methods for queuing animations

static func spinBothHands(by degrees: CGFloat) -> Animation {
let animation = Animation(animation: .spinBothHands)
animation.degrees = degrees
return animation
}

static func printString(string: String) -> Animation {
let animation = Animation(animation: .print)
animation.string = string
return animation
}

static func currentTimePrint() -> Animation {
return Animation(animation: .currentTimePrint)
}

static func currentTimeClock() -> Animation {
return Animation(animation: .currentTimeClock)
}

static func wait(duration: TimeInterval) -> Animation {
let animation = Animation(animation: .wait)
animation.duration = duration
return animation
}

static func positionBothHands(minuteDegrees: CGFloat, hourDegrees: CGFloat) -> Animation {
let animation = Animation(animation: .positionBothHands)
animation.minuteDegrees = minuteDegrees
animation.hourDegrees = hourDegrees
return animation
}

static func spinBothHandsWithDelay(by degrees: CGFloat, delay: TimeInterval) -> Animation {
let animation = Animation(animation: .spinBothHandsWithDelay)
animation.degrees = degrees
animation.delay = delay
return animation
}

static func display(pattern: [Int: [(CGFloat, CGFloat)]]) -> Animation {
let animation = Animation(animation: .displayPattern)
animation.pattern = pattern
return animation
}
// Pattern Generators

static func randomizedPattern() -> [Int: [(CGFloat, CGFloat)]] {
return [
Expand Down
25 changes: 10 additions & 15 deletions Shared/Scene/ClockController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ class ClockController {
Log.useEmoji = true

updateInterval = TimeInterval(1)

NotificationCenter.default.addObserver(self, selector: #selector(animationCompleted), name: NSNotification.Name("AnimationComplete"), object: nil)

NotificationCenter.default.addObserver(self, selector: #selector(setCurrentTime(_:)), name: NSNotification.Name("SetCurrentTime"), object: nil)
}

public func start() {
Expand All @@ -71,15 +67,6 @@ class ClockController {

// MARK: - Timer

@objc func setCurrentTime(_ notification: NSNotification) {
if let time = notification.userInfo?["time"] as? String {
if time != lastTimeDisplayed {
Log.debug("New displayed time: \(time)")
lastTimeDisplayed = time
}
}
}

@objc func updateTime() {
let date = Date()
let dateFormatter = DateFormatter()
Expand Down Expand Up @@ -220,7 +207,7 @@ class ClockController {

// MARK: - Animations

@objc func animationCompleted() {
private func animationCompleted() {
timeSinceLastAnimation = 0
animationsCompleted += 1
if animationsCompleted == 48 {
Expand All @@ -236,8 +223,16 @@ class ClockController {
}
}


private func setCurrentTime(time: String) {
if time != lastTimeDisplayed {
Log.debug("New displayed time: \(time)")
lastTimeDisplayed = time
}
}

private func run(_ animation: Animation) {
let actionGroup = animation.actions(clocks: clocks, clusters: clusters)
let actionGroup = animation.actions(clocks: clocks, clusters: clusters, completionHandler: animationCompleted, timeSetCompletionHandler: setCurrentTime)
isAnimating = true
timeSinceLastAnimation = 0
scene?.run(actionGroup)
Expand Down

0 comments on commit 28f203e

Please sign in to comment.