From 98f61d442a5daea7d185c370098fb7db90466c6e Mon Sep 17 00:00:00 2001 From: John Sundell Date: Sun, 22 Oct 2017 20:11:36 +0200 Subject: [PATCH] Actor: Compute rect manually MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CALayer gan get some funky values as its rect when not displayed on the screen yet on macOS. To make things nice and consistent we now compute an actor’s rect manually whenever the position or size changes. --- Sources/Core/API/Actor.swift | 15 ++++++++++++--- Tests/ImagineEngineTests/ActorTests.swift | 10 ++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Sources/Core/API/Actor.swift b/Sources/Core/API/Actor.swift index 9163361..ff17988 100644 --- a/Sources/Core/API/Actor.swift +++ b/Sources/Core/API/Actor.swift @@ -38,7 +38,7 @@ public final class Actor: InstanceHashable, ActionPerformer, Activatable, Movabl /// The size of the actor (centered on its position). public var size = Size() { didSet { sizeDidChange(from: oldValue) } } /// The rectangle the actor currently occupies within its scene. - public var rect: Rect { return layer.frame } + public private(set) var rect = Rect() { didSet { rectDidChange() } } /// The rotation of the actor along the z axis. public var rotation = Metric() { didSet { layer.rotation = rotation } } /// The scale of the actor. Does not affect its size, rect or collision detection. @@ -158,9 +158,10 @@ public final class Actor: InstanceHashable, ActionPerformer, Activatable, Movabl } layer.position = position + updateRect() + events.moved.trigger() events.rectChanged.trigger() - rectDidChange() } private func sizeDidChange(from oldValue: Size) { @@ -169,9 +170,10 @@ public final class Actor: InstanceHashable, ActionPerformer, Activatable, Movabl } layer.bounds.size = size + updateRect() + events.resized.trigger() events.rectChanged.trigger() - rectDidChange() } private func rectDidChange() { @@ -227,6 +229,13 @@ public final class Actor: InstanceHashable, ActionPerformer, Activatable, Movabl } } + private func updateRect() { + var newRect = Rect(origin: position, size: size) + newRect.origin.x -= size.width / 2 + newRect.origin.y -= size.height / 2 + rect = newRect + } + private func renderFirstAnimationFrameIfNeeded() { guard let animation = animation else { return diff --git a/Tests/ImagineEngineTests/ActorTests.swift b/Tests/ImagineEngineTests/ActorTests.swift index 93d9c6b..d76b10a 100644 --- a/Tests/ImagineEngineTests/ActorTests.swift +++ b/Tests/ImagineEngineTests/ActorTests.swift @@ -23,6 +23,16 @@ final class ActorTests: XCTestCase { // MARK: - Tests + func testRect() { + XCTAssertEqual(actor.rect, .zero) + + actor.position = Point(x: 150, y: 200) + XCTAssertEqual(actor.rect, Rect(x: 150, y: 200, width: 0, height: 0)) + + actor.size = Size(width: 100, height: 300) + XCTAssertEqual(actor.rect, Rect(x: 100, y: 50, width: 100, height: 300)) + } + func testAnimationAutoResizingActor() { let imageSizes = [ Size(width: 200, height: 150),