From 7d8af3b518fb895ae98b130ad2ed1dcefbcce820 Mon Sep 17 00:00:00 2001 From: Christophe Bronner Date: Thu, 3 Sep 2020 15:41:58 -0400 Subject: [PATCH 1/2] Moved to Swift Package Manager Made a single Package to englobe all of ImagineEngine and removed old project. Builds on Mac, iOS and tvOS. --- .../contents.xcworkspacedata | 0 .../xcschemes/ImagineEngine.xcscheme | 48 +- Configs/ImagineEngine.plist | 28 - Configs/ImagineEngineTests.plist | 24 - ImagineEngine.podspec | 41 - ImagineEngine.xcodeproj/project.pbxproj | 1906 ----------------- .../xcschemes/ImagineEngine-iOS.xcscheme | 100 - .../xcschemes/ImagineEngine-macOS.xcscheme | 99 - ImagineEngine/.gitignore | 5 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 0 ImagineEngine/Package.swift | 28 + ImagineEngine/Sources/Core/API/Action.swift | 99 + .../Sources/Core/API/ActionPerformer.swift | 20 + .../Sources/Core/API/ActionToken.swift | 113 + ImagineEngine/Sources/Core/API/Actor.swift | 366 ++++ .../Core/API/ActorEventCollection.swift | 46 + .../Sources/Core/API/Animation.swift | 230 ++ .../Sources/Core/API/AnimationAction.swift | 69 + ImagineEngine/Sources/Core/API/Block.swift | 383 ++++ .../Core/API/BlockTextureCollection.swift | 50 + ImagineEngine/Sources/Core/API/Camera.swift | 145 ++ .../Core/API/CameraEventCollection.swift | 17 + .../Sources/Core/API/CancellationToken.swift | 24 + .../Sources/Core/API/ClosureAction.swift | 29 + .../Sources/Core/API/Constraint.swift | 17 + .../Sources/Core/API/Coordinate.swift | 43 + ImagineEngine/Sources/Core/API/Event.swift | 151 ++ .../Sources/Core/API/EventCollection.swift | 55 + .../Sources/Core/API/EventToken.swift | 12 + .../Sources/Core/API/FadeAction.swift | 30 + ImagineEngine/Sources/Core/API/Fadeable.swift | 30 + ImagineEngine/Sources/Core/API/Game.swift | 90 + ImagineEngine/Sources/Core/API/Group.swift | 38 + .../Sources/Core/API/InstanceHashable.swift | 20 + ImagineEngine/Sources/Core/API/Label.swift | 220 ++ .../Core/API/LabelEventCollection.swift | 15 + .../Sources/Core/API/MetricAction.swift | 57 + .../Sources/Core/API/Mirroring.swift | 15 + ImagineEngine/Sources/Core/API/Movable.swift | 48 + .../Sources/Core/API/MoveAction.swift | 62 + ImagineEngine/Sources/Core/API/Node.swift | 19 + .../Sources/Core/API/Pluggable.swift | 42 + ImagineEngine/Sources/Core/API/Plugin.swift | 42 + .../Sources/Core/API/RepeatAction.swift | 32 + .../Sources/Core/API/RepeatMode.swift | 48 + .../Sources/Core/API/Rotatable.swift | 20 + .../Sources/Core/API/RotateAction.swift | 30 + ImagineEngine/Sources/Core/API/Scalable.swift | 25 + .../Sources/Core/API/ScaleAction.swift | 30 + ImagineEngine/Sources/Core/API/Scene.swift | 270 +++ .../Core/API/SceneEventCollection.swift | 21 + ImagineEngine/Sources/Core/API/Shadow.swift | 34 + .../Sources/Core/API/SpriteSheet.swift | 128 ++ ImagineEngine/Sources/Core/API/Texture.swift | 32 + .../Sources/Core/API/TextureFormat.swift | 15 + .../Sources/Core/API/TextureImageLoader.swift | 13 + .../Sources/Core/API/TextureManager.swift | 125 ++ ImagineEngine/Sources/Core/API/Timeline.swift | 248 +++ .../Sources/Core/API/Typealiases.swift | 39 + ImagineEngine/Sources/Core/API/ZIndexed.swift | 13 + .../Sources/Core/Internal/ActionManager.swift | 51 + .../Sources/Core/Internal/ActionWrapper.swift | 68 + .../Sources/Core/Internal/Activatable.swift | 16 + .../Sources/Core/Internal/AnyNode.swift | 5 + .../Core/Internal/BundleProtocol.swift | 13 + .../Internal/BundleTextureImageLoader.swift | 49 + .../Core/Internal/CALayer+Transform.swift | 22 + .../ClickGestureRecognizer-macOS.swift | 14 + .../Sources/Core/Internal/ClickPlugin.swift | 72 + .../Core/Internal/ClosureUpdatable.swift | 45 + .../Sources/Core/Internal/DisplayLink.swift | 8 + .../Core/Internal/DisplayLinkProtocol.swift | 12 + .../Core/Internal/EdgeInsets-macOS.swift | 14 + .../Sources/Core/Internal/Font+Default.swift | 18 + .../Sources/Core/Internal/GameView.swift | 31 + .../Sources/Core/Internal/Grid.swift | 451 ++++ .../Sources/Core/Internal/GridPlaceable.swift | 8 + .../Sources/Core/Internal/Image-macOS.swift | 24 + .../Sources/Core/Internal/Layer.swift | 30 + .../Sources/Core/Internal/LoadedTexture.swift | 32 + .../Core/Internal/Optional+GetOrSet.swift | 19 + .../Sources/Core/Internal/PluginManager.swift | 99 + .../Sources/Core/Internal/PluginWrapper.swift | 36 + .../Core/Internal/ReplicatorLayer.swift | 26 + .../Sources/Core/Internal/Screen.swift | 8 + .../Sources/Core/Internal/TextLayer.swift | 14 + .../Core/Internal/TextureErrorHandler.swift | 13 + .../Sources/Core/Internal/Updatable.swift | 11 + .../Core/Internal/UpdatableCollection.swift | 82 + .../Core/Internal/UpdatableWrapper.swift | 26 + .../Sources/Core/Internal/UpdateOutcome.swift | 12 + .../Core/Internal/View+MakeLayer.swift | 19 + .../AppKit/GameViewController-macOS.swift | 105 + .../AppKit/GameWindowController.swift | 37 + .../UIKit/GameViewController-iOS+tvOS.swift | 101 + .../Integrations/UIKit/GameWindow.swift | 28 + .../ImagineEngineTests/Mocks/ActionMock.swift | 33 + .../ImagineEngineTests/Mocks/BundleMock.swift | 33 + .../Mocks/ClickGestureRecognizerMock.swift | 20 + .../Mocks/DisplayLinkMock.swift | 18 + .../ImagineEngineTests/Mocks/GameMock.swift | 51 + .../Mocks/GameViewMock.swift | 12 + .../ImagineEngineTests/Mocks/PluginMock.swift | 28 + .../Mocks/TextureErrorHandlerMock.swift | 22 + .../Mocks/TextureImageLoaderMock.swift | 36 + .../ImagineEngineTests/Resources/sample.jpg | Bin 0 -> 3349 bytes .../ImagineEngineTests/Resources/sample.png | Bin 0 -> 1056 bytes .../Tests}/ActionTests.swift | 0 .../Tests}/ActorTests.swift | 0 .../Tests}/BlockTests.swift | 0 .../BundleTextureImageLoaderTests.swift | 0 .../Tests}/CameraTests.swift | 0 .../Tests}/EventTests.swift | 0 .../Tests}/LabelTests.swift | 0 .../Tests}/SceneTests.swift | 0 .../Tests}/SpriteSheetTests.swift | 0 .../Tests}/TextureManagerTests.swift | 0 .../Tests}/TimelineTests.swift | 0 .../ImagineEngineTests/Utilities/Assert.swift | 91 + .../Utilities/ImageMockFactory.swift | 29 + .../Utilities/TimeTraveler.swift | 19 + .../XCTAssertEqual+CATransform3D.swift | 12 + .../ImagineEngineTests/XCTestManifests.swift | 9 + ImagineEngine/Tests/LinuxMain.swift | 7 + Package.swift | 29 + .../ClickGestureRecognizer-macOS.swift | 2 + .../Core/Internal/DisplayLink-iOS+tvOS.swift | 8 +- Sources/Core/Internal/DisplayLink-macOS.swift | 4 +- Sources/Core/Internal/EdgeInsets-macOS.swift | 2 + Sources/Core/Internal/Image-macOS.swift | 2 + Sources/Core/Internal/Screen-iOS.swift | 8 +- Sources/Core/Internal/Screen-macOS.swift | 7 +- .../AppKit/GameViewController-macOS.swift | 2 + .../AppKit/GameWindowController.swift | 2 + .../UIKit/GameViewController-iOS+tvOS.swift | 2 + Sources/Integrations/UIKit/GameWindow.swift | 2 + .../Tests/ActionTests.swift | 256 +++ .../ImagineEngineTests/Tests/ActorTests.swift | 733 +++++++ .../ImagineEngineTests/Tests/BlockTests.swift | 36 + .../Tests/BundleTextureImageLoaderTests.swift | 34 + .../Tests/CameraTests.swift | 146 ++ .../ImagineEngineTests/Tests/EventTests.swift | 122 ++ .../ImagineEngineTests/Tests/LabelTests.swift | 159 ++ .../ImagineEngineTests/Tests/SceneTests.swift | 386 ++++ .../Tests/SpriteSheetTests.swift | 59 + .../Tests/TextureManagerTests.swift | 107 + .../Tests/TimelineTests.swift | 159 ++ .../ImagineEngineTests/Utilities/Assert.swift | 8 +- .../XCTAssertEqual+CATransform3D.swift | 2 +- .../ImagineEngineTests/XCTestManifests.swift | 9 + Tests/LinuxMain.swift | 7 + 152 files changed, 8089 insertions(+), 2249 deletions(-) rename {ImagineEngine.xcodeproj/project.xcworkspace => .swiftpm/xcode/package.xcworkspace}/contents.xcworkspacedata (100%) rename ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-tvOS.xcscheme => .swiftpm/xcode/xcshareddata/xcschemes/ImagineEngine.xcscheme (56%) delete mode 100644 Configs/ImagineEngine.plist delete mode 100644 Configs/ImagineEngineTests.plist delete mode 100644 ImagineEngine.podspec delete mode 100644 ImagineEngine.xcodeproj/project.pbxproj delete mode 100644 ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-iOS.xcscheme delete mode 100644 ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-macOS.xcscheme create mode 100644 ImagineEngine/.gitignore create mode 100644 ImagineEngine/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata rename {ImagineEngine.xcodeproj/project.xcworkspace => ImagineEngine/.swiftpm/xcode/package.xcworkspace}/xcshareddata/IDEWorkspaceChecks.plist (100%) create mode 100644 ImagineEngine/Package.swift create mode 100644 ImagineEngine/Sources/Core/API/Action.swift create mode 100644 ImagineEngine/Sources/Core/API/ActionPerformer.swift create mode 100644 ImagineEngine/Sources/Core/API/ActionToken.swift create mode 100644 ImagineEngine/Sources/Core/API/Actor.swift create mode 100644 ImagineEngine/Sources/Core/API/ActorEventCollection.swift create mode 100644 ImagineEngine/Sources/Core/API/Animation.swift create mode 100644 ImagineEngine/Sources/Core/API/AnimationAction.swift create mode 100644 ImagineEngine/Sources/Core/API/Block.swift create mode 100644 ImagineEngine/Sources/Core/API/BlockTextureCollection.swift create mode 100644 ImagineEngine/Sources/Core/API/Camera.swift create mode 100644 ImagineEngine/Sources/Core/API/CameraEventCollection.swift create mode 100644 ImagineEngine/Sources/Core/API/CancellationToken.swift create mode 100644 ImagineEngine/Sources/Core/API/ClosureAction.swift create mode 100644 ImagineEngine/Sources/Core/API/Constraint.swift create mode 100644 ImagineEngine/Sources/Core/API/Coordinate.swift create mode 100644 ImagineEngine/Sources/Core/API/Event.swift create mode 100644 ImagineEngine/Sources/Core/API/EventCollection.swift create mode 100644 ImagineEngine/Sources/Core/API/EventToken.swift create mode 100644 ImagineEngine/Sources/Core/API/FadeAction.swift create mode 100644 ImagineEngine/Sources/Core/API/Fadeable.swift create mode 100644 ImagineEngine/Sources/Core/API/Game.swift create mode 100644 ImagineEngine/Sources/Core/API/Group.swift create mode 100644 ImagineEngine/Sources/Core/API/InstanceHashable.swift create mode 100644 ImagineEngine/Sources/Core/API/Label.swift create mode 100644 ImagineEngine/Sources/Core/API/LabelEventCollection.swift create mode 100644 ImagineEngine/Sources/Core/API/MetricAction.swift create mode 100644 ImagineEngine/Sources/Core/API/Mirroring.swift create mode 100644 ImagineEngine/Sources/Core/API/Movable.swift create mode 100644 ImagineEngine/Sources/Core/API/MoveAction.swift create mode 100644 ImagineEngine/Sources/Core/API/Node.swift create mode 100644 ImagineEngine/Sources/Core/API/Pluggable.swift create mode 100644 ImagineEngine/Sources/Core/API/Plugin.swift create mode 100644 ImagineEngine/Sources/Core/API/RepeatAction.swift create mode 100644 ImagineEngine/Sources/Core/API/RepeatMode.swift create mode 100644 ImagineEngine/Sources/Core/API/Rotatable.swift create mode 100644 ImagineEngine/Sources/Core/API/RotateAction.swift create mode 100644 ImagineEngine/Sources/Core/API/Scalable.swift create mode 100644 ImagineEngine/Sources/Core/API/ScaleAction.swift create mode 100644 ImagineEngine/Sources/Core/API/Scene.swift create mode 100644 ImagineEngine/Sources/Core/API/SceneEventCollection.swift create mode 100644 ImagineEngine/Sources/Core/API/Shadow.swift create mode 100644 ImagineEngine/Sources/Core/API/SpriteSheet.swift create mode 100644 ImagineEngine/Sources/Core/API/Texture.swift create mode 100644 ImagineEngine/Sources/Core/API/TextureFormat.swift create mode 100644 ImagineEngine/Sources/Core/API/TextureImageLoader.swift create mode 100644 ImagineEngine/Sources/Core/API/TextureManager.swift create mode 100644 ImagineEngine/Sources/Core/API/Timeline.swift create mode 100644 ImagineEngine/Sources/Core/API/Typealiases.swift create mode 100644 ImagineEngine/Sources/Core/API/ZIndexed.swift create mode 100644 ImagineEngine/Sources/Core/Internal/ActionManager.swift create mode 100644 ImagineEngine/Sources/Core/Internal/ActionWrapper.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Activatable.swift create mode 100644 ImagineEngine/Sources/Core/Internal/AnyNode.swift create mode 100644 ImagineEngine/Sources/Core/Internal/BundleProtocol.swift create mode 100644 ImagineEngine/Sources/Core/Internal/BundleTextureImageLoader.swift create mode 100644 ImagineEngine/Sources/Core/Internal/CALayer+Transform.swift create mode 100644 ImagineEngine/Sources/Core/Internal/ClickGestureRecognizer-macOS.swift create mode 100644 ImagineEngine/Sources/Core/Internal/ClickPlugin.swift create mode 100644 ImagineEngine/Sources/Core/Internal/ClosureUpdatable.swift create mode 100644 ImagineEngine/Sources/Core/Internal/DisplayLink.swift create mode 100644 ImagineEngine/Sources/Core/Internal/DisplayLinkProtocol.swift create mode 100644 ImagineEngine/Sources/Core/Internal/EdgeInsets-macOS.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Font+Default.swift create mode 100644 ImagineEngine/Sources/Core/Internal/GameView.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Grid.swift create mode 100644 ImagineEngine/Sources/Core/Internal/GridPlaceable.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Image-macOS.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Layer.swift create mode 100644 ImagineEngine/Sources/Core/Internal/LoadedTexture.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Optional+GetOrSet.swift create mode 100644 ImagineEngine/Sources/Core/Internal/PluginManager.swift create mode 100644 ImagineEngine/Sources/Core/Internal/PluginWrapper.swift create mode 100644 ImagineEngine/Sources/Core/Internal/ReplicatorLayer.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Screen.swift create mode 100644 ImagineEngine/Sources/Core/Internal/TextLayer.swift create mode 100644 ImagineEngine/Sources/Core/Internal/TextureErrorHandler.swift create mode 100644 ImagineEngine/Sources/Core/Internal/Updatable.swift create mode 100644 ImagineEngine/Sources/Core/Internal/UpdatableCollection.swift create mode 100644 ImagineEngine/Sources/Core/Internal/UpdatableWrapper.swift create mode 100644 ImagineEngine/Sources/Core/Internal/UpdateOutcome.swift create mode 100644 ImagineEngine/Sources/Core/Internal/View+MakeLayer.swift create mode 100644 ImagineEngine/Sources/Integrations/AppKit/GameViewController-macOS.swift create mode 100644 ImagineEngine/Sources/Integrations/AppKit/GameWindowController.swift create mode 100644 ImagineEngine/Sources/Integrations/UIKit/GameViewController-iOS+tvOS.swift create mode 100644 ImagineEngine/Sources/Integrations/UIKit/GameWindow.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/ActionMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/BundleMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/ClickGestureRecognizerMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/DisplayLinkMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/GameMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/GameViewMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/PluginMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/TextureErrorHandlerMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Mocks/TextureImageLoaderMock.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Resources/sample.jpg create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Resources/sample.png rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/ActionTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/ActorTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/BlockTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/BundleTextureImageLoaderTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/CameraTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/EventTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/LabelTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/SceneTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/SpriteSheetTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/TextureManagerTests.swift (100%) rename {Tests/ImagineEngineTests => ImagineEngine/Tests/ImagineEngineTests/Tests}/TimelineTests.swift (100%) create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Utilities/Assert.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Utilities/ImageMockFactory.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Utilities/TimeTraveler.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/Utilities/XCTAssertEqual+CATransform3D.swift create mode 100644 ImagineEngine/Tests/ImagineEngineTests/XCTestManifests.swift create mode 100644 ImagineEngine/Tests/LinuxMain.swift create mode 100644 Package.swift create mode 100644 Tests/ImagineEngineTests/Tests/ActionTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/ActorTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/BlockTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/BundleTextureImageLoaderTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/CameraTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/EventTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/LabelTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/SceneTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/SpriteSheetTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/TextureManagerTests.swift create mode 100644 Tests/ImagineEngineTests/Tests/TimelineTests.swift create mode 100644 Tests/ImagineEngineTests/XCTestManifests.swift create mode 100644 Tests/LinuxMain.swift diff --git a/ImagineEngine.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata similarity index 100% rename from ImagineEngine.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata diff --git a/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-tvOS.xcscheme b/.swiftpm/xcode/xcshareddata/xcschemes/ImagineEngine.xcscheme similarity index 56% rename from ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-tvOS.xcscheme rename to .swiftpm/xcode/xcshareddata/xcschemes/ImagineEngine.xcscheme index d938792..0c61c66 100644 --- a/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-tvOS.xcscheme +++ b/.swiftpm/xcode/xcshareddata/xcschemes/ImagineEngine.xcscheme @@ -1,6 +1,6 @@ + BlueprintIdentifier = "ImagineEngine" + BuildableName = "ImagineEngine" + BlueprintName = "ImagineEngine" + ReferencedContainer = "container:"> @@ -32,24 +32,13 @@ skipped = "NO"> + BlueprintIdentifier = "ImagineEngineTests" + BuildableName = "ImagineEngineTests" + BlueprintName = "ImagineEngineTests" + ReferencedContainer = "container:"> - - - - - - - - - - - - + BlueprintIdentifier = "ImagineEngine" + BuildableName = "ImagineEngine" + BlueprintName = "ImagineEngine" + ReferencedContainer = "container:"> diff --git a/Configs/ImagineEngine.plist b/Configs/ImagineEngine.plist deleted file mode 100644 index f72534a..0000000 --- a/Configs/ImagineEngine.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2017 John Sundell. All rights reserved. - NSPrincipalClass - - - diff --git a/Configs/ImagineEngineTests.plist b/Configs/ImagineEngineTests.plist deleted file mode 100644 index ba72822..0000000 --- a/Configs/ImagineEngineTests.plist +++ /dev/null @@ -1,24 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - - diff --git a/ImagineEngine.podspec b/ImagineEngine.podspec deleted file mode 100644 index f716a33..0000000 --- a/ImagineEngine.podspec +++ /dev/null @@ -1,41 +0,0 @@ -Pod::Spec.new do |s| - s.name = "ImagineEngine" - s.version = "0.10.0" - s.summary = "A Swift game engine based on Core Animation" - s.description = <<-DESC - Imagine Engine is an ongoing project that aims to create a fast, high-performace Swift 2D game engine for Apple's platforms that is also a joy to use. - While there are still ways to go, things to fix and new capabilities to add, you are invited to participate in this new community to build a tool with - an ambitious but clear goal - to enable you to easily build any game that you can imagine. - DESC - s.homepage = "https://github.com/JohnSundell/ImagineEngine" - s.license = { :type => "MIT", :file => "LICENSE" } - s.author = { "John Sundell" => "john@sundell.co" } - s.social_media_url = "https://twitter.com/johnsundell" - s.ios.deployment_target = "9.0" - s.osx.deployment_target = "10.12" - s.tvos.deployment_target = "10.0" - s.source = { :git => "https://github.com/JohnSundell/ImagineEngine.git", :tag => s.version.to_s } - s.source_files = "Sources/Core/**/*.swift" - s.ios.source_files = "Sources/Integrations/UIKit/*.swift" - s.ios.exclude_files = [ - "Sources/Core/Internal/ClickGestureRecognizer-macOS.swift", - "Sources/Core/Internal/DisplayLink-macOS.swift", - "Sources/Core/Internal/EdgeInsets-macOS.swift", - "Sources/Core/Internal/Image-macOS.swift", - "Sources/Core/Internal/Screen-macOS.swift" - ] - s.osx.source_files = "Sources/Integrations/AppKit/*.swift" - s.osx.exclude_files = [ - "Sources/Core/Internal/DisplayLink-iOS+tvOS.swift", - "Sources/Core/Internal/Screen-iOS.swift" - ] - s.tvos.source_files = "Sources/Integrations/UIKit/*.swift" - s.tvos.exclude_files = [ - "Sources/Core/Internal/ClickGestureRecognizer-macOS.swift", - "Sources/Core/Internal/DisplayLink-macOS.swift", - "Sources/Core/Internal/EdgeInsets-macOS.swift", - "Sources/Core/Internal/Image-macOS.swift", - "Sources/Core/Internal/Screen-macOS.swift" - ] - s.frameworks = "Foundation", "CoreGraphics", "QuartzCore" -end diff --git a/ImagineEngine.xcodeproj/project.pbxproj b/ImagineEngine.xcodeproj/project.pbxproj deleted file mode 100644 index 8384720..0000000 --- a/ImagineEngine.xcodeproj/project.pbxproj +++ /dev/null @@ -1,1906 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 47; - objects = { - -/* Begin PBXBuildFile section */ - 026CE1C41FC06B7E00A0998B /* CameraEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026CE1C31FC06B7E00A0998B /* CameraEventCollection.swift */; }; - 026CE1C51FC06B7E00A0998B /* CameraEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026CE1C31FC06B7E00A0998B /* CameraEventCollection.swift */; }; - 026CE1C61FC06B7E00A0998B /* CameraEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 026CE1C31FC06B7E00A0998B /* CameraEventCollection.swift */; }; - 5204849D1FA353590011D372 /* ClickGestureRecognizerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5204849C1FA353590011D372 /* ClickGestureRecognizerMock.swift */; }; - 5204849E1FA353590011D372 /* ClickGestureRecognizerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5204849C1FA353590011D372 /* ClickGestureRecognizerMock.swift */; }; - 520484A21FA357070011D372 /* ClickGestureRecognizer-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5204849F1FA356F80011D372 /* ClickGestureRecognizer-macOS.swift */; }; - 5209C845208BE4A90033DB4A /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C844208BE4A90033DB4A /* Node.swift */; }; - 5209C846208BE4A90033DB4A /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C844208BE4A90033DB4A /* Node.swift */; }; - 5209C847208BE4A90033DB4A /* Node.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C844208BE4A90033DB4A /* Node.swift */; }; - 5209C849208BE8EB0033DB4A /* AnyNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C848208BE8EB0033DB4A /* AnyNode.swift */; }; - 5209C84A208BE8EB0033DB4A /* AnyNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C848208BE8EB0033DB4A /* AnyNode.swift */; }; - 5209C84B208BE8EB0033DB4A /* AnyNode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C848208BE8EB0033DB4A /* AnyNode.swift */; }; - 5209C84D208BEAC00033DB4A /* CALayer+Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C84C208BEAC00033DB4A /* CALayer+Transform.swift */; }; - 5209C84E208BEAC00033DB4A /* CALayer+Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C84C208BEAC00033DB4A /* CALayer+Transform.swift */; }; - 5209C84F208BEAC00033DB4A /* CALayer+Transform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C84C208BEAC00033DB4A /* CALayer+Transform.swift */; }; - 5209C854208BEFF00033DB4A /* XCTAssertEqual+CATransform3D.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C850208BEFC80033DB4A /* XCTAssertEqual+CATransform3D.swift */; }; - 5209C855208BEFF00033DB4A /* XCTAssertEqual+CATransform3D.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C850208BEFC80033DB4A /* XCTAssertEqual+CATransform3D.swift */; }; - 5209C856208BEFF10033DB4A /* XCTAssertEqual+CATransform3D.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C850208BEFC80033DB4A /* XCTAssertEqual+CATransform3D.swift */; }; - 5209C860208CC1690033DB4A /* GridPlaceable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C85F208CC1690033DB4A /* GridPlaceable.swift */; }; - 5209C861208CC1690033DB4A /* GridPlaceable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C85F208CC1690033DB4A /* GridPlaceable.swift */; }; - 5209C862208CC1690033DB4A /* GridPlaceable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5209C85F208CC1690033DB4A /* GridPlaceable.swift */; }; - 521054261FFD78B1002FCFB6 /* LabelEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521054251FFD78B1002FCFB6 /* LabelEventCollection.swift */; }; - 521054271FFD78B1002FCFB6 /* LabelEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521054251FFD78B1002FCFB6 /* LabelEventCollection.swift */; }; - 521054281FFD78B1002FCFB6 /* LabelEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 521054251FFD78B1002FCFB6 /* LabelEventCollection.swift */; }; - 522CD6691F8D451D008DB43D /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6281F8D4512008DB43D /* Action.swift */; }; - 522CD66A1F8D451D008DB43D /* ActionPerformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6291F8D4512008DB43D /* ActionPerformer.swift */; }; - 522CD66B1F8D451D008DB43D /* ActionToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62A1F8D4512008DB43D /* ActionToken.swift */; }; - 522CD66C1F8D451D008DB43D /* Actor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62B1F8D4512008DB43D /* Actor.swift */; }; - 522CD66D1F8D451D008DB43D /* ActorEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62C1F8D4512008DB43D /* ActorEventCollection.swift */; }; - 522CD66E1F8D451D008DB43D /* Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62D1F8D4512008DB43D /* Animation.swift */; }; - 522CD66F1F8D451D008DB43D /* AnimationAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62E1F8D4512008DB43D /* AnimationAction.swift */; }; - 522CD6701F8D451D008DB43D /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62F1F8D4512008DB43D /* Block.swift */; }; - 522CD6711F8D451D008DB43D /* BlockTextureCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6301F8D4512008DB43D /* BlockTextureCollection.swift */; }; - 522CD6721F8D451D008DB43D /* Camera.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6311F8D4512008DB43D /* Camera.swift */; }; - 522CD6731F8D451D008DB43D /* CancellationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6321F8D4512008DB43D /* CancellationToken.swift */; }; - 522CD6741F8D451D008DB43D /* ClosureAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6331F8D4512008DB43D /* ClosureAction.swift */; }; - 522CD6751F8D451D008DB43D /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6341F8D4512008DB43D /* Constraint.swift */; }; - 522CD6761F8D451D008DB43D /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6351F8D4512008DB43D /* Event.swift */; }; - 522CD6771F8D451D008DB43D /* EventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6361F8D4512008DB43D /* EventCollection.swift */; }; - 522CD6781F8D451D008DB43D /* EventToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6371F8D4512008DB43D /* EventToken.swift */; }; - 522CD6791F8D451D008DB43D /* Fadeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6381F8D4512008DB43D /* Fadeable.swift */; }; - 522CD67A1F8D451D008DB43D /* FadeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6391F8D4512008DB43D /* FadeAction.swift */; }; - 522CD67B1F8D451D008DB43D /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63A1F8D4512008DB43D /* Game.swift */; }; - 522CD67C1F8D451D008DB43D /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63B1F8D4512008DB43D /* Group.swift */; }; - 522CD67D1F8D451D008DB43D /* InstanceHashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63C1F8D4512008DB43D /* InstanceHashable.swift */; }; - 522CD67E1F8D451D008DB43D /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63D1F8D4512008DB43D /* Label.swift */; }; - 522CD67F1F8D451D008DB43D /* MetricAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63E1F8D4512008DB43D /* MetricAction.swift */; }; - 522CD6801F8D451D008DB43D /* Mirroring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63F1F8D4512008DB43D /* Mirroring.swift */; }; - 522CD6811F8D451D008DB43D /* Movable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6401F8D4512008DB43D /* Movable.swift */; }; - 522CD6821F8D451D008DB43D /* MoveAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6411F8D4512008DB43D /* MoveAction.swift */; }; - 522CD6831F8D451D008DB43D /* Plugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6421F8D4512008DB43D /* Plugin.swift */; }; - 522CD6841F8D451D008DB43D /* RepeatAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6431F8D4512008DB43D /* RepeatAction.swift */; }; - 522CD6851F8D451D008DB43D /* RepeatMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6441F8D4512008DB43D /* RepeatMode.swift */; }; - 522CD6861F8D451D008DB43D /* Rotatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6451F8D4512008DB43D /* Rotatable.swift */; }; - 522CD6871F8D451D008DB43D /* RotateAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6461F8D4512008DB43D /* RotateAction.swift */; }; - 522CD6881F8D451D008DB43D /* Scalable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6471F8D4512008DB43D /* Scalable.swift */; }; - 522CD6891F8D451D008DB43D /* ScaleAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6481F8D4512008DB43D /* ScaleAction.swift */; }; - 522CD68A1F8D451D008DB43D /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6491F8D4512008DB43D /* Scene.swift */; }; - 522CD68B1F8D451D008DB43D /* SceneEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64A1F8D4512008DB43D /* SceneEventCollection.swift */; }; - 522CD68C1F8D451D008DB43D /* Texture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64B1F8D4512008DB43D /* Texture.swift */; }; - 522CD68D1F8D451D008DB43D /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64C1F8D4512008DB43D /* Timeline.swift */; }; - 522CD68E1F8D451D008DB43D /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64D1F8D4512008DB43D /* Typealiases.swift */; }; - 522CD68F1F8D4521008DB43D /* ActionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64F1F8D4512008DB43D /* ActionManager.swift */; }; - 522CD6901F8D4521008DB43D /* ActionWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6501F8D4512008DB43D /* ActionWrapper.swift */; }; - 522CD6911F8D4521008DB43D /* Activatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6511F8D4512008DB43D /* Activatable.swift */; }; - 522CD6921F8D4521008DB43D /* ClickPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6521F8D4512008DB43D /* ClickPlugin.swift */; }; - 522CD6931F8D4521008DB43D /* ClosureUpdatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6531F8D4512008DB43D /* ClosureUpdatable.swift */; }; - 522CD6941F8D4521008DB43D /* DisplayLink-iOS+tvOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6541F8D4512008DB43D /* DisplayLink-iOS+tvOS.swift */; }; - 522CD6971F8D4521008DB43D /* GameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6571F8D4512008DB43D /* GameView.swift */; }; - 522CD6981F8D4521008DB43D /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6581F8D4512008DB43D /* Grid.swift */; }; - 522CD6991F8D4521008DB43D /* Layer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6591F8D4512008DB43D /* Layer.swift */; }; - 522CD69A1F8D4521008DB43D /* LoadedTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65A1F8D4512008DB43D /* LoadedTexture.swift */; }; - 522CD69B1F8D4521008DB43D /* Optional+GetOrSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65B1F8D4512008DB43D /* Optional+GetOrSet.swift */; }; - 522CD69C1F8D4521008DB43D /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65C1F8D4512008DB43D /* PluginManager.swift */; }; - 522CD69D1F8D4521008DB43D /* PluginWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65D1F8D4512008DB43D /* PluginWrapper.swift */; }; - 522CD69E1F8D4521008DB43D /* ReplicatorLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65E1F8D4512008DB43D /* ReplicatorLayer.swift */; }; - 522CD69F1F8D4521008DB43D /* TextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65F1F8D4512008DB43D /* TextLayer.swift */; }; - 522CD6A01F8D4521008DB43D /* TextureManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6601F8D4512008DB43D /* TextureManager.swift */; }; - 522CD6A11F8D4521008DB43D /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6611F8D4512008DB43D /* Updatable.swift */; }; - 522CD6A21F8D4521008DB43D /* UpdatableWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6621F8D4512008DB43D /* UpdatableWrapper.swift */; }; - 522CD6A31F8D4521008DB43D /* UpdateOutcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6631F8D4512008DB43D /* UpdateOutcome.swift */; }; - 522CD6A41F8D4521008DB43D /* View+MakeLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6641F8D4512008DB43D /* View+MakeLayer.swift */; }; - 522CD6A51F8D4526008DB43D /* GameViewController-iOS+tvOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6671F8D4512008DB43D /* GameViewController-iOS+tvOS.swift */; }; - 522CD6A61F8D4526008DB43D /* GameWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6681F8D4512008DB43D /* GameWindow.swift */; }; - 523E5D101F9FEFBC0084792C /* SpriteSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523E5D0F1F9FEFBC0084792C /* SpriteSheet.swift */; }; - 523E5D111F9FEFBC0084792C /* SpriteSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523E5D0F1F9FEFBC0084792C /* SpriteSheet.swift */; }; - 52479F801F8E58E200D22A87 /* TextureImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F7F1F8E58E200D22A87 /* TextureImageLoader.swift */; }; - 52479F821F8E5A6F00D22A87 /* TextureImageLoaderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F811F8E5A6F00D22A87 /* TextureImageLoaderMock.swift */; }; - 52479F841F8E7B4E00D22A87 /* SceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F831F8E7B4E00D22A87 /* SceneTests.swift */; }; - 52479F851F8E7BFA00D22A87 /* Assert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860321F8E381600C6C7A7 /* Assert.swift */; }; - 52479F861F8E7BFD00D22A87 /* TimeTraveler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860331F8E381600C6C7A7 /* TimeTraveler.swift */; }; - 52479F881F8E7CAF00D22A87 /* PluginMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F871F8E7CAF00D22A87 /* PluginMock.swift */; }; - 52479F8A1F8E804F00D22A87 /* TimelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F891F8E804F00D22A87 /* TimelineTests.swift */; }; - 52479F8C1F8E818100D22A87 /* ActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F8B1F8E818100D22A87 /* ActionTests.swift */; }; - 52479F8E1F8E823E00D22A87 /* ActionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F8D1F8E823E00D22A87 /* ActionMock.swift */; }; - 524B329F205488D50069A4A1 /* SpriteSheetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524B329E205488D50069A4A1 /* SpriteSheetTests.swift */; }; - 524B32A0205488D50069A4A1 /* SpriteSheetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524B329E205488D50069A4A1 /* SpriteSheetTests.swift */; }; - 524B32A1205488D50069A4A1 /* SpriteSheetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524B329E205488D50069A4A1 /* SpriteSheetTests.swift */; }; - 5253C79B1FA4D54000D304B5 /* GameViewController-iOS+tvOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6671F8D4512008DB43D /* GameViewController-iOS+tvOS.swift */; }; - 5253C79C1FA4D54000D304B5 /* GameWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6681F8D4512008DB43D /* GameWindow.swift */; }; - 5253C79D1FA4D56C00D304B5 /* ActionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64F1F8D4512008DB43D /* ActionManager.swift */; }; - 5253C79E1FA4D56C00D304B5 /* ActionWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6501F8D4512008DB43D /* ActionWrapper.swift */; }; - 5253C79F1FA4D56C00D304B5 /* Activatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6511F8D4512008DB43D /* Activatable.swift */; }; - 5253C7A01FA4D56C00D304B5 /* ClickPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6521F8D4512008DB43D /* ClickPlugin.swift */; }; - 5253C7A11FA4D56C00D304B5 /* ClosureUpdatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6531F8D4512008DB43D /* ClosureUpdatable.swift */; }; - 5253C7A21FA4D56C00D304B5 /* DisplayLinkProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860371F8E3A4900C6C7A7 /* DisplayLinkProtocol.swift */; }; - 5253C7A31FA4D56C00D304B5 /* DisplayLink-iOS+tvOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6541F8D4512008DB43D /* DisplayLink-iOS+tvOS.swift */; }; - 5253C7A41FA4D56C00D304B5 /* GameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6571F8D4512008DB43D /* GameView.swift */; }; - 5253C7A51FA4D56C00D304B5 /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6581F8D4512008DB43D /* Grid.swift */; }; - 5253C7A61FA4D56C00D304B5 /* Layer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6591F8D4512008DB43D /* Layer.swift */; }; - 5253C7A71FA4D56C00D304B5 /* LoadedTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65A1F8D4512008DB43D /* LoadedTexture.swift */; }; - 5253C7A81FA4D56C00D304B5 /* Optional+GetOrSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65B1F8D4512008DB43D /* Optional+GetOrSet.swift */; }; - 5253C7A91FA4D56C00D304B5 /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65C1F8D4512008DB43D /* PluginManager.swift */; }; - 5253C7AA1FA4D56C00D304B5 /* PluginWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65D1F8D4512008DB43D /* PluginWrapper.swift */; }; - 5253C7AB1FA4D56C00D304B5 /* ReplicatorLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65E1F8D4512008DB43D /* ReplicatorLayer.swift */; }; - 5253C7AC1FA4D56C00D304B5 /* Screen-iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525688B41F9CF08E00F87786 /* Screen-iOS.swift */; }; - 5253C7AD1FA4D56C00D304B5 /* TextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65F1F8D4512008DB43D /* TextLayer.swift */; }; - 5253C7AE1FA4D56C00D304B5 /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6611F8D4512008DB43D /* Updatable.swift */; }; - 5253C7AF1FA4D56C00D304B5 /* UpdatableCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528B21501FA382B300CE9967 /* UpdatableCollection.swift */; }; - 5253C7B01FA4D56C00D304B5 /* UpdatableWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6621F8D4512008DB43D /* UpdatableWrapper.swift */; }; - 5253C7B11FA4D56C00D304B5 /* UpdateOutcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6631F8D4512008DB43D /* UpdateOutcome.swift */; }; - 5253C7B21FA4D56C00D304B5 /* View+MakeLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6641F8D4512008DB43D /* View+MakeLayer.swift */; }; - 5253C7B31FA4D57200D304B5 /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6281F8D4512008DB43D /* Action.swift */; }; - 5253C7B41FA4D57200D304B5 /* ActionPerformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6291F8D4512008DB43D /* ActionPerformer.swift */; }; - 5253C7B51FA4D57200D304B5 /* ActionToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62A1F8D4512008DB43D /* ActionToken.swift */; }; - 5253C7B61FA4D57200D304B5 /* Actor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62B1F8D4512008DB43D /* Actor.swift */; }; - 5253C7B71FA4D57200D304B5 /* ActorEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62C1F8D4512008DB43D /* ActorEventCollection.swift */; }; - 5253C7B81FA4D57200D304B5 /* Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62D1F8D4512008DB43D /* Animation.swift */; }; - 5253C7B91FA4D57200D304B5 /* AnimationAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62E1F8D4512008DB43D /* AnimationAction.swift */; }; - 5253C7BA1FA4D57200D304B5 /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62F1F8D4512008DB43D /* Block.swift */; }; - 5253C7BB1FA4D57200D304B5 /* BlockTextureCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6301F8D4512008DB43D /* BlockTextureCollection.swift */; }; - 5253C7BC1FA4D57200D304B5 /* Camera.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6311F8D4512008DB43D /* Camera.swift */; }; - 5253C7BD1FA4D57200D304B5 /* CancellationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6321F8D4512008DB43D /* CancellationToken.swift */; }; - 5253C7BE1FA4D57200D304B5 /* ClosureAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6331F8D4512008DB43D /* ClosureAction.swift */; }; - 5253C7BF1FA4D57200D304B5 /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6341F8D4512008DB43D /* Constraint.swift */; }; - 5253C7C01FA4D57200D304B5 /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6351F8D4512008DB43D /* Event.swift */; }; - 5253C7C11FA4D57200D304B5 /* EventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6361F8D4512008DB43D /* EventCollection.swift */; }; - 5253C7C21FA4D57200D304B5 /* EventToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6371F8D4512008DB43D /* EventToken.swift */; }; - 5253C7C31FA4D57200D304B5 /* Fadeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6381F8D4512008DB43D /* Fadeable.swift */; }; - 5253C7C41FA4D57200D304B5 /* FadeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6391F8D4512008DB43D /* FadeAction.swift */; }; - 5253C7C51FA4D57200D304B5 /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63A1F8D4512008DB43D /* Game.swift */; }; - 5253C7C61FA4D57200D304B5 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63B1F8D4512008DB43D /* Group.swift */; }; - 5253C7C71FA4D57200D304B5 /* InstanceHashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63C1F8D4512008DB43D /* InstanceHashable.swift */; }; - 5253C7C81FA4D57200D304B5 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63D1F8D4512008DB43D /* Label.swift */; }; - 5253C7C91FA4D57200D304B5 /* MetricAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63E1F8D4512008DB43D /* MetricAction.swift */; }; - 5253C7CA1FA4D57200D304B5 /* Mirroring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63F1F8D4512008DB43D /* Mirroring.swift */; }; - 5253C7CB1FA4D57200D304B5 /* Movable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6401F8D4512008DB43D /* Movable.swift */; }; - 5253C7CC1FA4D57200D304B5 /* MoveAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6411F8D4512008DB43D /* MoveAction.swift */; }; - 5253C7CD1FA4D57200D304B5 /* Plugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6421F8D4512008DB43D /* Plugin.swift */; }; - 5253C7CE1FA4D57200D304B5 /* RepeatAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6431F8D4512008DB43D /* RepeatAction.swift */; }; - 5253C7CF1FA4D57200D304B5 /* RepeatMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6441F8D4512008DB43D /* RepeatMode.swift */; }; - 5253C7D01FA4D57200D304B5 /* Rotatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6451F8D4512008DB43D /* Rotatable.swift */; }; - 5253C7D11FA4D57200D304B5 /* RotateAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6461F8D4512008DB43D /* RotateAction.swift */; }; - 5253C7D21FA4D57200D304B5 /* Scalable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6471F8D4512008DB43D /* Scalable.swift */; }; - 5253C7D31FA4D57200D304B5 /* ScaleAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6481F8D4512008DB43D /* ScaleAction.swift */; }; - 5253C7D41FA4D57200D304B5 /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6491F8D4512008DB43D /* Scene.swift */; }; - 5253C7D51FA4D57200D304B5 /* SceneEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64A1F8D4512008DB43D /* SceneEventCollection.swift */; }; - 5253C7D61FA4D57200D304B5 /* SpriteSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 523E5D0F1F9FEFBC0084792C /* SpriteSheet.swift */; }; - 5253C7D71FA4D57200D304B5 /* Texture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64B1F8D4512008DB43D /* Texture.swift */; }; - 5253C7D81FA4D57200D304B5 /* TextureImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F7F1F8E58E200D22A87 /* TextureImageLoader.swift */; }; - 5253C7D91FA4D57200D304B5 /* TextureManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6601F8D4512008DB43D /* TextureManager.swift */; }; - 5253C7DA1FA4D57200D304B5 /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64C1F8D4512008DB43D /* Timeline.swift */; }; - 5253C7DB1FA4D57200D304B5 /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64D1F8D4512008DB43D /* Typealiases.swift */; }; - 5253C7DD1FA4D66500D304B5 /* Font+Default.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5253C7DC1FA4D66500D304B5 /* Font+Default.swift */; }; - 5253C7DE1FA4D7E400D304B5 /* Font+Default.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5253C7DC1FA4D66500D304B5 /* Font+Default.swift */; }; - 5253C7DF1FA4D7E500D304B5 /* Font+Default.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5253C7DC1FA4D66500D304B5 /* Font+Default.swift */; }; - 5253C7E01FA4D97D00D304B5 /* ActorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8602D1F8E36B600C6C7A7 /* ActorTests.swift */; }; - 5253C7E11FA4D97D00D304B5 /* ActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F8B1F8E818100D22A87 /* ActionTests.swift */; }; - 5253C7E21FA4D97D00D304B5 /* CameraTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC8071F8EB83F006B1295 /* CameraTests.swift */; }; - 5253C7E31FA4D97D00D304B5 /* EventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC8051F8EB223006B1295 /* EventTests.swift */; }; - 5253C7E41FA4D97D00D304B5 /* LabelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC80B1F8EBAAB006B1295 /* LabelTests.swift */; }; - 5253C7E51FA4D97D00D304B5 /* SceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F831F8E7B4E00D22A87 /* SceneTests.swift */; }; - 5253C7E61FA4D97D00D304B5 /* TextureManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86A78BD1FA1B61A0099632B /* TextureManagerTests.swift */; }; - 5253C7E71FA4D97D00D304B5 /* TimelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F891F8E804F00D22A87 /* TimelineTests.swift */; }; - 5253C7E81FA4D97D00D304B5 /* ActionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F8D1F8E823E00D22A87 /* ActionMock.swift */; }; - 5253C7E91FA4D97D00D304B5 /* ClickGestureRecognizerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5204849C1FA353590011D372 /* ClickGestureRecognizerMock.swift */; }; - 5253C7EA1FA4D97D00D304B5 /* DisplayLinkMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8603C1F8E537C00C6C7A7 /* DisplayLinkMock.swift */; }; - 5253C7EB1FA4D97D00D304B5 /* GameMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8603A1F8E535100C6C7A7 /* GameMock.swift */; }; - 5253C7EC1FA4D97D00D304B5 /* PluginMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F871F8E7CAF00D22A87 /* PluginMock.swift */; }; - 5253C7ED1FA4D97D00D304B5 /* TextureImageLoaderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F811F8E5A6F00D22A87 /* TextureImageLoaderMock.swift */; }; - 5253C7EE1FA4D97D00D304B5 /* Assert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860321F8E381600C6C7A7 /* Assert.swift */; }; - 5253C7EF1FA4D97D00D304B5 /* TimeTraveler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860331F8E381600C6C7A7 /* TimeTraveler.swift */; }; - 5253C7F01FA4D97D00D304B5 /* ImageMockFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860341F8E382800C6C7A7 /* ImageMockFactory.swift */; }; - 5253C80F1FA4E04A00D304B5 /* BundleTextureImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D2FCE41FA493940077B560 /* BundleTextureImageLoader.swift */; }; - 525688B51F9CF08E00F87786 /* Screen-iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525688B41F9CF08E00F87786 /* Screen-iOS.swift */; }; - 525688BF1F9CF33100F87786 /* ImagineEngine.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD21B7361F92E75A0034A7CE /* ImagineEngine.framework */; }; - 525688C51F9CF3E200F87786 /* ActorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8602D1F8E36B600C6C7A7 /* ActorTests.swift */; }; - 525688C61F9CF3E200F87786 /* ActionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F8B1F8E818100D22A87 /* ActionTests.swift */; }; - 525688C71F9CF3E200F87786 /* CameraTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC8071F8EB83F006B1295 /* CameraTests.swift */; }; - 525688C81F9CF3E200F87786 /* EventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC8051F8EB223006B1295 /* EventTests.swift */; }; - 525688C91F9CF3E200F87786 /* LabelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC80B1F8EBAAB006B1295 /* LabelTests.swift */; }; - 525688CA1F9CF3E200F87786 /* SceneTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F831F8E7B4E00D22A87 /* SceneTests.swift */; }; - 525688CB1F9CF3E200F87786 /* TimelineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F891F8E804F00D22A87 /* TimelineTests.swift */; }; - 525688CC1F9CF3E200F87786 /* ActionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F8D1F8E823E00D22A87 /* ActionMock.swift */; }; - 525688CD1F9CF3E200F87786 /* DisplayLinkMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8603C1F8E537C00C6C7A7 /* DisplayLinkMock.swift */; }; - 525688CE1F9CF3E200F87786 /* GameMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8603A1F8E535100C6C7A7 /* GameMock.swift */; }; - 525688CF1F9CF3E200F87786 /* PluginMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F871F8E7CAF00D22A87 /* PluginMock.swift */; }; - 525688D01F9CF3E200F87786 /* TextureImageLoaderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F811F8E5A6F00D22A87 /* TextureImageLoaderMock.swift */; }; - 525688D11F9CF3E200F87786 /* Assert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860321F8E381600C6C7A7 /* Assert.swift */; }; - 525688D21F9CF3E200F87786 /* TimeTraveler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860331F8E381600C6C7A7 /* TimeTraveler.swift */; }; - 525688D31F9CF3E200F87786 /* ImageMockFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860341F8E382800C6C7A7 /* ImageMockFactory.swift */; }; - 5256F9772053D989003F3F88 /* Coordinate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5256F9762053D989003F3F88 /* Coordinate.swift */; }; - 5256F9782053D989003F3F88 /* Coordinate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5256F9762053D989003F3F88 /* Coordinate.swift */; }; - 5256F9792053D989003F3F88 /* Coordinate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5256F9762053D989003F3F88 /* Coordinate.swift */; }; - 5262A1CD1FA4CD1900DD5B3D /* ImagineEngine.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5262A1BC1FA4CCF900DD5B3D /* ImagineEngine.framework */; }; - 527FC8061F8EB223006B1295 /* EventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC8051F8EB223006B1295 /* EventTests.swift */; }; - 527FC8081F8EB83F006B1295 /* CameraTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC8071F8EB83F006B1295 /* CameraTests.swift */; }; - 527FC80C1F8EBAAB006B1295 /* LabelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527FC80B1F8EBAAB006B1295 /* LabelTests.swift */; }; - 528B21511FA382B300CE9967 /* UpdatableCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528B21501FA382B300CE9967 /* UpdatableCollection.swift */; }; - 528B21521FA382B300CE9967 /* UpdatableCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528B21501FA382B300CE9967 /* UpdatableCollection.swift */; }; - 52A124CD1FAB9F9700252047 /* GameViewMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A124CC1FAB9F9700252047 /* GameViewMock.swift */; }; - 52A124CE1FAB9F9700252047 /* GameViewMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A124CC1FAB9F9700252047 /* GameViewMock.swift */; }; - 52A124CF1FAB9F9700252047 /* GameViewMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A124CC1FAB9F9700252047 /* GameViewMock.swift */; }; - 52A124D11FABA07500252047 /* EdgeInsets-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A124D01FABA07500252047 /* EdgeInsets-macOS.swift */; }; - 52A124D31FABA8AB00252047 /* Pluggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A124D21FABA8AB00252047 /* Pluggable.swift */; }; - 52A124D41FABA8AB00252047 /* Pluggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A124D21FABA8AB00252047 /* Pluggable.swift */; }; - 52A124D51FABA8AB00252047 /* Pluggable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A124D21FABA8AB00252047 /* Pluggable.swift */; }; - 52B8065E1FB373BC0042FBA7 /* ZIndexed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8065D1FB373BC0042FBA7 /* ZIndexed.swift */; }; - 52B8065F1FB373BC0042FBA7 /* ZIndexed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8065D1FB373BC0042FBA7 /* ZIndexed.swift */; }; - 52B806601FB373BC0042FBA7 /* ZIndexed.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8065D1FB373BC0042FBA7 /* ZIndexed.swift */; }; - 52B8066A1FB3B6180042FBA7 /* BlockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B806691FB3B6180042FBA7 /* BlockTests.swift */; }; - 52B8066B1FB3B6180042FBA7 /* BlockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B806691FB3B6180042FBA7 /* BlockTests.swift */; }; - 52B8066C1FB3B6180042FBA7 /* BlockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B806691FB3B6180042FBA7 /* BlockTests.swift */; }; - 52C860301F8E374100C6C7A7 /* ActorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8602D1F8E36B600C6C7A7 /* ActorTests.swift */; }; - 52C860361F8E383100C6C7A7 /* ImageMockFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860341F8E382800C6C7A7 /* ImageMockFactory.swift */; }; - 52C860381F8E3A4900C6C7A7 /* DisplayLinkProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860371F8E3A4900C6C7A7 /* DisplayLinkProtocol.swift */; }; - 52C8603B1F8E535100C6C7A7 /* GameMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8603A1F8E535100C6C7A7 /* GameMock.swift */; }; - 52C8603D1F8E537C00C6C7A7 /* DisplayLinkMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C8603C1F8E537C00C6C7A7 /* DisplayLinkMock.swift */; }; - 52D6D9871BEFF229002C0205 /* ImagineEngine.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D6D97C1BEFF229002C0205 /* ImagineEngine.framework */; }; - 52E725921FCF68AB0099FCC7 /* Shadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52E725911FCF68AB0099FCC7 /* Shadow.swift */; }; - 52E725931FCF68AB0099FCC7 /* Shadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52E725911FCF68AB0099FCC7 /* Shadow.swift */; }; - 52E725941FCF68AB0099FCC7 /* Shadow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52E725911FCF68AB0099FCC7 /* Shadow.swift */; }; - C800CE2D1FA77F74008EE08D /* BundleProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE2C1FA77F74008EE08D /* BundleProtocol.swift */; }; - C800CE2E1FA77F74008EE08D /* BundleProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE2C1FA77F74008EE08D /* BundleProtocol.swift */; }; - C800CE301FA782EA008EE08D /* TextureFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE2F1FA782EA008EE08D /* TextureFormat.swift */; }; - C800CE311FA782EA008EE08D /* TextureFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE2F1FA782EA008EE08D /* TextureFormat.swift */; }; - C800CE331FA788A5008EE08D /* BundleTextureImageLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE321FA788A5008EE08D /* BundleTextureImageLoaderTests.swift */; }; - C800CE341FA788A5008EE08D /* BundleTextureImageLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE321FA788A5008EE08D /* BundleTextureImageLoaderTests.swift */; }; - C800CE391FA78C74008EE08D /* BundleMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE381FA78C74008EE08D /* BundleMock.swift */; }; - C800CE3A1FA78C74008EE08D /* BundleMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE381FA78C74008EE08D /* BundleMock.swift */; }; - C800CE3F1FA790AA008EE08D /* sample.png in Resources */ = {isa = PBXBuildFile; fileRef = C800CE3C1FA790A9008EE08D /* sample.png */; }; - C800CE411FA790AA008EE08D /* sample.jpg in Resources */ = {isa = PBXBuildFile; fileRef = C800CE3D1FA790A9008EE08D /* sample.jpg */; }; - C809426E1FA798B7002B42A6 /* sample.jpg in Resources */ = {isa = PBXBuildFile; fileRef = C800CE3D1FA790A9008EE08D /* sample.jpg */; }; - C809426F1FA798B7002B42A6 /* sample.png in Resources */ = {isa = PBXBuildFile; fileRef = C800CE3C1FA790A9008EE08D /* sample.png */; }; - C80942701FA79925002B42A6 /* TextureFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE2F1FA782EA008EE08D /* TextureFormat.swift */; }; - C80942711FA79934002B42A6 /* BundleProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE2C1FA77F74008EE08D /* BundleProtocol.swift */; }; - C80942731FA7994C002B42A6 /* BundleTextureImageLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE321FA788A5008EE08D /* BundleTextureImageLoaderTests.swift */; }; - C80942751FA7995B002B42A6 /* BundleMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = C800CE381FA78C74008EE08D /* BundleMock.swift */; }; - C80942761FA7997B002B42A6 /* sample.jpg in Resources */ = {isa = PBXBuildFile; fileRef = C800CE3D1FA790A9008EE08D /* sample.jpg */; }; - C80942771FA7997B002B42A6 /* sample.png in Resources */ = {isa = PBXBuildFile; fileRef = C800CE3C1FA790A9008EE08D /* sample.png */; }; - C86A78BE1FA1B61A0099632B /* TextureManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86A78BD1FA1B61A0099632B /* TextureManagerTests.swift */; }; - C86A78BF1FA1B61A0099632B /* TextureManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C86A78BD1FA1B61A0099632B /* TextureManagerTests.swift */; }; - C8D2FCE51FA493940077B560 /* BundleTextureImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D2FCE41FA493940077B560 /* BundleTextureImageLoader.swift */; }; - C8D2FCE61FA493940077B560 /* BundleTextureImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8D2FCE41FA493940077B560 /* BundleTextureImageLoader.swift */; }; - CDC7F0041FC419F300782197 /* TextureErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC7F0031FC419F300782197 /* TextureErrorHandler.swift */; }; - CDC7F0051FC419F300782197 /* TextureErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC7F0031FC419F300782197 /* TextureErrorHandler.swift */; }; - CDC7F0061FC419F300782197 /* TextureErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC7F0031FC419F300782197 /* TextureErrorHandler.swift */; }; - CDC7F00B1FC42E6500782197 /* TextureErrorHandlerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC7F0071FC42D4800782197 /* TextureErrorHandlerMock.swift */; }; - CDC7F00C1FC42E6600782197 /* TextureErrorHandlerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC7F0071FC42D4800782197 /* TextureErrorHandlerMock.swift */; }; - CDC7F00D1FC42E6700782197 /* TextureErrorHandlerMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = CDC7F0071FC42D4800782197 /* TextureErrorHandlerMock.swift */; }; - DD21B6F21F92E75A0034A7CE /* View+MakeLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6641F8D4512008DB43D /* View+MakeLayer.swift */; }; - DD21B6F31F92E75A0034A7CE /* PluginWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65D1F8D4512008DB43D /* PluginWrapper.swift */; }; - DD21B6F41F92E75A0034A7CE /* Scalable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6471F8D4512008DB43D /* Scalable.swift */; }; - DD21B6F51F92E75A0034A7CE /* Plugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6421F8D4512008DB43D /* Plugin.swift */; }; - DD21B6F61F92E75A0034A7CE /* ActorEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62C1F8D4512008DB43D /* ActorEventCollection.swift */; }; - DD21B6F71F92E75A0034A7CE /* Movable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6401F8D4512008DB43D /* Movable.swift */; }; - DD21B6F81F92E75A0034A7CE /* Optional+GetOrSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65B1F8D4512008DB43D /* Optional+GetOrSet.swift */; }; - DD21B6F91F92E75A0034A7CE /* ClosureAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6331F8D4512008DB43D /* ClosureAction.swift */; }; - DD21B6FA1F92E75A0034A7CE /* RepeatAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6431F8D4512008DB43D /* RepeatAction.swift */; }; - DD21B6FB1F92E75A0034A7CE /* ClosureUpdatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6531F8D4512008DB43D /* ClosureUpdatable.swift */; }; - DD21B6FC1F92E75A0034A7CE /* LoadedTexture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65A1F8D4512008DB43D /* LoadedTexture.swift */; }; - DD21B6FD1F92E75A0034A7CE /* Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62F1F8D4512008DB43D /* Block.swift */; }; - DD21B6FE1F92E75A0034A7CE /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6611F8D4512008DB43D /* Updatable.swift */; }; - DD21B7001F92E75A0034A7CE /* Layer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6591F8D4512008DB43D /* Layer.swift */; }; - DD21B7011F92E75A0034A7CE /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6581F8D4512008DB43D /* Grid.swift */; }; - DD21B7031F92E75A0034A7CE /* GameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6571F8D4512008DB43D /* GameView.swift */; }; - DD21B7041F92E75A0034A7CE /* Activatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6511F8D4512008DB43D /* Activatable.swift */; }; - DD21B7051F92E75A0034A7CE /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63B1F8D4512008DB43D /* Group.swift */; }; - DD21B7061F92E75A0034A7CE /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63D1F8D4512008DB43D /* Label.swift */; }; - DD21B7071F92E75A0034A7CE /* UpdatableWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6621F8D4512008DB43D /* UpdatableWrapper.swift */; }; - DD21B7081F92E75A0034A7CE /* CancellationToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6321F8D4512008DB43D /* CancellationToken.swift */; }; - DD21B7091F92E75A0034A7CE /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6491F8D4512008DB43D /* Scene.swift */; }; - DD21B70A1F92E75A0034A7CE /* TextureImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52479F7F1F8E58E200D22A87 /* TextureImageLoader.swift */; }; - DD21B70B1F92E75A0034A7CE /* ActionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64F1F8D4512008DB43D /* ActionManager.swift */; }; - DD21B70C1F92E75A0034A7CE /* SceneEventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64A1F8D4512008DB43D /* SceneEventCollection.swift */; }; - DD21B70D1F92E75A0034A7CE /* ActionWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6501F8D4512008DB43D /* ActionWrapper.swift */; }; - DD21B70E1F92E75A0034A7CE /* EventCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6361F8D4512008DB43D /* EventCollection.swift */; }; - DD21B70F1F92E75A0034A7CE /* BlockTextureCollection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6301F8D4512008DB43D /* BlockTextureCollection.swift */; }; - DD21B7101F92E75A0034A7CE /* AnimationAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62E1F8D4512008DB43D /* AnimationAction.swift */; }; - DD21B7111F92E75A0034A7CE /* ScaleAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6481F8D4512008DB43D /* ScaleAction.swift */; }; - DD21B7121F92E75A0034A7CE /* ActionToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62A1F8D4512008DB43D /* ActionToken.swift */; }; - DD21B7131F92E75A0034A7CE /* TextLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65F1F8D4512008DB43D /* TextLayer.swift */; }; - DD21B7151F92E75A0034A7CE /* Fadeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6381F8D4512008DB43D /* Fadeable.swift */; }; - DD21B7161F92E75A0034A7CE /* RotateAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6461F8D4512008DB43D /* RotateAction.swift */; }; - DD21B7181F92E75A0034A7CE /* PluginManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65C1F8D4512008DB43D /* PluginManager.swift */; }; - DD21B7191F92E75A0034A7CE /* InstanceHashable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63C1F8D4512008DB43D /* InstanceHashable.swift */; }; - DD21B71A1F92E75A0034A7CE /* ActionPerformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6291F8D4512008DB43D /* ActionPerformer.swift */; }; - DD21B71B1F92E75A0034A7CE /* Rotatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6451F8D4512008DB43D /* Rotatable.swift */; }; - DD21B71C1F92E75A0034A7CE /* Camera.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6311F8D4512008DB43D /* Camera.swift */; }; - DD21B71D1F92E75A0034A7CE /* FadeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6391F8D4512008DB43D /* FadeAction.swift */; }; - DD21B71E1F92E75A0034A7CE /* Action.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6281F8D4512008DB43D /* Action.swift */; }; - DD21B71F1F92E75A0034A7CE /* Texture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64B1F8D4512008DB43D /* Texture.swift */; }; - DD21B7201F92E75A0034A7CE /* UpdateOutcome.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6631F8D4512008DB43D /* UpdateOutcome.swift */; }; - DD21B7211F92E75A0034A7CE /* MetricAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63E1F8D4512008DB43D /* MetricAction.swift */; }; - DD21B7221F92E75A0034A7CE /* Animation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62D1F8D4512008DB43D /* Animation.swift */; }; - DD21B7231F92E75A0034A7CE /* Game.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63A1F8D4512008DB43D /* Game.swift */; }; - DD21B7241F92E75A0034A7CE /* Mirroring.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD63F1F8D4512008DB43D /* Mirroring.swift */; }; - DD21B7251F92E75A0034A7CE /* Actor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD62B1F8D4512008DB43D /* Actor.swift */; }; - DD21B7261F92E75A0034A7CE /* Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64C1F8D4512008DB43D /* Timeline.swift */; }; - DD21B7271F92E75A0034A7CE /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6351F8D4512008DB43D /* Event.swift */; }; - DD21B7281F92E75A0034A7CE /* EventToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6371F8D4512008DB43D /* EventToken.swift */; }; - DD21B7291F92E75A0034A7CE /* MoveAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6411F8D4512008DB43D /* MoveAction.swift */; }; - DD21B72A1F92E75A0034A7CE /* TextureManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6601F8D4512008DB43D /* TextureManager.swift */; }; - DD21B72B1F92E75A0034A7CE /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6341F8D4512008DB43D /* Constraint.swift */; }; - DD21B72C1F92E75A0034A7CE /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD64D1F8D4512008DB43D /* Typealiases.swift */; }; - DD21B72D1F92E75A0034A7CE /* DisplayLinkProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52C860371F8E3A4900C6C7A7 /* DisplayLinkProtocol.swift */; }; - DD21B72E1F92E75A0034A7CE /* ReplicatorLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD65E1F8D4512008DB43D /* ReplicatorLayer.swift */; }; - DD21B72F1F92E75A0034A7CE /* RepeatMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6441F8D4512008DB43D /* RepeatMode.swift */; }; - DD21B73A1F92E8240034A7CE /* Image-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD21B7381F92E81C0034A7CE /* Image-macOS.swift */; }; - DD21B73D1F92E8CB0034A7CE /* Screen-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD21B73B1F92E8B90034A7CE /* Screen-macOS.swift */; }; - DD21B7411F92EA610034A7CE /* ClickPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522CD6521F8D4512008DB43D /* ClickPlugin.swift */; }; - DD21B7441F92EB1A0034A7CE /* DisplayLink-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD21B7421F92EB140034A7CE /* DisplayLink-macOS.swift */; }; - DD21B7481F92EC800034A7CE /* GameViewController-macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD21B7461F92EC610034A7CE /* GameViewController-macOS.swift */; }; - DD21B74B1F92ED6B0034A7CE /* GameWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD21B7491F92ED5E0034A7CE /* GameWindowController.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 525688C01F9CF33100F87786 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; - proxyType = 1; - remoteGlobalIDString = DD21B6F01F92E75A0034A7CE; - remoteInfo = "ImagineEngine-macOS"; - }; - 5262A1CE1FA4CD1900DD5B3D /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 5262A1BB1FA4CCF900DD5B3D; - remoteInfo = "ImagineEngine-tvOS"; - }; - 52D6D9881BEFF229002C0205 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 52D6D9731BEFF229002C0205 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 52D6D97B1BEFF229002C0205; - remoteInfo = ImagineEngine; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXFileReference section */ - 026CE1C31FC06B7E00A0998B /* CameraEventCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraEventCollection.swift; sourceTree = ""; }; - 5204849C1FA353590011D372 /* ClickGestureRecognizerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClickGestureRecognizerMock.swift; sourceTree = ""; }; - 5204849F1FA356F80011D372 /* ClickGestureRecognizer-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ClickGestureRecognizer-macOS.swift"; sourceTree = ""; }; - 5209C844208BE4A90033DB4A /* Node.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Node.swift; sourceTree = ""; }; - 5209C848208BE8EB0033DB4A /* AnyNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnyNode.swift; sourceTree = ""; }; - 5209C84C208BEAC00033DB4A /* CALayer+Transform.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CALayer+Transform.swift"; sourceTree = ""; }; - 5209C850208BEFC80033DB4A /* XCTAssertEqual+CATransform3D.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTAssertEqual+CATransform3D.swift"; sourceTree = ""; }; - 5209C85F208CC1690033DB4A /* GridPlaceable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GridPlaceable.swift; sourceTree = ""; }; - 521054251FFD78B1002FCFB6 /* LabelEventCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelEventCollection.swift; sourceTree = ""; }; - 522CD6281F8D4512008DB43D /* Action.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Action.swift; sourceTree = ""; }; - 522CD6291F8D4512008DB43D /* ActionPerformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionPerformer.swift; sourceTree = ""; }; - 522CD62A1F8D4512008DB43D /* ActionToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionToken.swift; sourceTree = ""; }; - 522CD62B1F8D4512008DB43D /* Actor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Actor.swift; sourceTree = ""; }; - 522CD62C1F8D4512008DB43D /* ActorEventCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActorEventCollection.swift; sourceTree = ""; }; - 522CD62D1F8D4512008DB43D /* Animation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Animation.swift; sourceTree = ""; }; - 522CD62E1F8D4512008DB43D /* AnimationAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationAction.swift; sourceTree = ""; }; - 522CD62F1F8D4512008DB43D /* Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Block.swift; sourceTree = ""; }; - 522CD6301F8D4512008DB43D /* BlockTextureCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockTextureCollection.swift; sourceTree = ""; }; - 522CD6311F8D4512008DB43D /* Camera.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Camera.swift; sourceTree = ""; }; - 522CD6321F8D4512008DB43D /* CancellationToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CancellationToken.swift; sourceTree = ""; }; - 522CD6331F8D4512008DB43D /* ClosureAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosureAction.swift; sourceTree = ""; }; - 522CD6341F8D4512008DB43D /* Constraint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constraint.swift; sourceTree = ""; }; - 522CD6351F8D4512008DB43D /* Event.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = ""; }; - 522CD6361F8D4512008DB43D /* EventCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventCollection.swift; sourceTree = ""; }; - 522CD6371F8D4512008DB43D /* EventToken.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventToken.swift; sourceTree = ""; }; - 522CD6381F8D4512008DB43D /* Fadeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Fadeable.swift; sourceTree = ""; }; - 522CD6391F8D4512008DB43D /* FadeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FadeAction.swift; sourceTree = ""; }; - 522CD63A1F8D4512008DB43D /* Game.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Game.swift; sourceTree = ""; }; - 522CD63B1F8D4512008DB43D /* Group.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Group.swift; sourceTree = ""; }; - 522CD63C1F8D4512008DB43D /* InstanceHashable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceHashable.swift; sourceTree = ""; }; - 522CD63D1F8D4512008DB43D /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = ""; }; - 522CD63E1F8D4512008DB43D /* MetricAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetricAction.swift; sourceTree = ""; }; - 522CD63F1F8D4512008DB43D /* Mirroring.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mirroring.swift; sourceTree = ""; }; - 522CD6401F8D4512008DB43D /* Movable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Movable.swift; sourceTree = ""; }; - 522CD6411F8D4512008DB43D /* MoveAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoveAction.swift; sourceTree = ""; }; - 522CD6421F8D4512008DB43D /* Plugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Plugin.swift; sourceTree = ""; }; - 522CD6431F8D4512008DB43D /* RepeatAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatAction.swift; sourceTree = ""; }; - 522CD6441F8D4512008DB43D /* RepeatMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RepeatMode.swift; sourceTree = ""; }; - 522CD6451F8D4512008DB43D /* Rotatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Rotatable.swift; sourceTree = ""; }; - 522CD6461F8D4512008DB43D /* RotateAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RotateAction.swift; sourceTree = ""; }; - 522CD6471F8D4512008DB43D /* Scalable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scalable.swift; sourceTree = ""; }; - 522CD6481F8D4512008DB43D /* ScaleAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScaleAction.swift; sourceTree = ""; }; - 522CD6491F8D4512008DB43D /* Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scene.swift; sourceTree = ""; }; - 522CD64A1F8D4512008DB43D /* SceneEventCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneEventCollection.swift; sourceTree = ""; }; - 522CD64B1F8D4512008DB43D /* Texture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Texture.swift; sourceTree = ""; }; - 522CD64C1F8D4512008DB43D /* Timeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Timeline.swift; sourceTree = ""; }; - 522CD64D1F8D4512008DB43D /* Typealiases.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Typealiases.swift; sourceTree = ""; }; - 522CD64F1F8D4512008DB43D /* ActionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionManager.swift; sourceTree = ""; }; - 522CD6501F8D4512008DB43D /* ActionWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionWrapper.swift; sourceTree = ""; }; - 522CD6511F8D4512008DB43D /* Activatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Activatable.swift; sourceTree = ""; }; - 522CD6521F8D4512008DB43D /* ClickPlugin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClickPlugin.swift; sourceTree = ""; }; - 522CD6531F8D4512008DB43D /* ClosureUpdatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClosureUpdatable.swift; sourceTree = ""; }; - 522CD6541F8D4512008DB43D /* DisplayLink-iOS+tvOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DisplayLink-iOS+tvOS.swift"; sourceTree = ""; }; - 522CD6571F8D4512008DB43D /* GameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameView.swift; sourceTree = ""; }; - 522CD6581F8D4512008DB43D /* Grid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Grid.swift; sourceTree = ""; }; - 522CD6591F8D4512008DB43D /* Layer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Layer.swift; sourceTree = ""; }; - 522CD65A1F8D4512008DB43D /* LoadedTexture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadedTexture.swift; sourceTree = ""; }; - 522CD65B1F8D4512008DB43D /* Optional+GetOrSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Optional+GetOrSet.swift"; sourceTree = ""; }; - 522CD65C1F8D4512008DB43D /* PluginManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginManager.swift; sourceTree = ""; }; - 522CD65D1F8D4512008DB43D /* PluginWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginWrapper.swift; sourceTree = ""; }; - 522CD65E1F8D4512008DB43D /* ReplicatorLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplicatorLayer.swift; sourceTree = ""; }; - 522CD65F1F8D4512008DB43D /* TextLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLayer.swift; sourceTree = ""; }; - 522CD6601F8D4512008DB43D /* TextureManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureManager.swift; sourceTree = ""; }; - 522CD6611F8D4512008DB43D /* Updatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Updatable.swift; sourceTree = ""; }; - 522CD6621F8D4512008DB43D /* UpdatableWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdatableWrapper.swift; sourceTree = ""; }; - 522CD6631F8D4512008DB43D /* UpdateOutcome.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateOutcome.swift; sourceTree = ""; }; - 522CD6641F8D4512008DB43D /* View+MakeLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+MakeLayer.swift"; sourceTree = ""; }; - 522CD6671F8D4512008DB43D /* GameViewController-iOS+tvOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GameViewController-iOS+tvOS.swift"; sourceTree = ""; }; - 522CD6681F8D4512008DB43D /* GameWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameWindow.swift; sourceTree = ""; }; - 523E5D0F1F9FEFBC0084792C /* SpriteSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpriteSheet.swift; sourceTree = ""; }; - 52479F7F1F8E58E200D22A87 /* TextureImageLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureImageLoader.swift; sourceTree = ""; }; - 52479F811F8E5A6F00D22A87 /* TextureImageLoaderMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureImageLoaderMock.swift; sourceTree = ""; }; - 52479F831F8E7B4E00D22A87 /* SceneTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneTests.swift; sourceTree = ""; }; - 52479F871F8E7CAF00D22A87 /* PluginMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginMock.swift; sourceTree = ""; }; - 52479F891F8E804F00D22A87 /* TimelineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTests.swift; sourceTree = ""; }; - 52479F8B1F8E818100D22A87 /* ActionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionTests.swift; sourceTree = ""; }; - 52479F8D1F8E823E00D22A87 /* ActionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionMock.swift; sourceTree = ""; }; - 524B329E205488D50069A4A1 /* SpriteSheetTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpriteSheetTests.swift; sourceTree = ""; }; - 5253C7DC1FA4D66500D304B5 /* Font+Default.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Font+Default.swift"; sourceTree = ""; }; - 525688B41F9CF08E00F87786 /* Screen-iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Screen-iOS.swift"; sourceTree = ""; }; - 525688BA1F9CF33100F87786 /* ImagineEngine-macOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ImagineEngine-macOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 5256F9762053D989003F3F88 /* Coordinate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Coordinate.swift; sourceTree = ""; }; - 5262A1BC1FA4CCF900DD5B3D /* ImagineEngine.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImagineEngine.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 5262A1C81FA4CD1900DD5B3D /* ImagineEngine-tvOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ImagineEngine-tvOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 527FC8051F8EB223006B1295 /* EventTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventTests.swift; sourceTree = ""; }; - 527FC8071F8EB83F006B1295 /* CameraTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraTests.swift; sourceTree = ""; }; - 527FC80B1F8EBAAB006B1295 /* LabelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelTests.swift; sourceTree = ""; }; - 528B21501FA382B300CE9967 /* UpdatableCollection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdatableCollection.swift; sourceTree = ""; }; - 52A124CC1FAB9F9700252047 /* GameViewMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameViewMock.swift; sourceTree = ""; }; - 52A124D01FABA07500252047 /* EdgeInsets-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "EdgeInsets-macOS.swift"; sourceTree = ""; }; - 52A124D21FABA8AB00252047 /* Pluggable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Pluggable.swift; sourceTree = ""; }; - 52B8065D1FB373BC0042FBA7 /* ZIndexed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZIndexed.swift; sourceTree = ""; }; - 52B806691FB3B6180042FBA7 /* BlockTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockTests.swift; sourceTree = ""; }; - 52C8602D1F8E36B600C6C7A7 /* ActorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActorTests.swift; sourceTree = ""; }; - 52C860321F8E381600C6C7A7 /* Assert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Assert.swift; sourceTree = ""; }; - 52C860331F8E381600C6C7A7 /* TimeTraveler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeTraveler.swift; sourceTree = ""; }; - 52C860341F8E382800C6C7A7 /* ImageMockFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageMockFactory.swift; sourceTree = ""; }; - 52C860371F8E3A4900C6C7A7 /* DisplayLinkProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayLinkProtocol.swift; sourceTree = ""; }; - 52C8603A1F8E535100C6C7A7 /* GameMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameMock.swift; sourceTree = ""; }; - 52C8603C1F8E537C00C6C7A7 /* DisplayLinkMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayLinkMock.swift; sourceTree = ""; }; - 52D6D97C1BEFF229002C0205 /* ImagineEngine.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImagineEngine.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 52D6D9861BEFF229002C0205 /* ImagineEngine-iOS Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "ImagineEngine-iOS Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; - 52E725911FCF68AB0099FCC7 /* Shadow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shadow.swift; sourceTree = ""; }; - AD2FAA261CD0B6D800659CF4 /* ImagineEngine.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ImagineEngine.plist; sourceTree = ""; }; - AD2FAA281CD0B6E100659CF4 /* ImagineEngineTests.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = ImagineEngineTests.plist; sourceTree = ""; }; - C800CE2C1FA77F74008EE08D /* BundleProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleProtocol.swift; sourceTree = ""; }; - C800CE2F1FA782EA008EE08D /* TextureFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureFormat.swift; sourceTree = ""; }; - C800CE321FA788A5008EE08D /* BundleTextureImageLoaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleTextureImageLoaderTests.swift; sourceTree = ""; }; - C800CE381FA78C74008EE08D /* BundleMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleMock.swift; sourceTree = ""; }; - C800CE3C1FA790A9008EE08D /* sample.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = sample.png; sourceTree = ""; }; - C800CE3D1FA790A9008EE08D /* sample.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = sample.jpg; sourceTree = ""; }; - C86A78BD1FA1B61A0099632B /* TextureManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureManagerTests.swift; sourceTree = ""; }; - C8D2FCE41FA493940077B560 /* BundleTextureImageLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleTextureImageLoader.swift; sourceTree = ""; }; - CDC7F0031FC419F300782197 /* TextureErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureErrorHandler.swift; sourceTree = ""; }; - CDC7F0071FC42D4800782197 /* TextureErrorHandlerMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextureErrorHandlerMock.swift; sourceTree = ""; }; - DD21B7361F92E75A0034A7CE /* ImagineEngine.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImagineEngine.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - DD21B7381F92E81C0034A7CE /* Image-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Image-macOS.swift"; sourceTree = ""; }; - DD21B73B1F92E8B90034A7CE /* Screen-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Screen-macOS.swift"; sourceTree = ""; }; - DD21B7421F92EB140034A7CE /* DisplayLink-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DisplayLink-macOS.swift"; sourceTree = ""; }; - DD21B7461F92EC610034A7CE /* GameViewController-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "GameViewController-macOS.swift"; sourceTree = ""; }; - DD21B7491F92ED5E0034A7CE /* GameWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GameWindowController.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 525688B71F9CF33100F87786 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 525688BF1F9CF33100F87786 /* ImagineEngine.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5262A1B81FA4CCF900DD5B3D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5262A1C51FA4CD1900DD5B3D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 5262A1CD1FA4CD1900DD5B3D /* ImagineEngine.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 52D6D9781BEFF229002C0205 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 52D6D9831BEFF229002C0205 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 52D6D9871BEFF229002C0205 /* ImagineEngine.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DD21B7301F92E75A0034A7CE /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 522CD6261F8D4512008DB43D /* Core */ = { - isa = PBXGroup; - children = ( - 522CD6271F8D4512008DB43D /* API */, - 522CD64E1F8D4512008DB43D /* Internal */, - ); - path = Core; - sourceTree = ""; - }; - 522CD6271F8D4512008DB43D /* API */ = { - isa = PBXGroup; - children = ( - 522CD6281F8D4512008DB43D /* Action.swift */, - 522CD6291F8D4512008DB43D /* ActionPerformer.swift */, - 522CD62A1F8D4512008DB43D /* ActionToken.swift */, - 522CD62B1F8D4512008DB43D /* Actor.swift */, - 522CD62C1F8D4512008DB43D /* ActorEventCollection.swift */, - 522CD62D1F8D4512008DB43D /* Animation.swift */, - 522CD62E1F8D4512008DB43D /* AnimationAction.swift */, - 522CD62F1F8D4512008DB43D /* Block.swift */, - 522CD6301F8D4512008DB43D /* BlockTextureCollection.swift */, - 522CD6311F8D4512008DB43D /* Camera.swift */, - 026CE1C31FC06B7E00A0998B /* CameraEventCollection.swift */, - 522CD6321F8D4512008DB43D /* CancellationToken.swift */, - 522CD6331F8D4512008DB43D /* ClosureAction.swift */, - 522CD6341F8D4512008DB43D /* Constraint.swift */, - 5256F9762053D989003F3F88 /* Coordinate.swift */, - 522CD6351F8D4512008DB43D /* Event.swift */, - 522CD6361F8D4512008DB43D /* EventCollection.swift */, - 522CD6371F8D4512008DB43D /* EventToken.swift */, - 522CD6381F8D4512008DB43D /* Fadeable.swift */, - 522CD6391F8D4512008DB43D /* FadeAction.swift */, - 522CD63A1F8D4512008DB43D /* Game.swift */, - 522CD63B1F8D4512008DB43D /* Group.swift */, - 522CD63C1F8D4512008DB43D /* InstanceHashable.swift */, - 522CD63D1F8D4512008DB43D /* Label.swift */, - 521054251FFD78B1002FCFB6 /* LabelEventCollection.swift */, - 522CD63E1F8D4512008DB43D /* MetricAction.swift */, - 522CD63F1F8D4512008DB43D /* Mirroring.swift */, - 522CD6401F8D4512008DB43D /* Movable.swift */, - 522CD6411F8D4512008DB43D /* MoveAction.swift */, - 5209C844208BE4A90033DB4A /* Node.swift */, - 52A124D21FABA8AB00252047 /* Pluggable.swift */, - 522CD6421F8D4512008DB43D /* Plugin.swift */, - 522CD6431F8D4512008DB43D /* RepeatAction.swift */, - 522CD6441F8D4512008DB43D /* RepeatMode.swift */, - 522CD6451F8D4512008DB43D /* Rotatable.swift */, - 522CD6461F8D4512008DB43D /* RotateAction.swift */, - 522CD6471F8D4512008DB43D /* Scalable.swift */, - 522CD6481F8D4512008DB43D /* ScaleAction.swift */, - 522CD6491F8D4512008DB43D /* Scene.swift */, - 522CD64A1F8D4512008DB43D /* SceneEventCollection.swift */, - 52E725911FCF68AB0099FCC7 /* Shadow.swift */, - 523E5D0F1F9FEFBC0084792C /* SpriteSheet.swift */, - 522CD64B1F8D4512008DB43D /* Texture.swift */, - C800CE2F1FA782EA008EE08D /* TextureFormat.swift */, - 52479F7F1F8E58E200D22A87 /* TextureImageLoader.swift */, - 522CD6601F8D4512008DB43D /* TextureManager.swift */, - 522CD64C1F8D4512008DB43D /* Timeline.swift */, - 522CD64D1F8D4512008DB43D /* Typealiases.swift */, - 52B8065D1FB373BC0042FBA7 /* ZIndexed.swift */, - ); - path = API; - sourceTree = ""; - }; - 522CD64E1F8D4512008DB43D /* Internal */ = { - isa = PBXGroup; - children = ( - 522CD64F1F8D4512008DB43D /* ActionManager.swift */, - 522CD6501F8D4512008DB43D /* ActionWrapper.swift */, - 522CD6511F8D4512008DB43D /* Activatable.swift */, - 5209C848208BE8EB0033DB4A /* AnyNode.swift */, - C800CE2C1FA77F74008EE08D /* BundleProtocol.swift */, - C8D2FCE41FA493940077B560 /* BundleTextureImageLoader.swift */, - 5209C84C208BEAC00033DB4A /* CALayer+Transform.swift */, - 5204849F1FA356F80011D372 /* ClickGestureRecognizer-macOS.swift */, - 522CD6521F8D4512008DB43D /* ClickPlugin.swift */, - 522CD6531F8D4512008DB43D /* ClosureUpdatable.swift */, - 522CD6541F8D4512008DB43D /* DisplayLink-iOS+tvOS.swift */, - DD21B7421F92EB140034A7CE /* DisplayLink-macOS.swift */, - 52C860371F8E3A4900C6C7A7 /* DisplayLinkProtocol.swift */, - 52A124D01FABA07500252047 /* EdgeInsets-macOS.swift */, - 5253C7DC1FA4D66500D304B5 /* Font+Default.swift */, - 522CD6571F8D4512008DB43D /* GameView.swift */, - 522CD6581F8D4512008DB43D /* Grid.swift */, - 5209C85F208CC1690033DB4A /* GridPlaceable.swift */, - DD21B7381F92E81C0034A7CE /* Image-macOS.swift */, - 522CD6591F8D4512008DB43D /* Layer.swift */, - 522CD65A1F8D4512008DB43D /* LoadedTexture.swift */, - 522CD65B1F8D4512008DB43D /* Optional+GetOrSet.swift */, - 522CD65C1F8D4512008DB43D /* PluginManager.swift */, - 522CD65D1F8D4512008DB43D /* PluginWrapper.swift */, - 522CD65E1F8D4512008DB43D /* ReplicatorLayer.swift */, - 525688B41F9CF08E00F87786 /* Screen-iOS.swift */, - DD21B73B1F92E8B90034A7CE /* Screen-macOS.swift */, - 522CD65F1F8D4512008DB43D /* TextLayer.swift */, - 522CD6611F8D4512008DB43D /* Updatable.swift */, - 528B21501FA382B300CE9967 /* UpdatableCollection.swift */, - 522CD6621F8D4512008DB43D /* UpdatableWrapper.swift */, - 522CD6631F8D4512008DB43D /* UpdateOutcome.swift */, - 522CD6641F8D4512008DB43D /* View+MakeLayer.swift */, - CDC7F0031FC419F300782197 /* TextureErrorHandler.swift */, - ); - path = Internal; - sourceTree = ""; - }; - 522CD6651F8D4512008DB43D /* Integrations */ = { - isa = PBXGroup; - children = ( - 522CD6661F8D4512008DB43D /* UIKit */, - DD21B7451F92EC450034A7CE /* AppKit */, - ); - path = Integrations; - sourceTree = ""; - }; - 522CD6661F8D4512008DB43D /* UIKit */ = { - isa = PBXGroup; - children = ( - 522CD6671F8D4512008DB43D /* GameViewController-iOS+tvOS.swift */, - 522CD6681F8D4512008DB43D /* GameWindow.swift */, - ); - path = UIKit; - sourceTree = ""; - }; - 52C860311F8E381600C6C7A7 /* Utilities */ = { - isa = PBXGroup; - children = ( - 52C860321F8E381600C6C7A7 /* Assert.swift */, - 52C860331F8E381600C6C7A7 /* TimeTraveler.swift */, - 52C860341F8E382800C6C7A7 /* ImageMockFactory.swift */, - 5209C850208BEFC80033DB4A /* XCTAssertEqual+CATransform3D.swift */, - ); - path = Utilities; - sourceTree = ""; - }; - 52C860391F8E534000C6C7A7 /* Mocks */ = { - isa = PBXGroup; - children = ( - 52479F8D1F8E823E00D22A87 /* ActionMock.swift */, - C800CE381FA78C74008EE08D /* BundleMock.swift */, - 5204849C1FA353590011D372 /* ClickGestureRecognizerMock.swift */, - 52C8603C1F8E537C00C6C7A7 /* DisplayLinkMock.swift */, - 52C8603A1F8E535100C6C7A7 /* GameMock.swift */, - 52A124CC1FAB9F9700252047 /* GameViewMock.swift */, - 52479F871F8E7CAF00D22A87 /* PluginMock.swift */, - 52479F811F8E5A6F00D22A87 /* TextureImageLoaderMock.swift */, - CDC7F0071FC42D4800782197 /* TextureErrorHandlerMock.swift */, - ); - path = Mocks; - sourceTree = ""; - }; - 52D6D9721BEFF229002C0205 = { - isa = PBXGroup; - children = ( - 8933C7811EB5B7E0000D00A4 /* Sources */, - 8933C7831EB5B7EB000D00A4 /* Tests */, - 52D6D99C1BEFF38C002C0205 /* Configs */, - 52D6D97D1BEFF229002C0205 /* Products */, - ); - sourceTree = ""; - }; - 52D6D97D1BEFF229002C0205 /* Products */ = { - isa = PBXGroup; - children = ( - 52D6D97C1BEFF229002C0205 /* ImagineEngine.framework */, - 52D6D9861BEFF229002C0205 /* ImagineEngine-iOS Tests.xctest */, - DD21B7361F92E75A0034A7CE /* ImagineEngine.framework */, - 525688BA1F9CF33100F87786 /* ImagineEngine-macOS Tests.xctest */, - 5262A1BC1FA4CCF900DD5B3D /* ImagineEngine.framework */, - 5262A1C81FA4CD1900DD5B3D /* ImagineEngine-tvOS Tests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 52D6D99C1BEFF38C002C0205 /* Configs */ = { - isa = PBXGroup; - children = ( - AD2FAA261CD0B6D800659CF4 /* ImagineEngine.plist */, - AD2FAA281CD0B6E100659CF4 /* ImagineEngineTests.plist */, - ); - path = Configs; - sourceTree = ""; - }; - 8933C7811EB5B7E0000D00A4 /* Sources */ = { - isa = PBXGroup; - children = ( - 522CD6261F8D4512008DB43D /* Core */, - 522CD6651F8D4512008DB43D /* Integrations */, - ); - path = Sources; - sourceTree = ""; - }; - 8933C7831EB5B7EB000D00A4 /* Tests */ = { - isa = PBXGroup; - children = ( - 52C8602D1F8E36B600C6C7A7 /* ActorTests.swift */, - 52479F8B1F8E818100D22A87 /* ActionTests.swift */, - 52B806691FB3B6180042FBA7 /* BlockTests.swift */, - C800CE321FA788A5008EE08D /* BundleTextureImageLoaderTests.swift */, - 527FC8071F8EB83F006B1295 /* CameraTests.swift */, - 527FC8051F8EB223006B1295 /* EventTests.swift */, - 527FC80B1F8EBAAB006B1295 /* LabelTests.swift */, - 52479F831F8E7B4E00D22A87 /* SceneTests.swift */, - 524B329E205488D50069A4A1 /* SpriteSheetTests.swift */, - C86A78BD1FA1B61A0099632B /* TextureManagerTests.swift */, - 52479F891F8E804F00D22A87 /* TimelineTests.swift */, - 52C860391F8E534000C6C7A7 /* Mocks */, - C800CE3B1FA79008008EE08D /* Resources */, - 52C860311F8E381600C6C7A7 /* Utilities */, - ); - name = Tests; - path = Tests/ImagineEngineTests; - sourceTree = ""; - }; - C800CE3B1FA79008008EE08D /* Resources */ = { - isa = PBXGroup; - children = ( - C800CE3D1FA790A9008EE08D /* sample.jpg */, - C800CE3C1FA790A9008EE08D /* sample.png */, - ); - path = Resources; - sourceTree = ""; - }; - DD21B7451F92EC450034A7CE /* AppKit */ = { - isa = PBXGroup; - children = ( - DD21B7461F92EC610034A7CE /* GameViewController-macOS.swift */, - DD21B7491F92ED5E0034A7CE /* GameWindowController.swift */, - ); - path = AppKit; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - 5262A1B91FA4CCF900DD5B3D /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 52D6D9791BEFF229002C0205 /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DD21B7311F92E75A0034A7CE /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - 525688B91F9CF33100F87786 /* ImagineEngine-macOS Tests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 525688C21F9CF33100F87786 /* Build configuration list for PBXNativeTarget "ImagineEngine-macOS Tests" */; - buildPhases = ( - 525688B61F9CF33100F87786 /* Sources */, - 525688B71F9CF33100F87786 /* Frameworks */, - 525688B81F9CF33100F87786 /* Resources */, - C854A9AE1FAE9D5600638A78 /* Run SwiftLint */, - ); - buildRules = ( - ); - dependencies = ( - 525688C11F9CF33100F87786 /* PBXTargetDependency */, - ); - name = "ImagineEngine-macOS Tests"; - productName = "ImagineEngine-macOS Tests"; - productReference = 525688BA1F9CF33100F87786 /* ImagineEngine-macOS Tests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 5262A1BB1FA4CCF900DD5B3D /* ImagineEngine-tvOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5262A1C31FA4CCF900DD5B3D /* Build configuration list for PBXNativeTarget "ImagineEngine-tvOS" */; - buildPhases = ( - 5262A1B71FA4CCF900DD5B3D /* Sources */, - 5262A1B81FA4CCF900DD5B3D /* Frameworks */, - 5262A1B91FA4CCF900DD5B3D /* Headers */, - 5262A1BA1FA4CCF900DD5B3D /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "ImagineEngine-tvOS"; - productName = "ImagineEngine-tvOS"; - productReference = 5262A1BC1FA4CCF900DD5B3D /* ImagineEngine.framework */; - productType = "com.apple.product-type.framework"; - }; - 5262A1C71FA4CD1900DD5B3D /* ImagineEngine-tvOS Tests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 5262A1D01FA4CD1900DD5B3D /* Build configuration list for PBXNativeTarget "ImagineEngine-tvOS Tests" */; - buildPhases = ( - 5262A1C41FA4CD1900DD5B3D /* Sources */, - 5262A1C51FA4CD1900DD5B3D /* Frameworks */, - 5262A1C61FA4CD1900DD5B3D /* Resources */, - C854A9AF1FAE9D6A00638A78 /* Run SwiftLint */, - ); - buildRules = ( - ); - dependencies = ( - 5262A1CF1FA4CD1900DD5B3D /* PBXTargetDependency */, - ); - name = "ImagineEngine-tvOS Tests"; - productName = "ImagineEngine-tvOS Tests"; - productReference = 5262A1C81FA4CD1900DD5B3D /* ImagineEngine-tvOS Tests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - 52D6D97B1BEFF229002C0205 /* ImagineEngine-iOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "ImagineEngine-iOS" */; - buildPhases = ( - 52D6D9771BEFF229002C0205 /* Sources */, - 52D6D9781BEFF229002C0205 /* Frameworks */, - 52D6D9791BEFF229002C0205 /* Headers */, - 52D6D97A1BEFF229002C0205 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "ImagineEngine-iOS"; - productName = ImagineEngine; - productReference = 52D6D97C1BEFF229002C0205 /* ImagineEngine.framework */; - productType = "com.apple.product-type.framework"; - }; - 52D6D9851BEFF229002C0205 /* ImagineEngine-iOS Tests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 52D6D9931BEFF229002C0205 /* Build configuration list for PBXNativeTarget "ImagineEngine-iOS Tests" */; - buildPhases = ( - 52D6D9821BEFF229002C0205 /* Sources */, - 52D6D9831BEFF229002C0205 /* Frameworks */, - 52D6D9841BEFF229002C0205 /* Resources */, - C854A9AD1FAE9D4300638A78 /* Run SwiftLint */, - ); - buildRules = ( - ); - dependencies = ( - 52D6D9891BEFF229002C0205 /* PBXTargetDependency */, - ); - name = "ImagineEngine-iOS Tests"; - productName = ImagineEngineTests; - productReference = 52D6D9861BEFF229002C0205 /* ImagineEngine-iOS Tests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; - DD21B6F01F92E75A0034A7CE /* ImagineEngine-macOS */ = { - isa = PBXNativeTarget; - buildConfigurationList = DD21B7331F92E75A0034A7CE /* Build configuration list for PBXNativeTarget "ImagineEngine-macOS" */; - buildPhases = ( - DD21B6F11F92E75A0034A7CE /* Sources */, - DD21B7301F92E75A0034A7CE /* Frameworks */, - DD21B7311F92E75A0034A7CE /* Headers */, - DD21B7321F92E75A0034A7CE /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = "ImagineEngine-macOS"; - productName = ImagineEngine; - productReference = DD21B7361F92E75A0034A7CE /* ImagineEngine.framework */; - productType = "com.apple.product-type.framework"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 52D6D9731BEFF229002C0205 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 0900; - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = ImagineEngine; - TargetAttributes = { - 525688B91F9CF33100F87786 = { - CreatedOnToolsVersion = 9.0; - DevelopmentTeam = TEE39J9D8F; - LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; - }; - 5262A1BB1FA4CCF900DD5B3D = { - CreatedOnToolsVersion = 9.0; - LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; - }; - 5262A1C71FA4CD1900DD5B3D = { - CreatedOnToolsVersion = 9.0; - DevelopmentTeam = TEE39J9D8F; - LastSwiftMigration = 1020; - ProvisioningStyle = Automatic; - }; - 52D6D97B1BEFF229002C0205 = { - CreatedOnToolsVersion = 7.1; - LastSwiftMigration = 1000; - }; - 52D6D9851BEFF229002C0205 = { - CreatedOnToolsVersion = 7.1; - LastSwiftMigration = 1020; - }; - DD21B6F01F92E75A0034A7CE = { - LastSwiftMigration = 1020; - }; - }; - }; - buildConfigurationList = 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "ImagineEngine" */; - compatibilityVersion = "Xcode 6.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 52D6D9721BEFF229002C0205; - productRefGroup = 52D6D97D1BEFF229002C0205 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 52D6D97B1BEFF229002C0205 /* ImagineEngine-iOS */, - 52D6D9851BEFF229002C0205 /* ImagineEngine-iOS Tests */, - DD21B6F01F92E75A0034A7CE /* ImagineEngine-macOS */, - 525688B91F9CF33100F87786 /* ImagineEngine-macOS Tests */, - 5262A1BB1FA4CCF900DD5B3D /* ImagineEngine-tvOS */, - 5262A1C71FA4CD1900DD5B3D /* ImagineEngine-tvOS Tests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 525688B81F9CF33100F87786 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C800CE3F1FA790AA008EE08D /* sample.png in Resources */, - C800CE411FA790AA008EE08D /* sample.jpg in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5262A1BA1FA4CCF900DD5B3D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5262A1C61FA4CD1900DD5B3D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C80942761FA7997B002B42A6 /* sample.jpg in Resources */, - C80942771FA7997B002B42A6 /* sample.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 52D6D97A1BEFF229002C0205 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 52D6D9841BEFF229002C0205 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - C809426E1FA798B7002B42A6 /* sample.jpg in Resources */, - C809426F1FA798B7002B42A6 /* sample.png in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DD21B7321F92E75A0034A7CE /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - C854A9AD1FAE9D4300638A78 /* Run SwiftLint */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run SwiftLint"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; - }; - C854A9AE1FAE9D5600638A78 /* Run SwiftLint */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run SwiftLint"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; - }; - C854A9AF1FAE9D6A00638A78 /* Run SwiftLint */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run SwiftLint"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 525688B61F9CF33100F87786 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5209C855208BEFF00033DB4A /* XCTAssertEqual+CATransform3D.swift in Sources */, - 525688D01F9CF3E200F87786 /* TextureImageLoaderMock.swift in Sources */, - 525688C81F9CF3E200F87786 /* EventTests.swift in Sources */, - 525688CE1F9CF3E200F87786 /* GameMock.swift in Sources */, - CDC7F00C1FC42E6600782197 /* TextureErrorHandlerMock.swift in Sources */, - C86A78BF1FA1B61A0099632B /* TextureManagerTests.swift in Sources */, - 525688C91F9CF3E200F87786 /* LabelTests.swift in Sources */, - 525688CA1F9CF3E200F87786 /* SceneTests.swift in Sources */, - 525688CC1F9CF3E200F87786 /* ActionMock.swift in Sources */, - 525688D31F9CF3E200F87786 /* ImageMockFactory.swift in Sources */, - 52A124CE1FAB9F9700252047 /* GameViewMock.swift in Sources */, - 525688D11F9CF3E200F87786 /* Assert.swift in Sources */, - 524B32A0205488D50069A4A1 /* SpriteSheetTests.swift in Sources */, - 52B8066B1FB3B6180042FBA7 /* BlockTests.swift in Sources */, - 525688C71F9CF3E200F87786 /* CameraTests.swift in Sources */, - 525688C51F9CF3E200F87786 /* ActorTests.swift in Sources */, - C800CE3A1FA78C74008EE08D /* BundleMock.swift in Sources */, - 525688D21F9CF3E200F87786 /* TimeTraveler.swift in Sources */, - 525688C61F9CF3E200F87786 /* ActionTests.swift in Sources */, - 525688CD1F9CF3E200F87786 /* DisplayLinkMock.swift in Sources */, - 525688CF1F9CF3E200F87786 /* PluginMock.swift in Sources */, - 525688CB1F9CF3E200F87786 /* TimelineTests.swift in Sources */, - C800CE341FA788A5008EE08D /* BundleTextureImageLoaderTests.swift in Sources */, - 5204849E1FA353590011D372 /* ClickGestureRecognizerMock.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5262A1B71FA4CCF900DD5B3D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5253C7D51FA4D57200D304B5 /* SceneEventCollection.swift in Sources */, - 5253C7D21FA4D57200D304B5 /* Scalable.swift in Sources */, - 5253C7B21FA4D56C00D304B5 /* View+MakeLayer.swift in Sources */, - 5253C7AD1FA4D56C00D304B5 /* TextLayer.swift in Sources */, - 5253C7C31FA4D57200D304B5 /* Fadeable.swift in Sources */, - 5253C7BC1FA4D57200D304B5 /* Camera.swift in Sources */, - 5253C7D01FA4D57200D304B5 /* Rotatable.swift in Sources */, - 5253C79B1FA4D54000D304B5 /* GameViewController-iOS+tvOS.swift in Sources */, - C80942701FA79925002B42A6 /* TextureFormat.swift in Sources */, - 52A124D51FABA8AB00252047 /* Pluggable.swift in Sources */, - 5253C7B61FA4D57200D304B5 /* Actor.swift in Sources */, - 52E725941FCF68AB0099FCC7 /* Shadow.swift in Sources */, - 5253C7A01FA4D56C00D304B5 /* ClickPlugin.swift in Sources */, - 5253C7C01FA4D57200D304B5 /* Event.swift in Sources */, - 5253C7A21FA4D56C00D304B5 /* DisplayLinkProtocol.swift in Sources */, - 026CE1C61FC06B7E00A0998B /* CameraEventCollection.swift in Sources */, - 5253C7B01FA4D56C00D304B5 /* UpdatableWrapper.swift in Sources */, - 5253C7A71FA4D56C00D304B5 /* LoadedTexture.swift in Sources */, - 52B806601FB373BC0042FBA7 /* ZIndexed.swift in Sources */, - 5253C7C61FA4D57200D304B5 /* Group.swift in Sources */, - C80942711FA79934002B42A6 /* BundleProtocol.swift in Sources */, - 5253C7A81FA4D56C00D304B5 /* Optional+GetOrSet.swift in Sources */, - 5253C7D91FA4D57200D304B5 /* TextureManager.swift in Sources */, - 5253C7A61FA4D56C00D304B5 /* Layer.swift in Sources */, - 5253C7DD1FA4D66500D304B5 /* Font+Default.swift in Sources */, - 5253C7D71FA4D57200D304B5 /* Texture.swift in Sources */, - 521054281FFD78B1002FCFB6 /* LabelEventCollection.swift in Sources */, - 5209C84F208BEAC00033DB4A /* CALayer+Transform.swift in Sources */, - 5253C7CB1FA4D57200D304B5 /* Movable.swift in Sources */, - 5253C7CD1FA4D57200D304B5 /* Plugin.swift in Sources */, - 5253C7A31FA4D56C00D304B5 /* DisplayLink-iOS+tvOS.swift in Sources */, - 5253C7D61FA4D57200D304B5 /* SpriteSheet.swift in Sources */, - 5253C7BB1FA4D57200D304B5 /* BlockTextureCollection.swift in Sources */, - 5253C7D41FA4D57200D304B5 /* Scene.swift in Sources */, - 5253C7BD1FA4D57200D304B5 /* CancellationToken.swift in Sources */, - 5253C7A51FA4D56C00D304B5 /* Grid.swift in Sources */, - 5253C7B71FA4D57200D304B5 /* ActorEventCollection.swift in Sources */, - 5253C7CA1FA4D57200D304B5 /* Mirroring.swift in Sources */, - 5253C7B91FA4D57200D304B5 /* AnimationAction.swift in Sources */, - 5253C7D11FA4D57200D304B5 /* RotateAction.swift in Sources */, - 5253C7A91FA4D56C00D304B5 /* PluginManager.swift in Sources */, - CDC7F0061FC419F300782197 /* TextureErrorHandler.swift in Sources */, - 5253C7DA1FA4D57200D304B5 /* Timeline.swift in Sources */, - 5253C7A41FA4D56C00D304B5 /* GameView.swift in Sources */, - 5253C7CC1FA4D57200D304B5 /* MoveAction.swift in Sources */, - 5209C862208CC1690033DB4A /* GridPlaceable.swift in Sources */, - 5253C7B11FA4D56C00D304B5 /* UpdateOutcome.swift in Sources */, - 5253C7BA1FA4D57200D304B5 /* Block.swift in Sources */, - 5253C7C21FA4D57200D304B5 /* EventToken.swift in Sources */, - 5253C7B41FA4D57200D304B5 /* ActionPerformer.swift in Sources */, - 5256F9792053D989003F3F88 /* Coordinate.swift in Sources */, - 5253C7C91FA4D57200D304B5 /* MetricAction.swift in Sources */, - 5253C7B51FA4D57200D304B5 /* ActionToken.swift in Sources */, - 5253C79E1FA4D56C00D304B5 /* ActionWrapper.swift in Sources */, - 5253C7AE1FA4D56C00D304B5 /* Updatable.swift in Sources */, - 5253C7BE1FA4D57200D304B5 /* ClosureAction.swift in Sources */, - 5253C7C41FA4D57200D304B5 /* FadeAction.swift in Sources */, - 5253C7BF1FA4D57200D304B5 /* Constraint.swift in Sources */, - 5209C847208BE4A90033DB4A /* Node.swift in Sources */, - 5253C7CF1FA4D57200D304B5 /* RepeatMode.swift in Sources */, - 5253C7DB1FA4D57200D304B5 /* Typealiases.swift in Sources */, - 5253C79C1FA4D54000D304B5 /* GameWindow.swift in Sources */, - 5253C7AB1FA4D56C00D304B5 /* ReplicatorLayer.swift in Sources */, - 5253C7D31FA4D57200D304B5 /* ScaleAction.swift in Sources */, - 5253C7C81FA4D57200D304B5 /* Label.swift in Sources */, - 5253C7C71FA4D57200D304B5 /* InstanceHashable.swift in Sources */, - 5253C7B31FA4D57200D304B5 /* Action.swift in Sources */, - 5253C7AC1FA4D56C00D304B5 /* Screen-iOS.swift in Sources */, - 5209C84B208BE8EB0033DB4A /* AnyNode.swift in Sources */, - 5253C79D1FA4D56C00D304B5 /* ActionManager.swift in Sources */, - 5253C7A11FA4D56C00D304B5 /* ClosureUpdatable.swift in Sources */, - 5253C7AA1FA4D56C00D304B5 /* PluginWrapper.swift in Sources */, - 5253C79F1FA4D56C00D304B5 /* Activatable.swift in Sources */, - 5253C80F1FA4E04A00D304B5 /* BundleTextureImageLoader.swift in Sources */, - 5253C7D81FA4D57200D304B5 /* TextureImageLoader.swift in Sources */, - 5253C7B81FA4D57200D304B5 /* Animation.swift in Sources */, - 5253C7CE1FA4D57200D304B5 /* RepeatAction.swift in Sources */, - 5253C7C51FA4D57200D304B5 /* Game.swift in Sources */, - 5253C7C11FA4D57200D304B5 /* EventCollection.swift in Sources */, - 5253C7AF1FA4D56C00D304B5 /* UpdatableCollection.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 5262A1C41FA4CD1900DD5B3D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5209C856208BEFF10033DB4A /* XCTAssertEqual+CATransform3D.swift in Sources */, - 5253C7ED1FA4D97D00D304B5 /* TextureImageLoaderMock.swift in Sources */, - 5253C7EF1FA4D97D00D304B5 /* TimeTraveler.swift in Sources */, - 5253C7E81FA4D97D00D304B5 /* ActionMock.swift in Sources */, - CDC7F00D1FC42E6700782197 /* TextureErrorHandlerMock.swift in Sources */, - 5253C7E71FA4D97D00D304B5 /* TimelineTests.swift in Sources */, - 5253C7EA1FA4D97D00D304B5 /* DisplayLinkMock.swift in Sources */, - 5253C7F01FA4D97D00D304B5 /* ImageMockFactory.swift in Sources */, - 5253C7E31FA4D97D00D304B5 /* EventTests.swift in Sources */, - 5253C7E41FA4D97D00D304B5 /* LabelTests.swift in Sources */, - 52A124CF1FAB9F9700252047 /* GameViewMock.swift in Sources */, - 5253C7E91FA4D97D00D304B5 /* ClickGestureRecognizerMock.swift in Sources */, - 524B32A1205488D50069A4A1 /* SpriteSheetTests.swift in Sources */, - 52B8066C1FB3B6180042FBA7 /* BlockTests.swift in Sources */, - 5253C7E51FA4D97D00D304B5 /* SceneTests.swift in Sources */, - 5253C7EE1FA4D97D00D304B5 /* Assert.swift in Sources */, - 5253C7EC1FA4D97D00D304B5 /* PluginMock.swift in Sources */, - 5253C7E61FA4D97D00D304B5 /* TextureManagerTests.swift in Sources */, - 5253C7E21FA4D97D00D304B5 /* CameraTests.swift in Sources */, - 5253C7EB1FA4D97D00D304B5 /* GameMock.swift in Sources */, - C80942751FA7995B002B42A6 /* BundleMock.swift in Sources */, - 5253C7E01FA4D97D00D304B5 /* ActorTests.swift in Sources */, - C80942731FA7994C002B42A6 /* BundleTextureImageLoaderTests.swift in Sources */, - 5253C7E11FA4D97D00D304B5 /* ActionTests.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 52D6D9771BEFF229002C0205 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 522CD6A41F8D4521008DB43D /* View+MakeLayer.swift in Sources */, - 522CD69D1F8D4521008DB43D /* PluginWrapper.swift in Sources */, - 522CD6881F8D451D008DB43D /* Scalable.swift in Sources */, - 523E5D101F9FEFBC0084792C /* SpriteSheet.swift in Sources */, - 522CD6831F8D451D008DB43D /* Plugin.swift in Sources */, - 522CD66D1F8D451D008DB43D /* ActorEventCollection.swift in Sources */, - 522CD6811F8D451D008DB43D /* Movable.swift in Sources */, - 522CD69B1F8D4521008DB43D /* Optional+GetOrSet.swift in Sources */, - C800CE301FA782EA008EE08D /* TextureFormat.swift in Sources */, - 52A124D31FABA8AB00252047 /* Pluggable.swift in Sources */, - 522CD6741F8D451D008DB43D /* ClosureAction.swift in Sources */, - 52E725921FCF68AB0099FCC7 /* Shadow.swift in Sources */, - 522CD6841F8D451D008DB43D /* RepeatAction.swift in Sources */, - 522CD6931F8D4521008DB43D /* ClosureUpdatable.swift in Sources */, - 522CD69A1F8D4521008DB43D /* LoadedTexture.swift in Sources */, - 026CE1C41FC06B7E00A0998B /* CameraEventCollection.swift in Sources */, - 522CD6701F8D451D008DB43D /* Block.swift in Sources */, - 522CD6A11F8D4521008DB43D /* Updatable.swift in Sources */, - 52B8065E1FB373BC0042FBA7 /* ZIndexed.swift in Sources */, - 522CD6941F8D4521008DB43D /* DisplayLink-iOS+tvOS.swift in Sources */, - 522CD6991F8D4521008DB43D /* Layer.swift in Sources */, - 522CD6981F8D4521008DB43D /* Grid.swift in Sources */, - 522CD6921F8D4521008DB43D /* ClickPlugin.swift in Sources */, - 528B21511FA382B300CE9967 /* UpdatableCollection.swift in Sources */, - 522CD6971F8D4521008DB43D /* GameView.swift in Sources */, - 522CD6911F8D4521008DB43D /* Activatable.swift in Sources */, - 521054261FFD78B1002FCFB6 /* LabelEventCollection.swift in Sources */, - 5209C84D208BEAC00033DB4A /* CALayer+Transform.swift in Sources */, - 522CD67C1F8D451D008DB43D /* Group.swift in Sources */, - 522CD67E1F8D451D008DB43D /* Label.swift in Sources */, - 522CD6A21F8D4521008DB43D /* UpdatableWrapper.swift in Sources */, - 525688B51F9CF08E00F87786 /* Screen-iOS.swift in Sources */, - 522CD6731F8D451D008DB43D /* CancellationToken.swift in Sources */, - 522CD68A1F8D451D008DB43D /* Scene.swift in Sources */, - 52479F801F8E58E200D22A87 /* TextureImageLoader.swift in Sources */, - C8D2FCE51FA493940077B560 /* BundleTextureImageLoader.swift in Sources */, - 522CD68F1F8D4521008DB43D /* ActionManager.swift in Sources */, - 522CD68B1F8D451D008DB43D /* SceneEventCollection.swift in Sources */, - 522CD6901F8D4521008DB43D /* ActionWrapper.swift in Sources */, - 522CD6771F8D451D008DB43D /* EventCollection.swift in Sources */, - 522CD6711F8D451D008DB43D /* BlockTextureCollection.swift in Sources */, - CDC7F0041FC419F300782197 /* TextureErrorHandler.swift in Sources */, - 522CD66F1F8D451D008DB43D /* AnimationAction.swift in Sources */, - 522CD6891F8D451D008DB43D /* ScaleAction.swift in Sources */, - 522CD66B1F8D451D008DB43D /* ActionToken.swift in Sources */, - 5209C860208CC1690033DB4A /* GridPlaceable.swift in Sources */, - 522CD69F1F8D4521008DB43D /* TextLayer.swift in Sources */, - 522CD6A61F8D4526008DB43D /* GameWindow.swift in Sources */, - 522CD6791F8D451D008DB43D /* Fadeable.swift in Sources */, - 522CD6871F8D451D008DB43D /* RotateAction.swift in Sources */, - 5256F9772053D989003F3F88 /* Coordinate.swift in Sources */, - 522CD6A51F8D4526008DB43D /* GameViewController-iOS+tvOS.swift in Sources */, - 522CD69C1F8D4521008DB43D /* PluginManager.swift in Sources */, - 522CD67D1F8D451D008DB43D /* InstanceHashable.swift in Sources */, - 522CD66A1F8D451D008DB43D /* ActionPerformer.swift in Sources */, - 522CD6861F8D451D008DB43D /* Rotatable.swift in Sources */, - 522CD6721F8D451D008DB43D /* Camera.swift in Sources */, - 5253C7DF1FA4D7E500D304B5 /* Font+Default.swift in Sources */, - 5209C845208BE4A90033DB4A /* Node.swift in Sources */, - 522CD67A1F8D451D008DB43D /* FadeAction.swift in Sources */, - 522CD6691F8D451D008DB43D /* Action.swift in Sources */, - 522CD68C1F8D451D008DB43D /* Texture.swift in Sources */, - 522CD6A31F8D4521008DB43D /* UpdateOutcome.swift in Sources */, - 522CD67F1F8D451D008DB43D /* MetricAction.swift in Sources */, - 522CD66E1F8D451D008DB43D /* Animation.swift in Sources */, - 522CD67B1F8D451D008DB43D /* Game.swift in Sources */, - 522CD6801F8D451D008DB43D /* Mirroring.swift in Sources */, - 522CD66C1F8D451D008DB43D /* Actor.swift in Sources */, - 5209C849208BE8EB0033DB4A /* AnyNode.swift in Sources */, - 522CD68D1F8D451D008DB43D /* Timeline.swift in Sources */, - 522CD6761F8D451D008DB43D /* Event.swift in Sources */, - 522CD6781F8D451D008DB43D /* EventToken.swift in Sources */, - 522CD6821F8D451D008DB43D /* MoveAction.swift in Sources */, - 522CD6A01F8D4521008DB43D /* TextureManager.swift in Sources */, - 522CD6751F8D451D008DB43D /* Constraint.swift in Sources */, - 522CD68E1F8D451D008DB43D /* Typealiases.swift in Sources */, - 52C860381F8E3A4900C6C7A7 /* DisplayLinkProtocol.swift in Sources */, - 522CD69E1F8D4521008DB43D /* ReplicatorLayer.swift in Sources */, - C800CE2D1FA77F74008EE08D /* BundleProtocol.swift in Sources */, - 522CD6851F8D451D008DB43D /* RepeatMode.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 52D6D9821BEFF229002C0205 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 5209C854208BEFF00033DB4A /* XCTAssertEqual+CATransform3D.swift in Sources */, - 527FC8081F8EB83F006B1295 /* CameraTests.swift in Sources */, - 52C8603B1F8E535100C6C7A7 /* GameMock.swift in Sources */, - 52479F861F8E7BFD00D22A87 /* TimeTraveler.swift in Sources */, - CDC7F00B1FC42E6500782197 /* TextureErrorHandlerMock.swift in Sources */, - C86A78BE1FA1B61A0099632B /* TextureManagerTests.swift in Sources */, - 52479F8A1F8E804F00D22A87 /* TimelineTests.swift in Sources */, - 527FC8061F8EB223006B1295 /* EventTests.swift in Sources */, - 52479F8E1F8E823E00D22A87 /* ActionMock.swift in Sources */, - 52479F881F8E7CAF00D22A87 /* PluginMock.swift in Sources */, - 52A124CD1FAB9F9700252047 /* GameViewMock.swift in Sources */, - 52C860361F8E383100C6C7A7 /* ImageMockFactory.swift in Sources */, - 524B329F205488D50069A4A1 /* SpriteSheetTests.swift in Sources */, - 52B8066A1FB3B6180042FBA7 /* BlockTests.swift in Sources */, - 52479F841F8E7B4E00D22A87 /* SceneTests.swift in Sources */, - 52C8603D1F8E537C00C6C7A7 /* DisplayLinkMock.swift in Sources */, - C800CE391FA78C74008EE08D /* BundleMock.swift in Sources */, - 52C860301F8E374100C6C7A7 /* ActorTests.swift in Sources */, - 527FC80C1F8EBAAB006B1295 /* LabelTests.swift in Sources */, - 52479F851F8E7BFA00D22A87 /* Assert.swift in Sources */, - 52479F8C1F8E818100D22A87 /* ActionTests.swift in Sources */, - 52479F821F8E5A6F00D22A87 /* TextureImageLoaderMock.swift in Sources */, - C800CE331FA788A5008EE08D /* BundleTextureImageLoaderTests.swift in Sources */, - 5204849D1FA353590011D372 /* ClickGestureRecognizerMock.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - DD21B6F11F92E75A0034A7CE /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - DD21B6F21F92E75A0034A7CE /* View+MakeLayer.swift in Sources */, - DD21B6F31F92E75A0034A7CE /* PluginWrapper.swift in Sources */, - DD21B6F41F92E75A0034A7CE /* Scalable.swift in Sources */, - DD21B6F51F92E75A0034A7CE /* Plugin.swift in Sources */, - 520484A21FA357070011D372 /* ClickGestureRecognizer-macOS.swift in Sources */, - CDC7F0051FC419F300782197 /* TextureErrorHandler.swift in Sources */, - DD21B6F61F92E75A0034A7CE /* ActorEventCollection.swift in Sources */, - DD21B6F71F92E75A0034A7CE /* Movable.swift in Sources */, - DD21B7411F92EA610034A7CE /* ClickPlugin.swift in Sources */, - DD21B6F81F92E75A0034A7CE /* Optional+GetOrSet.swift in Sources */, - DD21B6F91F92E75A0034A7CE /* ClosureAction.swift in Sources */, - DD21B6FA1F92E75A0034A7CE /* RepeatAction.swift in Sources */, - C8D2FCE61FA493940077B560 /* BundleTextureImageLoader.swift in Sources */, - DD21B6FB1F92E75A0034A7CE /* ClosureUpdatable.swift in Sources */, - DD21B74B1F92ED6B0034A7CE /* GameWindowController.swift in Sources */, - DD21B6FC1F92E75A0034A7CE /* LoadedTexture.swift in Sources */, - DD21B6FD1F92E75A0034A7CE /* Block.swift in Sources */, - C800CE2E1FA77F74008EE08D /* BundleProtocol.swift in Sources */, - DD21B6FE1F92E75A0034A7CE /* Updatable.swift in Sources */, - 5256F9782053D989003F3F88 /* Coordinate.swift in Sources */, - DD21B7001F92E75A0034A7CE /* Layer.swift in Sources */, - DD21B7011F92E75A0034A7CE /* Grid.swift in Sources */, - 52E725931FCF68AB0099FCC7 /* Shadow.swift in Sources */, - DD21B7031F92E75A0034A7CE /* GameView.swift in Sources */, - DD21B7041F92E75A0034A7CE /* Activatable.swift in Sources */, - C800CE311FA782EA008EE08D /* TextureFormat.swift in Sources */, - DD21B73A1F92E8240034A7CE /* Image-macOS.swift in Sources */, - DD21B7051F92E75A0034A7CE /* Group.swift in Sources */, - 5209C84E208BEAC00033DB4A /* CALayer+Transform.swift in Sources */, - 026CE1C51FC06B7E00A0998B /* CameraEventCollection.swift in Sources */, - DD21B7441F92EB1A0034A7CE /* DisplayLink-macOS.swift in Sources */, - DD21B73D1F92E8CB0034A7CE /* Screen-macOS.swift in Sources */, - 5253C7DE1FA4D7E400D304B5 /* Font+Default.swift in Sources */, - DD21B7061F92E75A0034A7CE /* Label.swift in Sources */, - 52A124D41FABA8AB00252047 /* Pluggable.swift in Sources */, - DD21B7071F92E75A0034A7CE /* UpdatableWrapper.swift in Sources */, - DD21B7081F92E75A0034A7CE /* CancellationToken.swift in Sources */, - DD21B7091F92E75A0034A7CE /* Scene.swift in Sources */, - DD21B70A1F92E75A0034A7CE /* TextureImageLoader.swift in Sources */, - DD21B70B1F92E75A0034A7CE /* ActionManager.swift in Sources */, - DD21B70C1F92E75A0034A7CE /* SceneEventCollection.swift in Sources */, - DD21B70D1F92E75A0034A7CE /* ActionWrapper.swift in Sources */, - DD21B70E1F92E75A0034A7CE /* EventCollection.swift in Sources */, - DD21B70F1F92E75A0034A7CE /* BlockTextureCollection.swift in Sources */, - DD21B7101F92E75A0034A7CE /* AnimationAction.swift in Sources */, - DD21B7111F92E75A0034A7CE /* ScaleAction.swift in Sources */, - DD21B7121F92E75A0034A7CE /* ActionToken.swift in Sources */, - 52B8065F1FB373BC0042FBA7 /* ZIndexed.swift in Sources */, - DD21B7131F92E75A0034A7CE /* TextLayer.swift in Sources */, - DD21B7151F92E75A0034A7CE /* Fadeable.swift in Sources */, - DD21B7161F92E75A0034A7CE /* RotateAction.swift in Sources */, - DD21B7181F92E75A0034A7CE /* PluginManager.swift in Sources */, - DD21B7481F92EC800034A7CE /* GameViewController-macOS.swift in Sources */, - DD21B7191F92E75A0034A7CE /* InstanceHashable.swift in Sources */, - DD21B71A1F92E75A0034A7CE /* ActionPerformer.swift in Sources */, - DD21B71B1F92E75A0034A7CE /* Rotatable.swift in Sources */, - DD21B71C1F92E75A0034A7CE /* Camera.swift in Sources */, - DD21B71D1F92E75A0034A7CE /* FadeAction.swift in Sources */, - DD21B71E1F92E75A0034A7CE /* Action.swift in Sources */, - 52A124D11FABA07500252047 /* EdgeInsets-macOS.swift in Sources */, - DD21B71F1F92E75A0034A7CE /* Texture.swift in Sources */, - DD21B7201F92E75A0034A7CE /* UpdateOutcome.swift in Sources */, - 523E5D111F9FEFBC0084792C /* SpriteSheet.swift in Sources */, - DD21B7211F92E75A0034A7CE /* MetricAction.swift in Sources */, - DD21B7221F92E75A0034A7CE /* Animation.swift in Sources */, - DD21B7231F92E75A0034A7CE /* Game.swift in Sources */, - DD21B7241F92E75A0034A7CE /* Mirroring.swift in Sources */, - DD21B7251F92E75A0034A7CE /* Actor.swift in Sources */, - DD21B7261F92E75A0034A7CE /* Timeline.swift in Sources */, - 5209C861208CC1690033DB4A /* GridPlaceable.swift in Sources */, - DD21B7271F92E75A0034A7CE /* Event.swift in Sources */, - 5209C84A208BE8EB0033DB4A /* AnyNode.swift in Sources */, - DD21B7281F92E75A0034A7CE /* EventToken.swift in Sources */, - DD21B7291F92E75A0034A7CE /* MoveAction.swift in Sources */, - DD21B72A1F92E75A0034A7CE /* TextureManager.swift in Sources */, - DD21B72B1F92E75A0034A7CE /* Constraint.swift in Sources */, - DD21B72C1F92E75A0034A7CE /* Typealiases.swift in Sources */, - 5209C846208BE4A90033DB4A /* Node.swift in Sources */, - DD21B72D1F92E75A0034A7CE /* DisplayLinkProtocol.swift in Sources */, - 521054271FFD78B1002FCFB6 /* LabelEventCollection.swift in Sources */, - 528B21521FA382B300CE9967 /* UpdatableCollection.swift in Sources */, - DD21B72E1F92E75A0034A7CE /* ReplicatorLayer.swift in Sources */, - DD21B72F1F92E75A0034A7CE /* RepeatMode.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 525688C11F9CF33100F87786 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = DD21B6F01F92E75A0034A7CE /* ImagineEngine-macOS */; - targetProxy = 525688C01F9CF33100F87786 /* PBXContainerItemProxy */; - }; - 5262A1CF1FA4CD1900DD5B3D /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 5262A1BB1FA4CCF900DD5B3D /* ImagineEngine-tvOS */; - targetProxy = 5262A1CE1FA4CD1900DD5B3D /* PBXContainerItemProxy */; - }; - 52D6D9891BEFF229002C0205 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 52D6D97B1BEFF229002C0205 /* ImagineEngine-iOS */; - targetProxy = 52D6D9881BEFF229002C0205 /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 525688C31F9CF33100F87786 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = NO; - DEVELOPMENT_TEAM = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Configs/ImagineEngineTests.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-macOS-Tests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 525688C41F9CF33100F87786 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = NO; - DEVELOPMENT_TEAM = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = Configs/ImagineEngineTests.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-macOS-Tests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 5262A1C11FA4CCF900DD5B3D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = "$(SRCROOT)/Configs/ImagineEngine.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-tvOS"; - PRODUCT_NAME = ImagineEngine; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 10.0; - }; - name = Debug; - }; - 5262A1C21FA4CCF900DD5B3D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_IDENTITY = ""; - CODE_SIGN_STYLE = Automatic; - DEFINES_MODULE = YES; - DEVELOPMENT_TEAM = ""; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = "$(SRCROOT)/Configs/ImagineEngine.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-tvOS"; - PRODUCT_NAME = ImagineEngine; - SDKROOT = appletvos; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 10.0; - }; - name = Release; - }; - 5262A1D11FA4CD1900DD5B3D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = TEE39J9D8F; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = "$(SRCROOT)/Configs/ImagineEngineTests.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-iOS-Tests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Debug; - }; - 5262A1D21FA4CD1900DD5B3D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = TEE39J9D8F; - GCC_C_LANGUAGE_STANDARD = gnu11; - INFOPLIST_FILE = "$(SRCROOT)/Configs/ImagineEngineTests.plist"; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-iOS-Tests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = appletvos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = 3; - TVOS_DEPLOYMENT_TARGET = 11.0; - }; - name = Release; - }; - 52D6D98E1BEFF229002C0205 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Debug; - }; - 52D6D98F1BEFF229002C0205 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SWIFT_VERSION = 3.0; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; - }; - name = Release; - }; - 52D6D9911BEFF229002C0205 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Configs/ImagineEngine.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-iOS"; - PRODUCT_NAME = ImagineEngine; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 52D6D9921BEFF229002C0205 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Configs/ImagineEngine.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-iOS"; - PRODUCT_NAME = ImagineEngine; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - 52D6D9941BEFF229002C0205 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - INFOPLIST_FILE = Configs/ImagineEngineTests.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-iOS-Tests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - }; - name = Debug; - }; - 52D6D9951BEFF229002C0205 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CLANG_ENABLE_MODULES = YES; - INFOPLIST_FILE = Configs/ImagineEngineTests.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-iOS-Tests"; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - }; - name = Release; - }; - DD21B7341F92E75A0034A7CE /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Configs/ImagineEngine.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-macOS"; - PRODUCT_NAME = ImagineEngine; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VALID_ARCHS = x86_64; - }; - name = Debug; - }; - DD21B7351F92E75A0034A7CE /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - APPLICATION_EXTENSION_API_ONLY = YES; - CLANG_ENABLE_MODULES = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Configs/ImagineEngine.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.12; - PRODUCT_BUNDLE_IDENTIFIER = "com.ImagineEngine.ImagineEngine-macOS"; - PRODUCT_NAME = ImagineEngine; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - SWIFT_VERSION = 5.0; - VALID_ARCHS = x86_64; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 525688C21F9CF33100F87786 /* Build configuration list for PBXNativeTarget "ImagineEngine-macOS Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 525688C31F9CF33100F87786 /* Debug */, - 525688C41F9CF33100F87786 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5262A1C31FA4CCF900DD5B3D /* Build configuration list for PBXNativeTarget "ImagineEngine-tvOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5262A1C11FA4CCF900DD5B3D /* Debug */, - 5262A1C21FA4CCF900DD5B3D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 5262A1D01FA4CD1900DD5B3D /* Build configuration list for PBXNativeTarget "ImagineEngine-tvOS Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 5262A1D11FA4CD1900DD5B3D /* Debug */, - 5262A1D21FA4CD1900DD5B3D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 52D6D9761BEFF229002C0205 /* Build configuration list for PBXProject "ImagineEngine" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 52D6D98E1BEFF229002C0205 /* Debug */, - 52D6D98F1BEFF229002C0205 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 52D6D9901BEFF229002C0205 /* Build configuration list for PBXNativeTarget "ImagineEngine-iOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 52D6D9911BEFF229002C0205 /* Debug */, - 52D6D9921BEFF229002C0205 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 52D6D9931BEFF229002C0205 /* Build configuration list for PBXNativeTarget "ImagineEngine-iOS Tests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 52D6D9941BEFF229002C0205 /* Debug */, - 52D6D9951BEFF229002C0205 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - DD21B7331F92E75A0034A7CE /* Build configuration list for PBXNativeTarget "ImagineEngine-macOS" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - DD21B7341F92E75A0034A7CE /* Debug */, - DD21B7351F92E75A0034A7CE /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 52D6D9731BEFF229002C0205 /* Project object */; -} diff --git a/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-iOS.xcscheme b/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-iOS.xcscheme deleted file mode 100644 index 046c280..0000000 --- a/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-iOS.xcscheme +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-macOS.xcscheme b/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-macOS.xcscheme deleted file mode 100644 index 900414c..0000000 --- a/ImagineEngine.xcodeproj/xcshareddata/xcschemes/ImagineEngine-macOS.xcscheme +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ImagineEngine/.gitignore b/ImagineEngine/.gitignore new file mode 100644 index 0000000..95c4320 --- /dev/null +++ b/ImagineEngine/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +/.build +/Packages +/*.xcodeproj +xcuserdata/ diff --git a/ImagineEngine/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata b/ImagineEngine/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/ImagineEngine/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ImagineEngine.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ImagineEngine/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from ImagineEngine.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to ImagineEngine/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/ImagineEngine/Package.swift b/ImagineEngine/Package.swift new file mode 100644 index 0000000..0ff0f41 --- /dev/null +++ b/ImagineEngine/Package.swift @@ -0,0 +1,28 @@ +// swift-tools-version:5.3 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "ImagineEngine", + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "ImagineEngine", + targets: ["ImagineEngine"]), + ], + dependencies: [ + // Dependencies declare other packages that this package depends on. + // .package(url: /* package url */, from: "1.0.0"), + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .target( + name: "ImagineEngine", + dependencies: []), + .testTarget( + name: "ImagineEngineTests", + dependencies: ["ImagineEngine"]), + ] +) diff --git a/ImagineEngine/Sources/Core/API/Action.swift b/ImagineEngine/Sources/Core/API/Action.swift new file mode 100644 index 0000000..72f2c90 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Action.swift @@ -0,0 +1,99 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Object representing an action that can be performed by an Imagine Engine game object + * + * By making an Actor or Camera perform an action, by can change one of its properties + * over time. Actions have a set duration during which they are performed, and get updated + * every frame. You can use actions to, for example, move objects around, resize them + * or fade them in or out. + * + * Imagine Engine ships with a default set of actions that are ready to use, and you + * can also easily define your own by subclassing this class and overriding one of the + * override points to perform your own custom action logic. + * + * Here's an example of how an Action can be used to move an Actor: + * + * ``` + * let point = Point(x: 200, y: 300) + * actor.perform(MoveAction(destination: point, duration: 5)) + * ``` + * + * When actions are performed, you get an `ActionToken` back as the result. These tokens + * enable you to both cancel an ongoing action, as well as to observe when it has been + * completed and chain it to other actions. + */ +open class Action { + internal let duration: TimeInterval + internal let token = ActionToken() + + private var startTime: TimeInterval? + private var lastUpdateTime: TimeInterval? + + // MARK: - Initializer + + /// Initialize an instance of this class with a duration + public init(duration: TimeInterval) { + self.duration = duration + } + + // MARK: - Override points + + /// Called on your action whenever it was started for an object + open func start(for object: Object) {} + + /// Called on each frame for as long as the action is active, with a context object + /// that can be used to drive your action's logic + open func update(with context: UpdateContext) {} + + /// Called whenever the action was cancelled, with the object it was attached to + open func cancel(for object: Object) {} + + /// Called whenever the action finished, with the object it was attached to + open func finish(for object: Object) {} + + // MARK: - Internal + + internal func reset() { + startTime = nil + lastUpdateTime = nil + } + + internal func update(for object: Object, currentTime: TimeInterval) -> UpdateOutcome { + let startTime = self.startTime.get(orSet: currentTime) + let timeElapsed = currentTime - startTime + let completionRatio = min(Metric(timeElapsed) / Metric(duration), 1) + let timeSinceLastUpdate = currentTime - (lastUpdateTime ?? currentTime) + + let context = Action.UpdateContext( + object: object, + timeElapsed: timeElapsed, + timeSinceLastUpdate: timeSinceLastUpdate, + completionRatio: completionRatio + ) + + update(with: context) + lastUpdateTime = currentTime + + if context.completionRatio < 1 { + return .continueAfter(0) + } + + return .finished + } +} + +public extension Action { + struct UpdateContext { + public let object: Object + public let timeElapsed: TimeInterval + public let timeSinceLastUpdate: TimeInterval + public let completionRatio: Metric + } +} diff --git a/ImagineEngine/Sources/Core/API/ActionPerformer.swift b/ImagineEngine/Sources/Core/API/ActionPerformer.swift new file mode 100644 index 0000000..5c98885 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/ActionPerformer.swift @@ -0,0 +1,20 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Protocol adopted by objects that are able to perform actions + * + * You don't conform to this protocol yourself, instead `Actor` & `Camera` already + * conform to this protocol, making them ready to perform actions. + */ +public protocol ActionPerformer: class { + /// Perform an action + /// The action will be started on the next frame, the returned `ActionToken` + /// can be used to cancel the action, or chain it to other ones. + @discardableResult func perform(_ action: Action) -> ActionToken +} diff --git a/ImagineEngine/Sources/Core/API/ActionToken.swift b/ImagineEngine/Sources/Core/API/ActionToken.swift new file mode 100644 index 0000000..ccd128c --- /dev/null +++ b/ImagineEngine/Sources/Core/API/ActionToken.swift @@ -0,0 +1,113 @@ +import Foundation + +/** + * Token returned when an action was performed + * + * You can use an action token to either cancel an action, or to observe when + * it was finished. You can also use it to chain an ongoing action to another + * one, making it automatically performed once the current action has finished. + * + * Here's an example of how to cancel an action: + * + * ``` + * let token = actor.move(byX: 50, y: 300, duration: 5) + * token.cancel() + * ``` + * + * Here's how you can run a closure whenever an action was finished: + * + * ``` + * actor.move(byX: 50, y: 300, duration: 5).then { + * print("Move finished!") + * } + * ``` + * + * Here's how an action can be chained into another: + * + * ``` + * actor.move(byX: 50, y: 300, duration: 5) + * .then(actor.fadeOut(withDuration: 3)) + * ``` + * + * Finally, here's how two actions can be linked togher to be performed at the same time: + * + * ``` + * actor.move(byX: 50, y: 300, duration: 5) + * .also(actor.fadeOut(withDuration: 3)) + * ``` + */ +public final class ActionToken: CancellationToken { + internal private(set) lazy var linkedTokens = [ActionToken]() + internal private(set) lazy var chain = [ChainItem]() + internal var isPending = false + private weak var precedingToken: ActionToken? + + // MARK: - API + + /// Link the action that this token is for to another one + /// You can use this API to perform two actions in parallel + @discardableResult public func also(_ token: ActionToken) -> ActionToken { + token.isPending = true + token.precedingToken = self + linkedTokens.append(token) + return token + } + + /// Chain the action that this token is for to another one + /// You can use this API to perform two actions in sequence + @discardableResult public func then(_ token: ActionToken) -> ActionToken { + token.isPending = true + token.precedingToken = self + chain.append(.token(token)) + return token + } + + /// Run any function after the action that this token is for has finished + @discardableResult public func then(_ closure: @escaping @autoclosure () -> Void) -> ActionToken { + chain.append(.closure(closure)) + return self + } + + /// Run any closure after the action that this token is for has finished + @discardableResult public func then(_ closure: @escaping () -> Void) -> ActionToken { + chain.append(.closure(closure)) + return self + } + + // MARK: - CancellationToken + + public override func cancel() { + super.cancel() + precedingToken?.cancel() + } + + // MARK: - Internal + + internal func performChaining() { + for item in chain { + switch item { + case .token(let token): + token.isPending = false + case .closure(let closure): + closure() + } + } + } +} + +public extension ActionToken { + /// Run a closure after the action that this token is for has finished, passing in a given object + /// to the closure (the object won't be retained and the closure won't be run if it's deallocated) + @discardableResult func then(using object: T, run closure: @escaping (T) -> Void) -> ActionToken { + return then { [weak object] in + object.map(closure) + } + } +} + +internal extension ActionToken { + enum ChainItem { + case token(ActionToken) + case closure(() -> Void) + } +} diff --git a/ImagineEngine/Sources/Core/API/Actor.swift b/ImagineEngine/Sources/Core/API/Actor.swift new file mode 100644 index 0000000..c2d5491 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Actor.swift @@ -0,0 +1,366 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation +import QuartzCore + +/** + * Class used to define an actor in a scene + * + * Actors are used to create active, animatable game objects that will make up + * all moving & controllable objects in your game. + * + * This class cannot be subclassed, and is instead designed to be configured & + * customized using Imagine Engine's Event & Plugin systems. By accessing an + * actor's event collection through the `event` property, you can easily bind + * actions to events that occur to it. You can also attach plugins to inject + * your own logic into an actor. See `Plugin` for more information. + * + * An example of adding an Actor that is playing an "Idle" animation to a Scene: + * + * ``` + * let actor = Actor() + * actor.animation = Animation(name: "Idle", frameCount: 4, frameDuration: 0.15) + * scene.add(actor) + * ``` + */ +public final class Actor: Node, InstanceHashable, ActionPerformer, + Pluggable, ZIndexed, Movable, Rotatable, Scalable, + Fadeable, Activatable, GridPlaceable { + /// The scene that the actor currently belongs to. + override public internal(set) weak var scene: Scene? { didSet { sceneDidChange() } } + /// A collection of events that can be used to observe the actor. + public private(set) lazy var events = ActorEventCollection(object: self) + /// The index of the actor on the z axis. Affects rendering & hit testing. 0 = implicit index. + public var zIndex = 0 { didSet { layer.zPosition = Metric(zIndex) } } + /// The position (center-point) of the actor within its scene. + public var position = Point() { didSet { positionDidChange(from: oldValue) } } + /// The size of the actor (centered on its position). + public var size = Size() { didSet { sizeDidChange(from: oldValue) } } + /// The rotation of the actor along the z axis. + public var rotation = Metric() { didSet { rotationDidChange(from: oldValue) } } + /// Any radius that should be applied to the corners of the actor. Default = 0. + public var cornerRadius = Metric() { didSet { layer.cornerRadius = cornerRadius } } + /// The scale the actor gets rendered at. Affects collision detection unless a hitboxSize is set. + public var scale: Metric = 1 { didSet { scaleDidChange(from: oldValue) } } + /// The velocity of the actor. Used for continous directional movement. + public var velocity = Vector() { didSet { velocityDidChange(from: oldValue) } } + /// The opacity of the actor. Ranges from 0 (transparent) - 1 (opaque). + public var opacity = Metric(1) { didSet { layer.opacity = Float(opacity) } } + /// Any mirroring to apply when rendering the actor. See `Mirroring` for options. + public var mirroring = Set() { didSet { applyLayerTransform() } } + /// The actor's background color. Default is `.clear` (no background). + public var backgroundColor = Color.clear { didSet { layer.backgroundColor = backgroundColor.cgColor } } + /// Any shadow that should be rendered beneath the actor. Using shadows may impact performance. + public var shadow: Shadow? { didSet { shadowDidChange() } } + /// Any texture-based animation that the actor is playing. See `Animation` for more info. + public var animation: Animation? { didSet { animationDidChange(from: oldValue) } } + /// Any prefix that should be prepended to the names of all textures loaded for the actor + public var textureNamePrefix: String? + /// Any explicit size of the actor's hitbox (for collision detection). `nil` = the actor's `size`. + public var hitboxSize: Size? + /// Whether the actor is able to participate in collisions. + public var isCollisionDetectionEnabled = true + /// Whether the actor responds to hit testing. + public var isHitTestingEnabled = true { didSet { hitTestingStatusDidChange(from: oldValue) } } + /// Any constraints that are applied to the actor, to restrict how and where it can move. + public var constraints = Set() + /// Any logical group that the actor is a part of. Can be used for events & collisions. + public var group: Group? + + internal lazy var actorsInContact = Set() + internal lazy var blocksInContact = Set() + internal var isWithinScene = false + internal var isCollisionDetectionActive = false + + private let pluginManager = PluginManager() + private lazy var actionManager = ActionManager(object: self) + private var velocityActionToken: ActionToken? + private var animationActionToken: ActionToken? + private var isUpdatingPosition = false + + // MARK: - Initializer + + /// Initialize an instance of this class + public init() { + super.init(layer: Layer()) + } + + // MARK: - API + + /// Remove this actor from its scene + public func remove() { + scene?.remove(self) + scene = nil + layer.removeFromSuperlayer() + } + + /// Check if this actor is in contact with another actor + public func isInContact(with actor: Actor) -> Bool { + return actorsInContact.contains(actor) + } + + /// Check if this actor is in contact with a given block + public func isInContact(with block: Block) -> Bool { + return blocksInContact.contains(block) + } + + // MARK: - ActionPerformer + + @discardableResult public func perform(_ action: Action) -> ActionToken { + return actionManager.add(action) + } + + // MARK: - Pluggable + + @discardableResult public func add(_ plugin: @autoclosure () -> P, + reuseExistingOfSameType: Bool) -> P where P.Object == Actor { + return pluginManager.add(plugin, for: self, reuseExistingOfSameType: reuseExistingOfSameType) + } + + public func plugins(ofType type: P.Type) -> [P] where P.Object == Actor { + return pluginManager.plugins(ofType: type) + } + + public func remove(_ plugin: P) where P.Object == Actor { + pluginManager.remove(plugin, from: self) + } + + public func removePlugins(ofType type: P.Type) where P.Object == Actor { + pluginManager.removePlugins(ofType: type, from: self) + } + + // MARK: - Activatable + + internal func activate(in game: Game) { + pluginManager.activate(in: game) + actionManager.activate(in: game) + } + + internal func deactivate() { + pluginManager.deactivate() + actionManager.deactivate() + } + + // MARK: - GridPlaceable + + internal func add(to gridTile: Grid.Tile) { + gridTile.actors.insert(self) + gridTiles.insert(gridTile) + } + + internal func remove(from gridTile: Grid.Tile) { + gridTile.actors.remove(self) + gridTiles.remove(gridTile) + } + + // MARK: - Internal + + internal func render(frame: Animation.Frame, scale: Int?, resize: Bool, ignoreNamePrefix: Bool) { + guard let textureManager = scene?.textureManager else { + return + } + + let namePrefix = ignoreNamePrefix ? nil : textureNamePrefix + let loadedTexture = textureManager.load(frame.texture, namePrefix: namePrefix, scale: scale) + + layer.contents = loadedTexture?.image + layer.contentsRect = frame.contentRect + + if resize { + if var newSize = loadedTexture?.size { + newSize.width *= frame.contentRect.width + newSize.height *= frame.contentRect.height + size = newSize + } + } + } + + // MARK: - Private + + private func sceneDidChange() { + renderFirstAnimationFrameIfNeeded() + } + + private func positionDidChange(from oldValue: Point) { + guard position != oldValue else { + return + } + + let isOriginalUpdate = !isUpdatingPosition + isUpdatingPosition = true + + layer.position = position + rectDidChange() + + guard isOriginalUpdate else { + return + } + + isUpdatingPosition = false + + guard position != oldValue else { + return + } + + events.moved.trigger(with: (oldValue, position)) + events.rectChanged.trigger() + } + + private func sizeDidChange(from oldValue: Size) { + guard size != oldValue else { + return + } + + layer.bounds.size = size + rectDidChange() + + events.resized.trigger() + events.rectChanged.trigger() + } + + private func rotationDidChange(from oldValue: Metric) { + guard rotation != oldValue else { + return + } + + applyLayerTransform() + rectDidChange() + + events.rotated.trigger() + } + + private func rectDidChange() { + guard isCollisionDetectionEnabled || isHitTestingEnabled else { + return + } + + scene?.actorRectDidChange(self) + } + + private func scaleDidChange(from oldValue: Metric) { + guard oldValue != scale else { + return + } + + applyLayerTransform() + rectDidChange() + } + + private func velocityDidChange(from oldValue: Vector) { + guard velocity != oldValue else { + return + } + + events.velocityChanged.trigger() + velocityActionToken?.cancel() + + guard velocity != .zero else { + return + } + + velocityActionToken = perform(RepeatAction( + action: MoveAction(vector: velocity, duration: 1) + )) + } + + private func shadowDidChange() { + layer.shadowRadius = shadow?.radius ?? 0 + layer.shadowOpacity = Float(shadow?.opacity ?? 0) + layer.shadowColor = shadow?.color.cgColor + layer.shadowOffset.width = shadow?.offset.x ?? 0 + layer.shadowOffset.height = shadow?.offset.y ?? 0 + layer.shadowPath = shadow?.path + } + + private func animationDidChange(from oldValue: Animation?) { + guard animation != oldValue else { + return + } + + animationActionToken?.cancel() + + guard let animation = animation else { + layer.contents = nil + return + } + + renderFirstAnimationFrameIfNeeded() + + guard animation.frameCount > 1 else { + return + } + + let action = AnimationAction(animation: animation, triggeredByActor: true) + animationActionToken = perform(action) + } + + private func hitTestingStatusDidChange(from oldValue: Bool) { + if oldValue == false && isHitTestingEnabled == true { + rectDidChange() + } + } + + private func renderFirstAnimationFrameIfNeeded() { + guard let animation = animation else { + return + } + + guard animation.frameCount > 0 else { + return + } + + render(frame: animation.frame(at: 0), + scale: animation.textureScale, + resize: animation.autoResize, + ignoreNamePrefix: animation.ignoreTextureNamePrefix) + } + + private func applyLayerTransform() { + layer.applyTransform(withRotation: rotation, scale: scale, mirroring: mirroring) + } +} + +public extension Actor { + /// Initialize an actor that renders a single texture with a given name + convenience init(textureNamed textureName: String, scale: Int? = nil, format: TextureFormat? = nil) { + self.init() + animation = Animation(textureNamed: textureName, scale: scale, format: format) + animationDidChange(from: nil) + } + + /// Initialize an actor that renders a single image as its animation + convenience init(image: Image) { + self.init() + animation = Animation(image: image) + animationDidChange(from: nil) + } + + /// Initialize an actor with a given size + convenience init(size: Size) { + self.init() + self.size = size + sizeDidChange(from: .zero) + } + + /// Makes the actor start playing an animation as an action + func playAnimation(_ animation: Animation) -> ActionToken { + return perform(AnimationAction(animation: animation)) + } +} + +internal extension Actor { + var rectForCollisionDetection: Rect { + if let hitboxSize = hitboxSize { + var rect = Rect(origin: position, size: hitboxSize) + rect.origin.x -= hitboxSize.width / 2 + rect.origin.y -= hitboxSize.height / 2 + return rect + } + + return rect + } +} diff --git a/ImagineEngine/Sources/Core/API/ActorEventCollection.swift b/ImagineEngine/Sources/Core/API/ActorEventCollection.swift new file mode 100644 index 0000000..105b47b --- /dev/null +++ b/ImagineEngine/Sources/Core/API/ActorEventCollection.swift @@ -0,0 +1,46 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Events that can be used to observe an actor +public final class ActorEventCollection: EventCollection { + /// Event triggered when the actor was moved + public private(set) lazy var moved = Event(object: self.object) + /// Event triggered when the actor was resized + public private(set) lazy var resized = Event(object: self.object) + /// Event triggered when the actor was rotated + public private(set) lazy var rotated = Event(object: self.object) + /// Event triggered when the actor's rectangle changed (either by position or size) + public private(set) lazy var rectChanged = Event(object: self.object) + /// Event triggered when the actor's velocity changed + public private(set) lazy var velocityChanged = Event(object: self.object) + /// Event triggered when actor entered its scene + public private(set) lazy var enteredScene = Event(object: self.object) + /// Event triggered when the actor exited its scene + public private(set) lazy var leftScene = Event(object: self.object) + /// Event triggered when the actor was clicked (on macOS) or tapped (on iOS/tvOS) + public private(set) lazy var clicked = Event(object: object) + + /// Event triggered when the actor collided with another actor + public func collided(with actor: Actor) -> Event { + object?.isCollisionDetectionActive = true + actor.isCollisionDetectionActive = true + return makeEvent(withSubject: actor) + } + + /// Event triggered when the actor collided with an actor in a given group + public func collided(withActorInGroup group: Group) -> Event { + object?.isCollisionDetectionActive = true + return makeEvent(withSubjectIdentifier: group.identifier) + } + + /// Event triggered when the actor collided with a block in a given group + public func collided(withBlockInGroup group: Group) -> Event { + object?.isCollisionDetectionActive = true + return makeEvent(withSubjectIdentifier: group.identifier) + } +} diff --git a/ImagineEngine/Sources/Core/API/Animation.swift b/ImagineEngine/Sources/Core/API/Animation.swift new file mode 100644 index 0000000..40b804a --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Animation.swift @@ -0,0 +1,230 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Type used to describe an animation that can be performed by an Actor + * + * An animation consists of frames that are rendered by an actor in sequence, + * based on a given `frameDuration`. The textures that make up an animation's + * frames can either be defined explicitly, or be interred based on the name + * of the animation + the index of the frame. You can also tweak other properties + * of an animation, including its repeat mode and whether the actor should be + * resized when performing it. + * + * Example usage: + * ``` + * let player = Actor() + * player.animation = Animation(textureNamed: "Idle") + * ``` + */ +public struct Animation { + /// The content that make up the frames of the animation + public var content: Content { didSet { updateIdentifier() } } + /// The duration for which each frame should be rendered + public var frameDuration = TimeInterval(1) + /// How the animation should be repeated + public var repeatMode = RepeatMode.forever + /// Whether the actor performing the animation should be resized according to each frame + public var autoResize = true + /// Whether the actor's `textureNamePrefix` should be ignored for this animation + public var ignoreTextureNamePrefix = false + /// Any explicit scale that should be used when loading textures for this animation + public var textureScale: Int? + + private var identifier = "" +} + +public extension Animation { + /// Initialize an instance with its various parameters. See the documentation for + /// each property for more information. + init(name: String, + frameCount: Int, + frameDuration: TimeInterval, + frameIndexSeparator: String = "/", + repeatMode: RepeatMode = .forever, + autoResize: Bool = true, + ignoreTextureNamePrefix: Bool = false, + textureFormat: TextureFormat = .png, + textureScale: Int? = nil) { + self.content = .frames(withBaseName: name, + indexSeparator: frameIndexSeparator, + format: textureFormat, + count: frameCount) + self.frameDuration = frameDuration + self.repeatMode = repeatMode + self.autoResize = autoResize + self.ignoreTextureNamePrefix = ignoreTextureNamePrefix + self.textureScale = textureScale + updateIdentifier() + } + + /// Initialize an instance with a single texture with a certain image name + init(textureNamed textureName: String, scale: Int? = nil, format: TextureFormat? = nil) { + content = .texture(Texture(name: textureName, format: format)) + textureScale = scale + updateIdentifier() + } + + /// Initialize an instance with a sequence of textures loaded from an array of image names + init(texturesNamed textureNames: [String], format: TextureFormat? = nil, frameDuration: TimeInterval) { + content = .textures(textureNames.map { Texture(name: $0, format: format) }) + self.frameDuration = frameDuration + updateIdentifier() + } + + /// Initialize an instance with an image to use for the animation + init(image: Image) { + content = .texture(Texture(image: image)) + updateIdentifier() + } + + /// Initialize an instance with an array of images to use for the animation + init(images: [Image], frameDuration: TimeInterval) { + content = .textures(images.map(Texture.init)) + self.frameDuration = frameDuration + updateIdentifier() + } + + /// Initialize an instance with a sprite sheet from a given image name + init(spriteSheetNamed name: String, + frameCount: Int, + rowCount: Int = 1, + frameDuration: TimeInterval, + repeatMode: RepeatMode = .forever, + autoResize: Bool = true, + ignoreTextureNamePrefix: Bool = false, + textureFormat format: TextureFormat? = nil) { + let spriteSheet = SpriteSheet( + textureNamed: name, + format: format, + frameCount: frameCount, + rowCount: rowCount + ) + + self.init(spriteSheet: spriteSheet, + frameDuration: frameDuration, + repeatMode: repeatMode, + autoResize: autoResize, + ignoreTextureNamePrefix: ignoreTextureNamePrefix) + } + + /// Initialize an instance with a sprite sheet + init(spriteSheet: SpriteSheet, + frameDuration: TimeInterval, + repeatMode: RepeatMode = .forever, + autoResize: Bool = true, + ignoreTextureNamePrefix: Bool = false) { + content = .spriteSheet(spriteSheet) + self.frameDuration = frameDuration + self.repeatMode = repeatMode + self.autoResize = autoResize + self.ignoreTextureNamePrefix = ignoreTextureNamePrefix + + updateIdentifier() + } +} + +public extension Animation { + /// Enum describing types of content that an animation can be made up of + enum Content { + /// The animation consists of a series of separate textures + case textures([Texture]) + /// The animation is powered by a single texture used as a sprite sheet + case spriteSheet(SpriteSheet) + } +} + +internal extension Animation { + struct Frame { + let texture: Texture + let contentRect: Rect + } + + var frameCount: Int { + switch content { + case .textures(let textures): + return textures.count + case .spriteSheet(let sheet): + return sheet.slicedArea?.frameCount ?? sheet.frameCount + } + } + + var totalDuration: TimeInterval { + switch repeatMode { + case .times(let count): + return TimeInterval(count) * TimeInterval(frameCount) * frameDuration + case .forever: + return .infinity + } + } + + func frame(at index: Int) -> Frame { + switch content { + case .textures(let textures): + let contentRect = Rect(x: 0, y: 0, width: 1, height: 1) + return Frame(texture: textures[index], contentRect: contentRect) + case .spriteSheet(let sheet): + return sheet.frame(at: index) + } + } +} + +private extension Animation { + mutating func updateIdentifier() { + var newIdentifier = "" + + switch content { + case .textures(let textures): + for texture in textures { + newIdentifier.append("\(texture.name)-") + } + case .spriteSheet(let sheet): + newIdentifier = "\(sheet.texture.name)-\(sheet.frameCount)-\(sheet.rowCount)" + } + + identifier = newIdentifier + } +} + +private extension Animation.Content { + static func frames(withBaseName name: String, + indexSeparator: String, + format: TextureFormat, + count: Int) -> Animation.Content { + let frames = (0.. Animation.Content { + return .textures([texture]) + } +} + +extension Animation: Equatable { + public static func ==(lhs: Animation, rhs: Animation) -> Bool { + guard lhs.identifier == rhs.identifier else { + return false + } + + guard lhs.frameDuration == rhs.frameDuration else { + return false + } + + guard lhs.repeatMode == rhs.repeatMode else { + return false + } + + guard lhs.autoResize == rhs.autoResize else { + return false + } + + return true + } +} diff --git a/ImagineEngine/Sources/Core/API/AnimationAction.swift b/ImagineEngine/Sources/Core/API/AnimationAction.swift new file mode 100644 index 0000000..2dc865b --- /dev/null +++ b/ImagineEngine/Sources/Core/API/AnimationAction.swift @@ -0,0 +1,69 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Action used to make an actor play an animation +public final class AnimationAction: Action { + private let animation: Animation + private let triggeredByActor: Bool + private var frameIndex = 0 + private var repeatCount = 0 + + // MARK: - Initializers + + /// Initialize an instance of this action with an animation + public init(animation: Animation) { + self.animation = animation + self.triggeredByActor = false + super.init(duration: animation.totalDuration) + } + + internal init(animation: Animation, triggeredByActor: Bool) { + self.animation = animation + self.triggeredByActor = triggeredByActor + super.init(duration: animation.totalDuration) + } + + // MARK: - Action + + public override func start(for actor: Actor) { + if !triggeredByActor { + actor.animation = animation + } + } + + internal override func update(for actor: Actor, currentTime: TimeInterval) -> UpdateOutcome { + let frame = animation.frame(at: frameIndex) + frameIndex += 1 + + actor.render(frame: frame, + scale: animation.textureScale, + resize: animation.autoResize, + ignoreNamePrefix: animation.ignoreTextureNamePrefix) + + if animation.frameCount < 2 { + return .finished + } + + if frameIndex == animation.frameCount { + switch animation.repeatMode { + case .times(let count): + guard repeatCount < count else { + actor.animation = nil + return .finished + } + case .forever: + break + } + + repeatCount += 1 + frameIndex = 0 + } + + return .continueAfter(animation.frameDuration) + } +} diff --git a/ImagineEngine/Sources/Core/API/Block.swift b/ImagineEngine/Sources/Core/API/Block.swift new file mode 100644 index 0000000..97224e5 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Block.swift @@ -0,0 +1,383 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation +import QuartzCore + +/** + * Class used to render a block of tiled textures + * + * Blocks are non-active game objects (in that they can't be resized, transformed + * or have any events associated with them), that have the unique ability to render + * a collection of textures in a tiled way. You can assign up to 9 textures to a + * block, and it will automatically tile them to make it look nicely no matter which + * size the block itself is. + * + * You specify the textures that a block should render using `BlockTextureCollection`, + * or you can simpy pass the name of such a collection when creating a block to have + * Imagine Engine automatically infer the names of all its parts. + */ +public final class Block: Node, InstanceHashable, ActionPerformer, ZIndexed, + Movable, Activatable, GridPlaceable { + /// The index of the block on the z axis. 0 = implicit index. + public var zIndex = 0 { didSet { layer.zPosition = Metric(zIndex) } } + /// The position (center-point) of the block within its scene. + public var position = Point() { didSet { positionDidChange() } } + /// The size of the block (centered on its position). + public let size: Size + /// The block's background color. Default is `.clear` (no background). + public var backgroundColor = Color.clear { didSet { layer.backgroundColor = backgroundColor.cgColor } } + /// Any logical group that the block is a part of. Can be used for events & collisions. + public var group: Group? + + internal lazy var actorsInContact = Set() + + private let content: Content + private let textureScale: Int? + private lazy var actionManager = ActionManager(object: self) + + private init(size: Size, content: Content, textureScale: Int? = nil) { + self.size = size + self.content = content + self.textureScale = textureScale + + super.init(layer: Layer()) + + layer.bounds.size = size + } + + // MARK: - Public + + /// Remove this block from its scene + public func remove() { + scene?.remove(self) + scene = nil + layer.removeFromSuperlayer() + } + + // MARK: - ActionPerformer + + @discardableResult public func perform(_ action: Action) -> ActionToken { + return actionManager.add(action) + } + + // MARK: - Activatable + + internal func activate(in game: Game) { + addSublayers(using: game.scene.textureManager) + actionManager.activate(in: game) + } + + internal func deactivate() { + actionManager.deactivate() + } + + // MARK: - GridPlaceable + + internal func add(to gridTile: Grid.Tile) { + gridTile.blocks.insert(self) + gridTiles.insert(gridTile) + } + + internal func remove(from gridTile: Grid.Tile) { + gridTile.blocks.remove(self) + gridTiles.remove(gridTile) + } + + // MARK: - Private + + private func addSublayers(using textureManager: TextureManager) { + let segmentLayers: SegmentLayerCollection + + switch content { + case .collection(let textures): + segmentLayers = makeSegmentLayers(from: textures, using: textureManager) + case .texture(let texture): + guard let loadedTexture = textureManager.load(texture, namePrefix: nil, scale: textureScale) else { + return + } + + segmentLayers = makeSegmentLayers(from: loadedTexture) + } + + setupFrames(for: segmentLayers) + let centerReplicatorLayer = makeCenterReplicationLayer(for: segmentLayers) + + layer.addSublayer(segmentLayers.top) + layer.addSublayer(segmentLayers.bottom) + layer.addSublayer(centerReplicatorLayer) + } + + private func makeSegmentLayers(from textures: BlockTextureCollection, + using textureManager: TextureManager) -> SegmentLayerCollection { + func loadTexture(_ texture: Texture?) -> LoadedTexture? { + guard let texture = texture else { + return nil + } + + return textureManager.load(texture, namePrefix: nil, scale: textureScale) + } + + let topSegmentLayer = SegmentLayer() + topSegmentLayer.renderWithTextures(left: loadTexture(textures.topLeft), + center: loadTexture(textures.top), + right: loadTexture(textures.topRight), + width: size.width) + + let bottomSegmentLayer = SegmentLayer() + bottomSegmentLayer.renderWithTextures(left: loadTexture(textures.bottomLeft), + center: loadTexture(textures.bottom), + right: loadTexture(textures.bottomRight), + width: size.width) + + let centerSegmentLayer = SegmentLayer() + centerSegmentLayer.renderWithTextures(left: loadTexture(textures.left), + center: loadTexture(textures.center), + right: loadTexture(textures.right), + width: size.width) + + return SegmentLayerCollection( + top: topSegmentLayer, + bottom: bottomSegmentLayer, + center: centerSegmentLayer + ) + } + + private func makeSegmentLayers(from texture: LoadedTexture) -> SegmentLayerCollection { + let contentMetric: Metric = 1 / 3 + let contentSize = Size(width: contentMetric, height: contentMetric) + + func makeContentRect(withX x: Metric, y: Metric) -> Rect { + return Rect(origin: Point(x: x, y: y), size: contentSize) + } + + let contentRects = ( + top: makeContentRect(withX: contentMetric, y: 0), + topLeft: makeContentRect(withX: 0, y: 0), + topRight: makeContentRect(withX: contentMetric * 2, y: 0), + left: makeContentRect(withX: 0, y: contentMetric), + right: makeContentRect(withX: contentMetric * 2, y: contentMetric), + center: makeContentRect(withX: contentMetric, y: contentMetric), + bottom: makeContentRect(withX: contentMetric, y: contentMetric * 2), + bottomLeft: makeContentRect(withX: 0, y: contentMetric * 2), + bottomRight: makeContentRect(withX: contentMetric * 2, y: contentMetric * 2) + ) + + let topSegmentLayer = SegmentLayer() + topSegmentLayer.renderWithTextures( + left: texture, + center: texture, + right: texture, + leftContentRect: contentRects.topLeft, + centerContentRect: contentRects.top, + rightContentRect: contentRects.topRight, + width: size.width + ) + + let bottomSegmentLayer = SegmentLayer() + bottomSegmentLayer.renderWithTextures( + left: texture, + center: texture, + right: texture, + leftContentRect: contentRects.bottomLeft, + centerContentRect: contentRects.bottom, + rightContentRect: contentRects.bottomRight, + width: size.width + ) + + let centerSegmentLayer = SegmentLayer() + centerSegmentLayer.renderWithTextures( + left: texture, + center: texture, + right: texture, + leftContentRect: contentRects.left, + centerContentRect: contentRects.center, + rightContentRect: contentRects.right, + width: size.width + ) + + return SegmentLayerCollection( + top: topSegmentLayer, + bottom: bottomSegmentLayer, + center: centerSegmentLayer + ) + } + + private func setupFrames(for segmentLayers: SegmentLayerCollection) { + #if os(macOS) + let centerHeight = size.height - segmentLayers.top.frame.height - segmentLayers.bottom.frame.height + segmentLayers.top.frame.origin.y = size.height - segmentLayers.top.frame.size.height + segmentLayers.center.frame.origin.y = centerHeight - segmentLayers.center.frame.size.height + + segmentLayers.bottom.frame.origin.y = 0 + #else + segmentLayers.bottom.frame.origin.y = size.height - segmentLayers.bottom.frame.height + #endif + } + + private func makeCenterReplicationLayer(for segmentLayers: SegmentLayerCollection) -> ReplicatorLayer { + let centerReplicatorLayer = ReplicatorLayer() + + #if os(macOS) + let centerHeight = size.height - segmentLayers.top.frame.height - segmentLayers.bottom.frame.height + centerReplicatorLayer.frame = Rect( + x: 0, + y: segmentLayers.bottom.frame.height, + width: size.width, + height: centerHeight + ) + centerReplicatorLayer.instanceTransform = CATransform3DMakeTranslation(0, -segmentLayers.center.frame.height, 0) + #else + centerReplicatorLayer.frame = Rect( + x: 0, + y: segmentLayers.top.frame.height, + width: size.width, + height: size.height - segmentLayers.top.frame.height - segmentLayers.bottom.frame.height + ) + centerReplicatorLayer.instanceTransform = CATransform3DMakeTranslation(0, segmentLayers.center.frame.height, 0) + #endif + + centerReplicatorLayer.masksToBounds = true + + if segmentLayers.center.frame.height > 0 { + let fractionalInstanceCount = centerReplicatorLayer.frame.height / segmentLayers.center.frame.height + centerReplicatorLayer.instanceCount = Int(ceil(fractionalInstanceCount)) + } + + centerReplicatorLayer.addSublayer(segmentLayers.center) + + return centerReplicatorLayer + } + + private func positionDidChange() { + layer.position = position + scene?.blockRectDidChange(self) + } +} + +public extension Block { + /// Initialize an instance of this class, with a given size and a collection of + /// textures that it should render. You may also (optionally) choose which scale + /// that the textures should be loaded using. + convenience init(size: Size, textures: BlockTextureCollection, textureScale: Int? = nil) { + self.init(size: size, content: .collection(textures), textureScale: textureScale) + } + + /// Initialize an instance of this class with a single texture. You may also + /// (optionally) choose which scale that the textures should be loaded using. + convenience init(size: Size, texture: Texture, textureScale: Int? = nil) { + var collection = BlockTextureCollection() + collection.center = texture + self.init(size: size, textures: collection, textureScale: textureScale) + } + + /// Initialize an instance with a given size and the name of a texture collection + /// See `BlockTextureCollection` for more information about how the names of + /// individual textures are inferred. + convenience init(size: Size, + textureCollectionName: String, + textureScale: Int? = nil, + textureFormat: TextureFormat? = nil) { + let textures = BlockTextureCollection(name: textureCollectionName, textureFormat: textureFormat) + self.init(size: size, content: .collection(textures), textureScale: textureScale) + } + + /// Initialize an instance with a given size and the name of a sprite sheet to use for + /// the block's textures. The texture for the sprite sheet will be cut into 9 identically + /// sized pieces (3 x 3), which will be used to tile the block. + convenience init(size: Size, + spriteSheetName: String, + textureScale: Int? = nil, + textureFormat: TextureFormat? = nil) { + let texture = Texture(name: spriteSheetName, format: textureFormat) + self.init(size: size, content: .texture(texture), textureScale: textureScale) + } +} + +private extension Block { + enum Content { + case texture(Texture) + case collection(BlockTextureCollection) + } + + final class SegmentLayer: CALayer { + override func action(forKey event: String) -> CAAction? { + return NSNull() + } + + func renderWithTextures(left leftTexture: LoadedTexture?, + center centerTexture: LoadedTexture?, + right rightTexture: LoadedTexture?, + leftContentRect: Rect = .defaultContentRect, + centerContentRect: Rect = .defaultContentRect, + rightContentRect: Rect = .defaultContentRect, + width: Metric) { + var leftLayerSize = Size() + var rightLayerSize = Size() + var centerLayerHeight: Metric = 0 + + if let leftTexture = leftTexture { + let leftLayer = makeContentLayer(withTexture: leftTexture, contentRect: leftContentRect) + addSublayer(leftLayer) + leftLayerSize = leftLayer.frame.size + } + + if let rightTexture = rightTexture { + let rightLayer = makeContentLayer(withTexture: rightTexture, contentRect: rightContentRect) + rightLayer.frame.origin.x = width - rightLayer.frame.width + addSublayer(rightLayer) + rightLayerSize = rightLayer.frame.size + } + + if let centerTexture = centerTexture { + let centerContentLayer = makeContentLayer(withTexture: centerTexture, contentRect: centerContentRect) + let centerTextureSize = centerContentLayer.frame.size + + let replicatorLayer = ReplicatorLayer() + replicatorLayer.frame.size.width = width - leftLayerSize.width - rightLayerSize.width + replicatorLayer.frame.size.height = centerTextureSize.height + replicatorLayer.frame.origin.x = leftLayerSize.width + replicatorLayer.instanceCount = Int(ceil(replicatorLayer.frame.width / centerTextureSize.width)) + replicatorLayer.instanceTransform = CATransform3DMakeTranslation(centerTextureSize.width, 0, 0) + replicatorLayer.masksToBounds = true + replicatorLayer.addSublayer(centerContentLayer) + addSublayer(replicatorLayer) + + centerLayerHeight = replicatorLayer.frame.height + } + + frame.size = Size( + width: width, + height: max(leftLayerSize.height, rightLayerSize.height, centerLayerHeight) + ) + } + + private func makeContentLayer(withTexture texture: LoadedTexture, contentRect: Rect) -> CALayer { + let layer = Layer() + layer.contents = texture.image + layer.contentsRect = contentRect + layer.frame.size.width = texture.size.width * contentRect.size.width + layer.frame.size.height = texture.size.height * contentRect.size.height + return layer + } + } + + final class ReplicatorLayer: CAReplicatorLayer { + override func action(forKey event: String) -> CAAction? { + return NSNull() + } + } + + struct SegmentLayerCollection { + let top: SegmentLayer + let bottom: SegmentLayer + let center: SegmentLayer + } +} + +private extension Rect { + static let defaultContentRect = Rect(x: 0, y: 0, width: 1, height: 1) +} diff --git a/ImagineEngine/Sources/Core/API/BlockTextureCollection.swift b/ImagineEngine/Sources/Core/API/BlockTextureCollection.swift new file mode 100644 index 0000000..3a3c52c --- /dev/null +++ b/ImagineEngine/Sources/Core/API/BlockTextureCollection.swift @@ -0,0 +1,50 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// A collection of textures that a Block can render +public struct BlockTextureCollection { + /// The top texture, tiled horizontally if needed + public var top: Texture? + /// The top left texture + public var topLeft: Texture? + /// The top right texture + public var topRight: Texture? + /// The right texture, tiled vertically if needed + public var right: Texture? + /// The left texture, tiled vertically if needed + public var left: Texture? + /// The center texture, tiled both horizontally & vertically if needed + public var center: Texture? + /// The bottom texture, tiled horizontally if needed + public var bottom: Texture? + /// The bottom left texture + public var bottomLeft: Texture? + /// The bottom right texture + public var bottomRight: Texture? + + /// Initialize an instance, optionally with a name + /// If a name is given, then textures will automatically be assigned to + /// all properties using the property name as a suffix for the texture's + /// name. This enables you to create a folder containing textures for a + /// block and simply reference them using the folder's name. + public init(name: String? = nil, textureFormat: TextureFormat? = nil) { + guard let name = name else { + return + } + + top = Texture(name: "\(name)/top", format: textureFormat) + topLeft = Texture(name: "\(name)/topLeft", format: textureFormat) + topRight = Texture(name: "\(name)/topRight", format: textureFormat) + right = Texture(name: "\(name)/right", format: textureFormat) + left = Texture(name: "\(name)/left", format: textureFormat) + center = Texture(name: "\(name)/center", format: textureFormat) + bottom = Texture(name: "\(name)/bottom", format: textureFormat) + bottomLeft = Texture(name: "\(name)/bottomLeft", format: textureFormat) + bottomRight = Texture(name: "\(name)/bottomRight", format: textureFormat) + } +} diff --git a/ImagineEngine/Sources/Core/API/Camera.swift b/ImagineEngine/Sources/Core/API/Camera.swift new file mode 100644 index 0000000..c4e76f8 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Camera.swift @@ -0,0 +1,145 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Class that represents a camera in a scene + * + * You use a scene's camera to move the viewport of your game around. Initially + * all cameras start out at the center of their scene. A camera gets its size + * from the game that its scene is presented in. + */ +public final class Camera: ActionPerformer, Pluggable, Movable, Activatable { + /// The position of the camera within its scene + public var position = Point() { didSet { positionDidChange(from: oldValue) } } + /// The size of the camera's viewport. Set as soon as its presented in a game. + public internal(set) var size = Size() { didSet { sizeDidChange(from: oldValue) }} + /// The current rectangle of the camera's viewport. + public private(set) var rect = Rect() + /// A collection of events that can be used to observe the camera. + public private(set) lazy var events = CameraEventCollection(object: self) + /// Whether the camera is constrained to the scene or can move outside of it (default = false) + public var constrainedToScene = false { didSet { update() } } + + private let pluginManager = PluginManager() + private lazy var actionManager = ActionManager(object: self) + private weak var scene: Scene? + private let layer: Layer + + // MARK: - Initializer + + internal init(scene: Scene, layer: Layer) { + self.scene = scene + self.layer = layer + + scene.events.resized.addObserver(self) { camera in + camera.update() + } + } + + // MARK: - ActionPerformer + + @discardableResult public func perform(_ action: Action) -> ActionToken { + return actionManager.add(action) + } + + // MARK: - Pluggable + + @discardableResult public func add(_ plugin: @autoclosure () -> P, + reuseExistingOfSameType: Bool) -> P where P.Object == Camera { + return pluginManager.add(plugin, for: self, reuseExistingOfSameType: reuseExistingOfSameType) + } + + public func plugins(ofType type: P.Type) -> [P] where P.Object == Camera { + return pluginManager.plugins(ofType: type) + } + + public func remove(_ plugin: P) where P.Object == Camera { + pluginManager.remove(plugin, from: self) + } + + public func removePlugins(ofType type: P.Type) where P.Object == Camera { + pluginManager.removePlugins(ofType: type, from: self) + } + + // MARK: - Activatable + + internal func activate(in game: Game) { + size = game.view.frame.size + pluginManager.activate(in: game) + actionManager.activate(in: game) + } + + internal func deactivate() { + pluginManager.deactivate() + actionManager.deactivate() + } + + // MARK: - Internal + + internal func handleClick(at point: Point) { + events.clicked.trigger(with: point) + } + + // MARK: - Private + + private func positionDidChange(from oldValue: Point) { + if position != oldValue { + update() + events.moved.trigger(with: (oldValue, position)) + } + } + + private func sizeDidChange(from oldValue: Size) { + if size != oldValue { + update() + events.resized.trigger() + } + } + + private func update() { + guard let scene = scene else { + return + } + + var newRect = Rect(origin: position, size: size) + newRect.origin.x -= size.width / 2 + newRect.origin.y -= size.height / 2 + rect = newRect + + if constrainedToScene { + if scene.size.width >= size.width { + guard newRect.minX >= 0 else { + position.x = size.width / 2 + return + } + + guard newRect.maxX <= scene.size.width else { + position.x = scene.size.width - size.width / 2 + return + } + } + + if scene.size.height >= size.height { + guard newRect.minY >= 0 else { + position.y = size.height / 2 + return + } + + guard newRect.maxY <= scene.size.height else { + position.y = scene.size.height - size.height / 2 + return + } + } + } + + layer.frame.origin = Point( + x: size.width / 2 - position.x, + y: size.height / 2 - position.y + ) + } +} diff --git a/ImagineEngine/Sources/Core/API/CameraEventCollection.swift b/ImagineEngine/Sources/Core/API/CameraEventCollection.swift new file mode 100644 index 0000000..f4d3d4a --- /dev/null +++ b/ImagineEngine/Sources/Core/API/CameraEventCollection.swift @@ -0,0 +1,17 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Events that can be used to observe a camera +public final class CameraEventCollection: EventCollection { + /// Event triggered when the camera was moved + public private(set) lazy var moved = Event(object: object) + /// Event triggered when the camera was resized + public private(set) lazy var resized = Event(object: object) + /// Event triggered when the camera was clicked (on macOS) or tapped (on iOS/tvOS) + public private(set) lazy var clicked = Event(object: object) +} diff --git a/ImagineEngine/Sources/Core/API/CancellationToken.swift b/ImagineEngine/Sources/Core/API/CancellationToken.swift new file mode 100644 index 0000000..1f8a1f3 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/CancellationToken.swift @@ -0,0 +1,24 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Class used to cancel an operation that takes place over time + * + * Whenever you perform an action, schedule an event on a timeline + * or do something else that will either be performed later or + * during a longer period of time, Imagine Engine returns a token + * to you that can be used to cancel that operation. + */ +public class CancellationToken: InstanceHashable { + internal private(set) var isCancelled = false + + /// Cancel the operation that this token is for + public func cancel() { + isCancelled = true + } +} diff --git a/ImagineEngine/Sources/Core/API/ClosureAction.swift b/ImagineEngine/Sources/Core/API/ClosureAction.swift new file mode 100644 index 0000000..e3e0c9d --- /dev/null +++ b/ImagineEngine/Sources/Core/API/ClosureAction.swift @@ -0,0 +1,29 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Class that can be used to implement custom actions using a closure + * + * This class provides a simple way to define your own custom actions, + * by simply using a closure that gets passed the current update context + * whenever the action is updated. + */ +public final class ClosureAction: Action { + private let closure: (UpdateContext) -> Void + + /// Initialize an instance with a given duration and a closure that will + /// be run on every update of the action. + public init(duration: TimeInterval, closure: @escaping (UpdateContext) -> Void) { + self.closure = closure + super.init(duration: duration) + } + + public override func update(with context: UpdateContext) { + closure(context) + } +} diff --git a/ImagineEngine/Sources/Core/API/Constraint.swift b/ImagineEngine/Sources/Core/API/Constraint.swift new file mode 100644 index 0000000..a52f2b5 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Constraint.swift @@ -0,0 +1,17 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Enum defining various constraints that can be applied to Imagine Engine +/// game objects, in order to restrict their movement in various ways. +public enum Constraint: Hashable { + /// Constraint the object to its scene. When this constraint it set the + /// object won't be able to leave its scene. + case scene + /// Prevent the object from overlaping a block in a given group. + case neverOverlapBlockInGroup(Group) +} diff --git a/ImagineEngine/Sources/Core/API/Coordinate.swift b/ImagineEngine/Sources/Core/API/Coordinate.swift new file mode 100644 index 0000000..837d8ff --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Coordinate.swift @@ -0,0 +1,43 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2018 + * See LICENSE file for license + */ + +import Foundation + +/// Type that can be used to express a non-fractional coordinate within a space +/// In Imagine Engine itself this is mostly used to slice sprite sheets, but you +/// can also use it in your own code for maps and other coordinate systems. +/// +/// Note on comparability: A coordinate is considered to be "lower than" another +/// when either its x or y component has a lower value than the other coordinate. +public struct Coordinate { + /// The coordinate's position on the horizontal axis + public var x: Int + /// The coordinate's position on the vertical axis + public var y: Int + + /// Initialize an instance with given x & y values + public init(x: Int = 0, y: Int = 0) { + self.x = x + self.y = y + } +} + +extension Coordinate: Comparable { + public static func ==(lhs: Coordinate, rhs: Coordinate) -> Bool { + return lhs.x == rhs.x && lhs.y == rhs.y + } + + public static func <(lhs: Coordinate, rhs: Coordinate) -> Bool { + return lhs.x < rhs.x || lhs.y < rhs.y + } +} + +public extension Coordinate { + /// A coordinate value that has both its x & y components set to 0 + static var zero: Coordinate { + return Coordinate() + } +} diff --git a/ImagineEngine/Sources/Core/API/Event.swift b/ImagineEngine/Sources/Core/API/Event.swift new file mode 100644 index 0000000..08191f2 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Event.swift @@ -0,0 +1,151 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Class that represents an event that can occur in a game + * + * You use this class to observe and trigger events that can happen + * in your game, and is the recommended way to drive most of your + * game logic. + * + * To observe an event, simply call the `observe` method on it: + * + * ``` + * actor.events.moved.observe { actor in + * print("This actor was moved: \(actor)") + * } + * ``` + * + * To define a custom event, create an extension on `EventCollection` + * that defines a computed property for your event, and simply call + * `makeEvent()` within its implementation, like this: + * + * ``` + * extension EventCollection where Object == Actor { + * var myEvent: Event { + * return makeEvent() + * } + * } + * ``` + * + * You can then trigger the event like this: + * + * ``` + * actor.events.myEvent.trigger() + * ``` + */ +public final class Event { + private weak var object: Object? + private lazy var observations = [ObservationKey : Observation]() + + // MARK: - Initializer + + internal init(object: Object?) { + self.object = object + } + + // MARK: - Public + + /// Trigger the event with a subject value + /// A subject is the object or value that the event happened with, for + /// example in a collision the subject will be the object collided with. + public func trigger(with subject: Subject) { + guard let object = object else { + return + } + + for (key, observation) in observations { + switch key { + case .objectIdentifier: + break + case .token(let token): + guard !token.isCancelled else { + observations[key] = nil + continue + } + } + + observation.closure(object, subject) + } + } + + /// Observe the event using a closure + @discardableResult public func observe(using closure: @escaping (Object, Subject) -> Void) -> EventToken { + let token = EventToken() + observations[.token(token)] = Observation(closure: closure) + return token + } + + /// Add an observer to the event, that will be passed into the observation closure + public func addObserver(_ observer: T, closure: @escaping (T, Object, Subject) -> Void) { + let identifier = ObjectIdentifier(observer) + + observations[.objectIdentifier(identifier)] = Observation { [weak self, weak observer] object, subject in + guard let observer = observer else { + self?.observations[.objectIdentifier(identifier)] = nil + return + } + + closure(observer, object, subject) + } + } + + /// Remove an observer from the event + public func removeObserver(_ observer: T) { + let identifier = ObjectIdentifier(observer) + observations[.objectIdentifier(identifier)] = nil + } +} + +public extension Event { + /// Observe the event using a closure that only gets passed the event's object + @discardableResult func observe(using closure: @escaping (Object) -> Void) -> EventToken { + return observe { object, _ in + closure(object) + } + } + + /// Observe the event using a closure that doesn't take any arguments + @discardableResult func observe(using closure: @escaping () -> Void) -> EventToken { + return observe { _, _ in + closure() + } + } + + /// Add an observer to the event using a closure that only gets passed the event's object + func addObserver(_ observer: T, closure: @escaping (T, Object) -> Void) { + addObserver(observer) { observer, object, _ in + closure(observer, object) + } + } + + /// Add an observer to the event using a closure that only gets passed the observer + func addObserver(_ observer: T, closure: @escaping (T) -> Void) { + addObserver(observer) { observer, _, _ in + closure(observer) + } + } +} + +public extension Event where Subject == Void { + /// Trigger a Void-based event without a subject + func trigger() { + trigger(with: Void()) + } +} + +private extension Event { + enum ObservationKey: Hashable { + case token(EventToken) + case objectIdentifier(ObjectIdentifier) + } + + struct Observation { + let closure: (Object, Subject) -> Void + } +} diff --git a/ImagineEngine/Sources/Core/API/EventCollection.swift b/ImagineEngine/Sources/Core/API/EventCollection.swift new file mode 100644 index 0000000..de9845f --- /dev/null +++ b/ImagineEngine/Sources/Core/API/EventCollection.swift @@ -0,0 +1,55 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Class that defines a collection of events + * + * Events are used to drive most of the game logic in an Imagine Engine + * game. Objects like Actors and Scenes define an event collection that + * both comes with built-in events, and enables you to define your own. + */ +public class EventCollection { + internal private(set) weak var object: Object? + private lazy var events = [String : AnyObject]() + + internal init(object: Object) { + self.object = object + } + + /// Make a new event with an identifier for the event's subject + /// Call this method within an extension defining a custom event. + /// For more information, see the documentation for `Event`. + public func makeEvent(named name: StaticString = #function, + withSubjectIdentifier subjectIdentifier: String) -> Event { + let name = "\(name)-\(subjectIdentifier)" + + if let event = events[name] { + // swiftlint:disable:next force_cast + return event as! Event + } + + let event = Event(object: object) + events[name] = event + return event + } + + /// Make a new event with a subject + /// Call this method within an extension defining a custom event. + /// For more information, see the documentation for `Event`. + public func makeEvent(named name: StaticString = #function, + withSubject subject: Subject) -> Event { + return makeEvent(named: name, withSubjectIdentifier: String(describing: ObjectIdentifier(subject))) + } + + /// Make a new event that is not bound to a specific subject + /// Call this method within an extension defining a custom event. + /// For more information, see the documentation for `Event`. + public func makeEvent(named name: StaticString = #function) -> Event { + return makeEvent(named: name, withSubjectIdentifier: "Void") + } +} diff --git a/ImagineEngine/Sources/Core/API/EventToken.swift b/ImagineEngine/Sources/Core/API/EventToken.swift new file mode 100644 index 0000000..cd8a14f --- /dev/null +++ b/ImagineEngine/Sources/Core/API/EventToken.swift @@ -0,0 +1,12 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Token that can be used to cancel an event observation +public final class EventToken: CancellationToken { + internal let identifier = UUID() +} diff --git a/ImagineEngine/Sources/Core/API/FadeAction.swift b/ImagineEngine/Sources/Core/API/FadeAction.swift new file mode 100644 index 0000000..c4d1341 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/FadeAction.swift @@ -0,0 +1,30 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Action that can be used to fade objects that are fadable over time +public final class FadeAction: MetricAction { + /// Initialize an instance with a target opacity & duration + public init(opacity: Metric, duration: TimeInterval) { + super.init( + mode: .target(opacity), + duration: duration, + getClosure: { $0.opacity }, + setClosure: { $0.opacity = $1 } + ) + } + + /// Initialize an instance with a delta opacity & duration + public init(delta: Metric, duration: TimeInterval) { + super.init( + mode: .delta(delta), + duration: duration, + getClosure: { $0.opacity }, + setClosure: { $0.opacity = $1 } + ) + } +} diff --git a/ImagineEngine/Sources/Core/API/Fadeable.swift b/ImagineEngine/Sources/Core/API/Fadeable.swift new file mode 100644 index 0000000..ff99517 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Fadeable.swift @@ -0,0 +1,30 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Protocol adopted by objects that can have their opacity changed +public protocol Fadeable: class { + /// The opacity of the object, ranging from 0 (invisible) - 1 (opaque) + var opacity: Metric { get set } +} + +public extension Fadeable where Self: ActionPerformer { + /// Fade in the object (to opacity = 1) with a given duration + @discardableResult func fadeIn(withDuration duration: TimeInterval) -> ActionToken { + return perform(FadeAction(opacity: 1, duration: duration)) + } + + /// Fade the object to a given opacity with a duration + @discardableResult func fade(to opacity: Metric, withDuration duration: TimeInterval) -> ActionToken { + return perform(FadeAction(opacity: opacity, duration: duration)) + } + + /// Fade out the object (to opacity = 0) with a given duration + @discardableResult func fadeOut(withDuration duration: TimeInterval) -> ActionToken { + return perform(FadeAction(opacity: 0, duration: duration)) + } +} diff --git a/ImagineEngine/Sources/Core/API/Game.swift b/ImagineEngine/Sources/Core/API/Game.swift new file mode 100644 index 0000000..2a2cffe --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Game.swift @@ -0,0 +1,90 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/** + * Class used to create an Imagine Engine game + * + * A Game is the root object any Imagine Engine game and provides a view + * that can be attached to an app's view hierarchy. To present game content + * create a `Scene` and attach it to your game. + */ +open class Game { + /// The game's view, attach it to one of your app's views to start the game + public let view: View + /// The current active scene that the game is presenting + public var scene: Scene { didSet { sceneDidChange(from: oldValue) } } + + internal private(set) var currentTime: TimeInterval + + private let displayLink: DisplayLinkProtocol + private let dateProvider: () -> Date + private var isActive = false + + // MARK: - Initializers + + /// Initialize an instance with a certain viewport size & an initial scene + public convenience init(size: Size, scene: Scene) { + let view = GameView(frame: Rect(origin: .zero, size: size)) + self.init(view: view, scene: scene, displayLink: DisplayLink()) + } + + internal init(view: GameView, + scene: Scene, + displayLink: DisplayLinkProtocol, + dateProvider: @escaping () -> Date = Date.init) { + self.view = view + self.scene = scene + self.displayLink = displayLink + self.dateProvider = dateProvider + currentTime = dateProvider().timeIntervalSinceReferenceDate + + view.game = self + sceneDidChange(from: nil) + } + + // MARK: - Internal + + internal func updateActivationStatus() { + guard view.superview != nil else { + isActive = false + return + } + + guard view.frame.size != .zero else { + isActive = false + return + } + + guard !isActive else { + return + } + + isActive = true + scene.activate(in: self) + displayLink.activate() + } + + // MARK: - Private + + private func sceneDidChange(from previousScene: Scene?) { + previousScene?.deactivate() + + if isActive { + scene.activate(in: self) + } + + displayLink.callback = { [weak self] in + guard let `self` = self else { + return + } + + self.currentTime = self.dateProvider().timeIntervalSinceReferenceDate + self.scene.timeline.update(currentTime: self.currentTime) + } + } +} diff --git a/ImagineEngine/Sources/Core/API/Group.swift b/ImagineEngine/Sources/Core/API/Group.swift new file mode 100644 index 0000000..2501767 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Group.swift @@ -0,0 +1,38 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Enum used to define logical groups that game objects can belong to +public enum Group: Hashable { + /// A group that is identified by a string-based name + case name(String) + /// A group that is identifier by a number + case number(Int) +} + +public extension Group { + /// Create a group using a member of a string-based enum + static func enumValue(_ value: R) -> Group where R.RawValue == String { + return .name(value.rawValue) + } + + /// Create a group using a member of an int-based enum + static func enumValue(_ value: R) -> Group where R.RawValue == Int { + return .number(value.rawValue) + } +} + +internal extension Group { + var identifier: String { + switch self { + case .name(let name): + return "name-\(name)" + case .number(let number): + return "number-\(number)" + } + } +} diff --git a/ImagineEngine/Sources/Core/API/InstanceHashable.swift b/ImagineEngine/Sources/Core/API/InstanceHashable.swift new file mode 100644 index 0000000..11a9ad4 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/InstanceHashable.swift @@ -0,0 +1,20 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation + +/// Protocol adopted by objects that have their hash value calculated +/// based on their instance (object) identifier +public protocol InstanceHashable: class, Hashable {} + +extension InstanceHashable { + public static func ==(lhs: Self, rhs: Self) -> Bool { + return ObjectIdentifier(lhs) == ObjectIdentifier(rhs) + } + public func hash(into hasher: inout Hasher) { + hasher.combine(ObjectIdentifier(self)) + } +} diff --git a/ImagineEngine/Sources/Core/API/Label.swift b/ImagineEngine/Sources/Core/API/Label.swift new file mode 100644 index 0000000..36a1a01 --- /dev/null +++ b/ImagineEngine/Sources/Core/API/Label.swift @@ -0,0 +1,220 @@ +/** + * Imagine Engine + * Copyright (c) John Sundell 2017 + * See LICENSE file for license + */ + +import Foundation +import QuartzCore + +/** + * Class used to render text content in a scene + * + * You can use a label to render text in a scene. It supports features like + * setting the font and text color of text and will automatically resize itself + * to fit the text you assign to it. + */ +public final class Label: Node, InstanceHashable, ActionPerformer, Pluggable, + ZIndexed, Movable, Fadeable, Rotatable, Scalable, Activatable, + GridPlaceable { + /// A collection of events that can be used to observe the label. + public private(set) lazy var events = LabelEventCollection(object: self) + /// Whether the label's text should be wrapped on multiple lines in case it doesn't fit its width. + public var shouldWrap = false { didSet { layer.isWrapped = shouldWrap } } + /// The index of the label on the z axis. Affects rendering. 0 = implicit index. + public var zIndex = 0 { didSet { layer.zPosition = Metric(zIndex) } } + /// The position of the label within its scene. + public var position = Point() { didSet { positionDidChange(from: oldValue) } } + /// The size of the label, centered on its position. + public var size = Size() { didSet { sizeDidChange(from: oldValue) } } + /// The rotation of the label along the z axis. + public var rotation = Metric() { didSet { rotationDidChange(from: oldValue) } } + /// Whether the label should automatically be resized to fit its content. + public var shouldAutoResize = true + /// The opacity of the label. Ranges from 0 (transparent) - 1 (opaque). + public var opacity = Metric(1) { didSet { layer.opacity = Float(opacity) } } + /// The text that the label is currently rendering. + public var text: String { didSet { textDidChange() } } + /// The font that the label renders its text using. + public var font: Font { didSet { fontDidChange() } } + /// The color of the text that the label is rendering. + public var textColor = Color.white { didSet { layer.foregroundColor = textColor.cgColor } } + /// The way the label's text should be laid out given excess space + public var horizontalAlignment = HorizontalAlignment.left { didSet { horizontalAlignmentDidChange() } } + /// The label's background color. Default is `.clear` (no background). + public var backgroundColor = Color.clear { didSet { layer.backgroundColor = backgroundColor.cgColor } } + /// The scale the label gets rendered at. + public var scale: Metric = 1 { didSet { scaleDidChange(from: oldValue) } } + + private lazy var actionManager = ActionManager(object: self) + private let pluginManager = PluginManager() + + // MARK: - Initializer + + /// Initialize an instance, optionally with an initial text + public init(text: String = "") { + self.text = text + font = .default + + super.init(layer: TextLayer()) + + layer.string = text + layer.contentsScale = Screen.mainScreenScale + + fontDidChange() + horizontalAlignmentDidChange() + } + + // MARK: - ActionPerformer + + @discardableResult public func perform(_ action: Action