From eabb1810f040f48bf5bbd2918022e2858c32a005 Mon Sep 17 00:00:00 2001 From: Alisa Mylnikova Date: Wed, 8 May 2019 13:13:50 +0700 Subject: [PATCH] Move layer to renderer --- Source/animation/AnimationProducer.swift | 20 ++- Source/animation/AnimationUtils.swift | 4 +- .../Cache/AnimationCache.swift | 120 +++++++----------- .../MorphingGenerator.swift | 9 +- .../OpacityGenerator.swift | 15 +-- .../ShapeAnimationGenerator.swift | 16 +-- .../TransformGenerator.swift | 16 +-- Source/events/TouchEvent.swift | 6 + Source/platform/macOS/MView_macOS.swift | 2 +- Source/render/GroupRenderer.swift | 9 +- Source/render/ImageRenderer.swift | 4 +- Source/render/NodeRenderer.swift | 46 ++++--- Source/render/RenderUtils.swift | 10 +- Source/render/ShapeRenderer.swift | 6 +- Source/render/TextRenderer.swift | 4 +- Source/utils/CGMappings.swift | 2 +- Source/views/MacawView.swift | 22 +--- Source/views/ShapeLayer.swift | 1 - 18 files changed, 136 insertions(+), 176 deletions(-) diff --git a/Source/animation/AnimationProducer.swift b/Source/animation/AnimationProducer.swift index a72b94a7..af6e9ebd 100644 --- a/Source/animation/AnimationProducer.swift +++ b/Source/animation/AnimationProducer.swift @@ -16,7 +16,6 @@ class AnimationProducer { struct ContentAnimationDesc { let animation: ContentsAnimation - weak var cache: AnimationCache? let startDate: Date let finishDate: Date let completion: (() -> Void)? @@ -90,38 +89,38 @@ class AnimationProducer { return } - guard let layer = macawView.mLayer, let cache = macawView.animationCache else { + guard let layer = macawView.mLayer else { return } // swiftlint:disable superfluous_disable_command switch_case_alignment switch animation.type { case .affineTransformation: - addTransformAnimation(animation, context, sceneLayer: layer, animationCache: cache, completion: { + addTransformAnimation(animation, context, sceneLayer: layer, completion: { if let next = animation.next { self.play(next, context) } }) case .opacity: - addOpacityAnimation(animation, context, sceneLayer: layer, animationCache: cache, completion: { + addOpacityAnimation(animation, context, sceneLayer: layer, completion: { if let next = animation.next { self.play(next, context) } }) case .contents: - addContentsAnimation(animation, context, cache: cache) { + addContentsAnimation(animation, context) { if let next = animation.next { self.play(next, context) } } case .morphing: - addMorphingAnimation(animation, context, sceneLayer: layer, animationCache: cache) { + addMorphingAnimation(animation, context, sceneLayer: layer) { if let next = animation.next { self.play(next, context) } } case .shape: - addShapeAnimation(animation, context, sceneLayer: layer, animationCache: cache) { + addShapeAnimation(animation, context, sceneLayer: layer) { if let next = animation.next { self.play(next, context) } @@ -220,7 +219,7 @@ class AnimationProducer { // MARK: - Contents animation - func addContentsAnimation(_ animation: BasicAnimation, _ context: AnimationContext, cache: AnimationCache?, completion: @escaping (() -> Void)) { + func addContentsAnimation(_ animation: BasicAnimation, _ context: AnimationContext, completion: @escaping (() -> Void)) { guard let contentsAnimation = animation as? ContentsAnimation else { return } @@ -252,7 +251,6 @@ class AnimationProducer { let animationDesc = ContentAnimationDesc( animation: contentsAnimation, - cache: cache, startDate: Date(), finishDate: Date(timeInterval: contentsAnimation.duration, since: startDate), completion: completion @@ -302,7 +300,7 @@ class AnimationProducer { } contentsAnimations.remove(at: count - 1 - index) - animationDesc.cache?.freeLayer(renderer) + renderer.freeLayer() animationDesc.completion?() continue } @@ -315,7 +313,7 @@ class AnimationProducer { if animation.manualStop || animation.paused { defer { contentsAnimations.remove(at: count - 1 - index) - animationDesc.cache?.freeLayer(renderer) + renderer.freeLayer() } if animation.manualStop { diff --git a/Source/animation/AnimationUtils.swift b/Source/animation/AnimationUtils.swift index d1588940..71de54b0 100644 --- a/Source/animation/AnimationUtils.swift +++ b/Source/animation/AnimationUtils.swift @@ -1,9 +1,9 @@ import Foundation -class AnimationUtils { +class AbsoluteUtils { class func absolutePosition(_ nodeRenderer: NodeRenderer?, _ context: AnimationContext) -> Transform { - return AnimationUtils.absoluteTransform(nodeRenderer, context, pos: nodeRenderer?.node.place ?? .identity) + return AbsoluteUtils.absoluteTransform(nodeRenderer, context, pos: nodeRenderer?.node.place ?? .identity) } class func absoluteTransform(_ nodeRenderer: NodeRenderer?, _ context: AnimationContext, pos: Transform) -> Transform { diff --git a/Source/animation/types/animation_generators/Cache/AnimationCache.swift b/Source/animation/types/animation_generators/Cache/AnimationCache.swift index c967536e..f2fc9527 100644 --- a/Source/animation/types/animation_generators/Cache/AnimationCache.swift +++ b/Source/animation/types/animation_generators/Cache/AnimationCache.swift @@ -6,29 +6,12 @@ import UIKit import AppKit #endif -class AnimationCache { +class AnimationUtils { - class CachedLayer { - let rootLayer: ShapeLayer - let animationLayer: ShapeLayer - - required init(rootLayer: ShapeLayer, animationLayer: ShapeLayer) { - self.rootLayer = rootLayer - self.animationLayer = animationLayer - } - } - - weak var sceneLayer: CALayer? - var cache = [NodeRenderer: CachedLayer]() - - required init(sceneLayer: CALayer) { - self.sceneLayer = sceneLayer - } - - func layerForNodeRenderer(_ renderer: NodeRenderer, _ context: AnimationContext, animation: Animation, customBounds: Rect? = .none, shouldRenderContent: Bool = true) -> ShapeLayer { + class func layerForNodeRenderer(_ renderer: NodeRenderer, _ context: AnimationContext, animation: Animation, customBounds: Rect? = .none, shouldRenderContent: Bool = true) -> ShapeLayer { let node = renderer.node - if let cachedLayer = cache[renderer] { + if let cachedLayer = renderer.layer { cachedLayer.rootLayer.transform = CATransform3DMakeAffineTransform(uncachedParentsPlace(renderer).toCG()) cachedLayer.animationLayer.opacity = Float(node.opacity) return cachedLayer.animationLayer @@ -37,19 +20,18 @@ class AnimationCache { // 'sublayer' is for actual CAAnimations, and 'layer' is for manual transforming and hierarchy changes let sublayer = ShapeLayer() sublayer.shouldRenderContent = shouldRenderContent - sublayer.animationCache = self let layer = ShapeLayer() layer.addSublayer(sublayer) layer.masksToBounds = false // Use to debug animation layers -// sublayer.backgroundColor = MColor.green.cgColor -// sublayer.borderWidth = 2.0 -// sublayer.borderColor = MColor.red.cgColor -// layer.backgroundColor = MColor.blue.cgColor -// layer.borderWidth = 2.0 -// layer.borderColor = MColor.cyan.cgColor + // sublayer.backgroundColor = MColor.green.cgColor + // sublayer.borderWidth = 2.0 + // sublayer.borderColor = MColor.red.cgColor + // layer.backgroundColor = MColor.blue.cgColor + // layer.borderWidth = 2.0 + // layer.borderColor = MColor.cyan.cgColor let calculatedBounds = customBounds ?? node.bounds if let shapeBounds = calculatedBounds { @@ -67,7 +49,7 @@ class AnimationCache { layer.zPosition = CGFloat(renderer.zPosition) // Clip - if let clip = AnimationUtils.absoluteClip(renderer) { + if let clip = AbsoluteUtils.absoluteClip(renderer) { let maskLayer = CAShapeLayer() let origPath = clip.toCGPath() var offsetTransform = CGAffineTransform(translationX: -1.0 * cgRect.origin.x, y: -1.0 * cgRect.origin.y) @@ -84,10 +66,10 @@ class AnimationCache { // find first parent with cached layer var parent: NodeRenderer? = renderer.parentRenderer - var parentCachedLayer: CALayer? = sceneLayer + var parentCachedLayer: CALayer? = renderer.sceneLayer while parent != nil { if let parent = parent { - if let cached = cache[parent] { + if let cached = parent.layer { parentCachedLayer = cached.animationLayer break } @@ -99,11 +81,11 @@ class AnimationCache { parentCachedLayer?.addSublayer(layer) parentCachedLayer?.setNeedsDisplay() - cache[renderer] = CachedLayer(rootLayer: layer, animationLayer: sublayer) - + renderer.layer = CachedLayer(rootLayer: layer, animationLayer: sublayer) + // move children to new layer for child in renderer.getAllChildrenRecursive() { - if let cachedChildLayer = cache[child], let parentCachedLayer = parentCachedLayer { + if let cachedChildLayer = child.layer, let parentCachedLayer = parentCachedLayer { parentCachedLayer.sublayers?.forEach { childLayer in if childLayer === cachedChildLayer.rootLayer { @@ -116,12 +98,12 @@ class AnimationCache { } } - sceneLayer?.setNeedsDisplay() + renderer.sceneLayer?.setNeedsDisplay() return sublayer } - private func calculateAnimationScale(animation: Animation) -> CGFloat { + class private func calculateAnimationScale(animation: Animation) -> CGFloat { guard let defaultScale = MMainScreen()?.mScale else { return 1.0 } @@ -159,22 +141,41 @@ class AnimationCache { return defaultScale * CGFloat(sqrt(maxArea)) } - func freeLayerHard(_ renderer: NodeRenderer) { - freeLayer(renderer) + class func uncachedParentsPlace(_ renderer: NodeRenderer) -> Transform { + var parent: NodeRenderer? = renderer.parentRenderer + var uncachedParentsPlace = Transform.identity + while parent != nil { + if let parent = parent { + if parent.layer != nil { + break + } + uncachedParentsPlace = uncachedParentsPlace.concat(with: parent.node.place) + } + parent = parent?.parentRenderer + } + return uncachedParentsPlace + } +} + +extension NodeRenderer { + + func isAnimating() -> Bool { + return layer != nil } - func freeLayer(_ renderer: NodeRenderer?) { - guard let nodeRenderer = renderer, let layer = cache[nodeRenderer] else { + func freeLayer() { + + let nodeRenderer = self + guard let layer = nodeRenderer.layer else { return } - - cache.removeValue(forKey: nodeRenderer) + nodeRenderer.layer = nil // find first parent with cached layer var parent: NodeRenderer? = nodeRenderer.parentRenderer - var parentCachedLayer: CALayer? = sceneLayer + var parentCachedLayer: CALayer? = nodeRenderer.sceneLayer while parent != nil { - if let parent = parent, let cached = cache[parent] { + if let parent = parent, let cached = parent.layer { parentCachedLayer = cached.animationLayer break } @@ -183,12 +184,12 @@ class AnimationCache { // move children to closest parent layer for child in nodeRenderer.getAllChildrenRecursive() { - if let cachedChildLayer = cache[child], let parentCachedLayer = parentCachedLayer { + if let cachedChildLayer = child.layer, let parentCachedLayer = parentCachedLayer { layer.animationLayer.sublayers?.forEach { childLayer in if childLayer === cachedChildLayer.rootLayer { - CATransaction.setValue(kCFBooleanTrue, forKey:kCATransactionDisableActions) + CATransaction.setValue(kCFBooleanTrue, forKey: kCATransactionDisableActions) childLayer.removeFromSuperlayer() - childLayer.transform = CATransform3DMakeAffineTransform(uncachedParentsPlace(child).toCG()) + childLayer.transform = CATransform3DMakeAffineTransform(AnimationUtils.uncachedParentsPlace(child).toCG()) parentCachedLayer.addSublayer(childLayer) childLayer.setNeedsDisplay() CATransaction.commit() @@ -202,31 +203,4 @@ class AnimationCache { parentCachedLayer?.setNeedsDisplay() sceneLayer?.setNeedsDisplay() } - - func isAnimating(_ nodeRenderer: NodeRenderer) -> Bool { - return cache[nodeRenderer] != nil - } - - func isAnimating(_ node: Node) -> Bool { - if let renderer = cache.keys.first(where: { $0.node === node }) { - return isAnimating(renderer) - } - return false - } - - func uncachedParentsPlace(_ renderer: NodeRenderer) -> Transform { - var parent: NodeRenderer? = renderer.parentRenderer - var uncachedParentsPlace = Transform.identity - while parent != nil { - if let parent = parent { - if cache[parent] != nil { - break - } - uncachedParentsPlace = uncachedParentsPlace.concat(with: parent.node.place) - } - parent = parent?.parentRenderer - } - return uncachedParentsPlace - } - } diff --git a/Source/animation/types/animation_generators/MorphingGenerator.swift b/Source/animation/types/animation_generators/MorphingGenerator.swift index 99d4e0c7..212cbd9d 100644 --- a/Source/animation/types/animation_generators/MorphingGenerator.swift +++ b/Source/animation/types/animation_generators/MorphingGenerator.swift @@ -14,7 +14,7 @@ import UIKit import AppKit #endif -func addMorphingAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) { +func addMorphingAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer?, completion: @escaping (() -> Void)) { guard let morphingAnimation = animation as? MorphingAnimation else { return } @@ -30,9 +30,8 @@ func addMorphingAnimation(_ animation: BasicAnimation, _ context: AnimationConte let toLocus = morphingAnimation.getVFunc()(animation.autoreverses ? 0.5 : 1.0) let duration = animation.autoreverses ? animation.getDuration() / 2.0 : animation.getDuration() - guard let layer = animationCache?.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: false) else { - return - } + let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: false) + // Creating proper animation let generatedAnimation = pathAnimation( from: fromLocus, @@ -59,7 +58,7 @@ func addMorphingAnimation(_ animation: BasicAnimation, _ context: AnimationConte shape.form = morphingAnimation.getVFunc()(1.0) } - animationCache?.freeLayer(renderer) + renderer.freeLayer() if !animation.cycled && !animation.manualStop { diff --git a/Source/animation/types/animation_generators/OpacityGenerator.swift b/Source/animation/types/animation_generators/OpacityGenerator.swift index 6b4b6d5e..c91c1942 100644 --- a/Source/animation/types/animation_generators/OpacityGenerator.swift +++ b/Source/animation/types/animation_generators/OpacityGenerator.swift @@ -6,7 +6,7 @@ import UIKit import AppKit #endif -func addOpacityAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) { +func addOpacityAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer?, completion: @escaping (() -> Void)) { guard let opacityAnimation = animation as? OpacityAnimation else { return } @@ -34,7 +34,7 @@ func addOpacityAnimation(_ animation: BasicAnimation, _ context: AnimationContex generatedAnimation.completion = { finished in - animationCache?.freeLayer(renderer) + renderer.freeLayer() if animation.paused { animation.pausedProgress += animation.progress @@ -58,12 +58,11 @@ func addOpacityAnimation(_ animation: BasicAnimation, _ context: AnimationContex completion() } - if let layer = animationCache?.layerForNodeRenderer(renderer, context, animation: animation) { - let animationId = animation.ID - layer.add(generatedAnimation, forKey: animationId) - animation.removeFunc = { [weak layer] in - layer?.removeAnimation(forKey: animationId) - } + let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation) + let animationId = animation.ID + layer.add(generatedAnimation, forKey: animationId) + animation.removeFunc = { [weak layer] in + layer?.removeAnimation(forKey: animationId) } if !transactionsDisabled { diff --git a/Source/animation/types/animation_generators/ShapeAnimationGenerator.swift b/Source/animation/types/animation_generators/ShapeAnimationGenerator.swift index 9f703093..10c1f8e6 100644 --- a/Source/animation/types/animation_generators/ShapeAnimationGenerator.swift +++ b/Source/animation/types/animation_generators/ShapeAnimationGenerator.swift @@ -14,7 +14,7 @@ import UIKit import AppKit #endif -func addShapeAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) { +func addShapeAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer?, completion: @escaping (() -> Void)) { guard let shapeAnimation = animation as? ShapeAnimation else { return } @@ -30,16 +30,14 @@ func addShapeAnimation(_ animation: BasicAnimation, _ context: AnimationContext, let toShape = shapeAnimation.getVFunc()(animation.autoreverses ? 0.5 : 1.0) let duration = animation.autoreverses ? animation.getDuration() / 2.0 : animation.getDuration() - guard let layer = animationCache?.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: false) else { - return - } + let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: false) // Creating proper animation let generatedAnimation = generateShapeAnimation(context, - from: fromShape, - to: toShape, - animation: shapeAnimation, - duration: duration) + from: fromShape, + to: toShape, + animation: shapeAnimation, + duration: duration) generatedAnimation.repeatCount = Float(animation.repeatCount) generatedAnimation.timingFunction = caTimingFunction(animation.easing) @@ -68,7 +66,7 @@ func addShapeAnimation(_ animation: BasicAnimation, _ context: AnimationContext, shape.fill = fromShape.fill } - animationCache?.freeLayer(renderer) + renderer.freeLayer() if !animation.cycled && !animation.manualStop { animation.completion?() diff --git a/Source/animation/types/animation_generators/TransformGenerator.swift b/Source/animation/types/animation_generators/TransformGenerator.swift index 98778f89..98612d1c 100644 --- a/Source/animation/types/animation_generators/TransformGenerator.swift +++ b/Source/animation/types/animation_generators/TransformGenerator.swift @@ -6,7 +6,7 @@ import UIKit import AppKit #endif -func addTransformAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer, animationCache: AnimationCache?, completion: @escaping (() -> Void)) { +func addTransformAnimation(_ animation: BasicAnimation, _ context: AnimationContext, sceneLayer: CALayer?, completion: @escaping (() -> Void)) { guard let transformAnimation = animation as? TransformAnimation else { return } @@ -22,16 +22,14 @@ func addTransformAnimation(_ animation: BasicAnimation, _ context: AnimationCont let transactionsDisabled = CATransaction.disableActions() CATransaction.setDisableActions(true) - guard let layer = animationCache?.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: true) else { - return - } + let layer = AnimationUtils.layerForNodeRenderer(renderer, context, animation: animation, shouldRenderContent: true) // Creating proper animation let generatedAnimation = transformAnimationByFunc(transformAnimation, - context, - duration: animation.getDuration(), - offset: animation.pausedProgress, - fps: transformAnimation.logicalFps) + context, + duration: animation.getDuration(), + offset: animation.pausedProgress, + fps: transformAnimation.logicalFps) generatedAnimation.repeatCount = Float(animation.repeatCount) @@ -56,7 +54,7 @@ func addTransformAnimation(_ animation: BasicAnimation, _ context: AnimationCont node.placeVar.value = transformAnimation.getVFunc()(1.0) } - animationCache?.freeLayer(renderer) + renderer.freeLayer() if !animation.cycled && !animation.manualStop && diff --git a/Source/events/TouchEvent.swift b/Source/events/TouchEvent.swift index 8eadc4fa..a006aacd 100644 --- a/Source/events/TouchEvent.swift +++ b/Source/events/TouchEvent.swift @@ -12,6 +12,12 @@ import UIKit import AppKit #endif +public enum Relativity { + case parent + case scene + case view +} + class NodePath { let node: Node let location: CGPoint diff --git a/Source/platform/macOS/MView_macOS.swift b/Source/platform/macOS/MView_macOS.swift index 141346b7..469d36b4 100644 --- a/Source/platform/macOS/MView_macOS.swift +++ b/Source/platform/macOS/MView_macOS.swift @@ -79,7 +79,7 @@ open class MView: NSView, Touchable { func layoutSubviews() { super.resizeSubviews(withOldSize: self.bounds.size) } - + // MARK: - Touch pad open override func touchesBegan(with event: NSEvent) { super.touchesBegan(with: event) diff --git a/Source/render/GroupRenderer.swift b/Source/render/GroupRenderer.swift index 4aca8301..420c9628 100644 --- a/Source/render/GroupRenderer.swift +++ b/Source/render/GroupRenderer.swift @@ -13,9 +13,9 @@ class GroupRenderer: NodeRenderer { return group } - init(group: Group, view: MacawView?, animationCache: AnimationCache?, parentRenderer: GroupRenderer? = nil) { + init(group: Group, view: MacawView?, parentRenderer: GroupRenderer? = nil) { self.group = group - super.init(node: group, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + super.init(node: group, view: view, parentRenderer: parentRenderer) updateRenderers() } @@ -40,7 +40,7 @@ class GroupRenderer: NodeRenderer { override func doRender(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) { renderers.forEach { renderer in - if !(animationCache?.isAnimating(renderer) ?? false) { + if !renderer.isAnimating() { renderer.render(in: context, force: force, opacity: opacity, coloringMode: coloringMode) } } @@ -64,13 +64,12 @@ class GroupRenderer: NodeRenderer { private func updateRenderers() { renderers.forEach { - animationCache?.freeLayerHard($0) $0.dispose() } renderers.removeAll() renderers = group.contents.compactMap { child -> NodeRenderer? in - return RenderUtils.createNodeRenderer(child, view: view, animationCache: animationCache, parentRenderer: self) + return RenderUtils.createNodeRenderer(child, view: view, parentRenderer: self) } var parent: NodeRenderer = self diff --git a/Source/render/ImageRenderer.swift b/Source/render/ImageRenderer.swift index 24f24b84..c9a571cc 100644 --- a/Source/render/ImageRenderer.swift +++ b/Source/render/ImageRenderer.swift @@ -17,9 +17,9 @@ class ImageRenderer: NodeRenderer { return image } - init(image: Image, view: MacawView?, animationCache: AnimationCache?, parentRenderer: GroupRenderer? = nil) { + init(image: Image, view: MacawView?, parentRenderer: GroupRenderer? = nil) { self.image = image - super.init(node: image, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + super.init(node: image, view: view, parentRenderer: parentRenderer) } deinit { diff --git a/Source/render/NodeRenderer.swift b/Source/render/NodeRenderer.swift index 23d3cd72..87240b55 100644 --- a/Source/render/NodeRenderer.swift +++ b/Source/render/NodeRenderer.swift @@ -6,26 +6,34 @@ import UIKit import AppKit #endif -public enum Relativity { - case parent - case scene - case view -} - enum ColoringMode { case rgb, greyscale, alphaOnly } +class CachedLayer { + let rootLayer: ShapeLayer + let animationLayer: ShapeLayer + + required init(rootLayer: ShapeLayer, animationLayer: ShapeLayer) { + self.rootLayer = rootLayer + self.animationLayer = animationLayer + } +} + class NodeRenderer { weak var view: MacawView? - let parentRenderer: GroupRenderer? + var sceneLayer: CALayer? { + return view?.mLayer + } + var layer: CachedLayer? var zPosition: Int = 0 + let parentRenderer: GroupRenderer? + fileprivate let onNodeChange: () -> Void fileprivate let disposables = GroupDisposable() fileprivate var active = false - weak var animationCache: AnimationCache? fileprivate var cachedAbsPlace: Transform? fileprivate var absPlace: Transform { @@ -63,19 +71,14 @@ class NodeRenderer { fatalError("Unsupported") } - init(node: Node, view: MacawView?, animationCache: AnimationCache?, parentRenderer: GroupRenderer? = nil) { + init(node: Node, view: MacawView?, parentRenderer: GroupRenderer? = nil) { self.view = view - self.animationCache = animationCache self.parentRenderer = parentRenderer - onNodeChange = { [unowned node, weak view] in - guard let isAnimating = animationCache?.isAnimating(node) else { - return - } - - if isAnimating { - return - } + onNodeChange = { [weak view] in + // if self.isAnimating() { + // return + // } view?.setNeedsDisplay() } @@ -116,6 +119,7 @@ class NodeRenderer { open func dispose() { removeObservers() node.animationObservers = node.animationObservers.filter { !($0 as? NodeRenderer === self) } + freeLayer() } final public func render(in context: CGContext, force: Bool, opacity: Double, coloringMode: ColoringMode = .rgb) { @@ -169,7 +173,7 @@ class NodeRenderer { } final func directRender(in context: CGContext, force: Bool = true, opacity: Double = 1.0, coloringMode: ColoringMode = .rgb) { - if let isAnimating = animationCache?.isAnimating(self), isAnimating { + if isAnimating() { self.removeObservers() if !force { return @@ -329,7 +333,7 @@ class NodeRenderer { private func getMaskedImage(bounds: Rect) -> CGImage { let mask = node.mask! let image = renderToImage(bounds: bounds) - let nodeRenderer = RenderUtils.createNodeRenderer(mask, view: .none, animationCache: animationCache) + let nodeRenderer = RenderUtils.createNodeRenderer(mask, view: .none) let maskImage = nodeRenderer.renderToImage(bounds: bounds, coloringMode: .greyscale) return apply(maskImage: maskImage, to: image) } @@ -371,7 +375,7 @@ class NodeRenderer { func getAllChildrenRecursive() -> [NodeRenderer] { var children = getAllChildren(self) - children.removeAll(where: { (r) -> Bool in + children.removeAll(where: { r -> Bool in r === self }) return children diff --git a/Source/render/RenderUtils.swift b/Source/render/RenderUtils.swift index c8fb310b..8b9ebeff 100644 --- a/Source/render/RenderUtils.swift +++ b/Source/render/RenderUtils.swift @@ -16,15 +16,15 @@ class RenderUtils { return p } - class func createNodeRenderer(_ node: Node, view: MacawView?, animationCache: AnimationCache?, parentRenderer: GroupRenderer? = nil) -> NodeRenderer { + class func createNodeRenderer(_ node: Node, view: MacawView?, parentRenderer: GroupRenderer? = nil) -> NodeRenderer { if let group = node as? Group { - return GroupRenderer(group: group, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + return GroupRenderer(group: group, view: view, parentRenderer: parentRenderer) } else if let shape = node as? Shape { - return ShapeRenderer(shape: shape, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + return ShapeRenderer(shape: shape, view: view, parentRenderer: parentRenderer) } else if let text = node as? Text { - return TextRenderer(text: text, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + return TextRenderer(text: text, view: view, parentRenderer: parentRenderer) } else if let image = node as? Image { - return ImageRenderer(image: image, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + return ImageRenderer(image: image, view: view, parentRenderer: parentRenderer) } fatalError("Unsupported node: \(node)") } diff --git a/Source/render/ShapeRenderer.swift b/Source/render/ShapeRenderer.swift index cfddc19a..69f5f417 100644 --- a/Source/render/ShapeRenderer.swift +++ b/Source/render/ShapeRenderer.swift @@ -10,9 +10,9 @@ class ShapeRenderer: NodeRenderer { var shape: Shape - init(shape: Shape, view: MacawView?, animationCache: AnimationCache?, parentRenderer: GroupRenderer? = nil) { + init(shape: Shape, view: MacawView?, parentRenderer: GroupRenderer? = nil) { self.shape = shape - super.init(node: shape, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + super.init(node: shape, view: view, parentRenderer: parentRenderer) } deinit { @@ -165,7 +165,7 @@ class ShapeRenderer: NodeRenderer { if !pattern.userSpace, let node = BoundsUtils.createNodeFromRespectiveCoords(respectiveNode: pattern.content, absoluteLocus: shape.form) { patternNode = node } - let renderer = RenderUtils.createNodeRenderer(patternNode, view: view, animationCache: animationCache) + let renderer = RenderUtils.createNodeRenderer(patternNode, view: view) var patternBounds = pattern.bounds if !pattern.userSpace { diff --git a/Source/render/TextRenderer.swift b/Source/render/TextRenderer.swift index 61467074..292e0f3a 100644 --- a/Source/render/TextRenderer.swift +++ b/Source/render/TextRenderer.swift @@ -13,9 +13,9 @@ class TextRenderer: NodeRenderer { return text } - init(text: Text, view: MacawView?, animationCache: AnimationCache?, parentRenderer: GroupRenderer? = nil) { + init(text: Text, view: MacawView?, parentRenderer: GroupRenderer? = nil) { self.text = text - super.init(node: text, view: view, animationCache: animationCache, parentRenderer: parentRenderer) + super.init(node: text, view: view, parentRenderer: parentRenderer) } deinit { diff --git a/Source/utils/CGMappings.swift b/Source/utils/CGMappings.swift index 4b76f6db..e3acc84b 100644 --- a/Source/utils/CGMappings.swift +++ b/Source/utils/CGMappings.swift @@ -136,7 +136,7 @@ public extension CGAffineTransform { public extension Node { func toNativeImage(size: Size, layout: ContentLayout = .of()) -> MImage { - let renderer = RenderUtils.createNodeRenderer(self, view: nil, animationCache: nil) + let renderer = RenderUtils.createNodeRenderer(self, view: nil) let rect = size.rect() MGraphicsBeginImageContextWithOptions(size.toCG(), false, 1) diff --git a/Source/views/MacawView.swift b/Source/views/MacawView.swift index 3eb9ad71..d6369115 100644 --- a/Source/views/MacawView.swift +++ b/Source/views/MacawView.swift @@ -17,9 +17,7 @@ open class MacawView: MView, MGestureRecognizerDelegate { didSet { layoutHelper.nodeChanged() self.renderer?.dispose() - if let cache = animationCache { - self.renderer = RenderUtils.createNodeRenderer(node, view: self, animationCache: cache) - } + self.renderer = RenderUtils.createNodeRenderer(node, view: self) if let _ = superview { animationProducer.addStoredAnimations(node, self) @@ -100,8 +98,6 @@ open class MacawView: MView, MGestureRecognizerDelegate { var toRender = true var frameSetFirstTime = false - internal var animationCache: AnimationCache? - #if os(OSX) open override var layer: CALayer? { didSet { @@ -111,7 +107,7 @@ open class MacawView: MView, MGestureRecognizerDelegate { initializeView() if let cache = self.animationCache { - self.renderer = RenderUtils.createNodeRenderer(node, view: self, animationCache: cache) + self.renderer = RenderUtils.createNodeRenderer(node, view: self) } } } @@ -124,9 +120,7 @@ open class MacawView: MView, MGestureRecognizerDelegate { initializeView() self.node = node - if let cache = self.animationCache { - self.renderer = RenderUtils.createNodeRenderer(node, view: self, animationCache: cache) - } + self.renderer = RenderUtils.createNodeRenderer(node, view: self) backgroundColor = .white } @@ -134,9 +128,7 @@ open class MacawView: MView, MGestureRecognizerDelegate { self.init(frame: frame) self.node = node - if let cache = self.animationCache { - self.renderer = RenderUtils.createNodeRenderer(node, view: self, animationCache: cache) - } + self.renderer = RenderUtils.createNodeRenderer(node, view: self) backgroundColor = .white } @@ -160,12 +152,6 @@ open class MacawView: MView, MGestureRecognizerDelegate { self.contentLayout = .none self.context = RenderContext(view: self) - guard let layer = self.mLayer else { - return - } - - self.animationCache = AnimationCache(sceneLayer: layer) - let tapRecognizer = MTapGestureRecognizer(target: self, action: #selector(MacawView.handleTap)) let longTapRecognizer = MLongPressGestureRecognizer(target: self, action: #selector(MacawView.handleLongTap(recognizer:))) let panRecognizer = MPanGestureRecognizer(target: self, action: #selector(MacawView.handlePan)) diff --git a/Source/views/ShapeLayer.swift b/Source/views/ShapeLayer.swift index 74693b63..2551bdc5 100644 --- a/Source/views/ShapeLayer.swift +++ b/Source/views/ShapeLayer.swift @@ -8,7 +8,6 @@ import AppKit class ShapeLayer: CAShapeLayer { weak var renderer: NodeRenderer? - weak var animationCache: AnimationCache? var shouldRenderContent = true var isForceRenderingEnabled = true