1
1
mirror of https://github.com/exyte/Macaw.git synced 2024-09-11 13:15:35 +03:00

Display link fix and refactoring

This commit is contained in:
Viktor Sukochev 2017-08-28 10:20:14 +07:00
parent 2f20ef96f1
commit a6fdbe665b
5 changed files with 99 additions and 65 deletions

View File

@ -13,7 +13,7 @@ class AnimationProducer {
var storedAnimations = [Node: BasicAnimation]()
var delayedAnimations = [BasicAnimation: Timer]()
var displayLink: MDisplayLink?
var displayLink: MDisplayLinkProtocol?
struct ContentAnimationDesc {
let animation: ContentsAnimation
@ -329,9 +329,12 @@ class AnimationProducer {
contentsAnimations.append(animationDesc)
if displayLink == nil {
displayLink = MDisplayLink(target: self, selector: #selector(updateContentAnimations))
//displayLink?.frameInterval = 1
displayLink?.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
displayLink = MDisplayLink()
displayLink?.startUpdates { [weak self] in
DispatchQueue.main.async {
self?.updateContentAnimations()
}
}
}
}

View File

@ -0,0 +1,14 @@
//
// MDisplayLink.swift
// Pods
//
// Created by Victor Sukochev on 28/08/2017.
//
//
import Foundation
protocol MDisplayLinkProtocol {
func startUpdates(_ onUpdate: @escaping () -> Void)
func invalidate()
}

View File

@ -26,7 +26,6 @@ import Foundation
public typealias MPinchGestureRecognizer = UIPinchGestureRecognizer
public typealias MRotationGestureRecognizer = UIRotationGestureRecognizer
public typealias MScreen = UIScreen
public typealias MDisplayLink = CADisplayLink
public typealias MViewContentMode = UIViewContentMode
extension MTapGestureRecognizer {

View File

@ -0,0 +1,39 @@
//
// MDisplayLink_iOS.swift
// Pods
//
// Created by Victor Sukochev on 28/08/2017.
//
//
#if os(iOS)
import UIKit
class MDisplayLink: MDisplayLinkProtocol {
private var displayLink: CADisplayLink?
private var onUpdate: (() -> Void)?
// MARK: - Lifecycle
deinit {
displayLink?.invalidate()
}
//MARK: - MDisplayLinkProtocol
func startUpdates(_ onUpdate: @escaping () -> Void) {
self.onUpdate = onUpdate
displayLink = CADisplayLink(target: self, selector: #selector(updateHandler))
displayLink?.frameInterval = 1
displayLink?.add(to: RunLoop.current, forMode: RunLoopMode.defaultRunLoopMode)
}
func invalidate() {
displayLink?.invalidate()
}
// MARK: - Private
@objc func updateHandler() {
onUpdate?()
}
}
#endif

View File

@ -9,68 +9,47 @@
import Foundation
#if os(OSX)
import AppKit
public class MDisplayLink {
private var timer: Timer?
private var displayLink: CVDisplayLink?
private weak var target: AnyObject?
private var selector: Selector
import AppKit
private var _timestamp: CFTimeInterval = 0.0
public var timestamp: CFTimeInterval {
return _timestamp
}
init(target: AnyObject, selector: Selector) {
self.target = target
self.selector = selector
if CVDisplayLinkCreateWithActiveCGDisplays(&displayLink) == kCVReturnSuccess {
public class MDisplayLink: MDisplayLinkProtocol {
private var displayLink: CVDisplayLink?
private var onUpdate: (() -> Void)?
CVDisplayLinkSetOutputCallback(displayLink!, { (displayLink, inNow, inOutputTime, flagsIn, flagsOut, userData) -> CVReturn in
let `self` = unsafeBitCast(userData, to: MDisplayLink.self)
`self`._timestamp = CFAbsoluteTimeGetCurrent()
`self`.target?.performSelector(onMainThread: `self`.selector, with: `self`, waitUntilDone: false)
return kCVReturnSuccess
}, Unmanaged.passUnretained(self).toOpaque())
} else {
timer = Timer(timeInterval: 1.0 / 60.0, target: target, selector: selector, userInfo: nil, repeats: true)
}
}
deinit {
stop()
}
open func invalidate() {
stop()
}
open func add(to runloop: RunLoop, forMode mode: RunLoopMode) {
if displayLink != nil {
CVDisplayLinkStart(displayLink!)
// MARK: - Lifecycle
deinit {
stop()
}
} else if timer != nil {
runloop.add(timer!, forMode: mode)
}
}
open func remove(from: RunLoop, forMode: RunLoopMode) {
stop()
}
private func stop() {
if displayLink != nil {
CVDisplayLinkStop(displayLink!)
}
if timer != nil {
timer?.invalidate()
}
}
}
// MARK: - MDisplayLinkProtocol
func startUpdates(_ onUpdate: @escaping () -> Void) {
self.onUpdate = onUpdate
if CVDisplayLinkCreateWithActiveCGDisplays(&displayLink) != kCVReturnSuccess {
return
}
CVDisplayLinkSetOutputCallback(displayLink!, { (displayLink, inNow, inOutputTime, flagsIn, flagsOut, userData) -> CVReturn in
let `self` = unsafeBitCast(userData, to: MDisplayLink.self)
`self`.onUpdate?()
return kCVReturnSuccess
}, Unmanaged.passUnretained(self).toOpaque())
if displayLink != nil {
CVDisplayLinkStart(displayLink!)
}
}
func invalidate() {
stop()
}
private func stop() {
if displayLink != nil {
CVDisplayLinkStop(displayLink!)
}
}
}
#endif