From 8e9575b019010c6a8daa5205f03cfae502b5a45e Mon Sep 17 00:00:00 2001 From: Fumiya Yamanaka Date: Sat, 6 May 2017 18:30:55 +0900 Subject: [PATCH] Migrate to Swift 3 --- MetalParticles.xcodeproj/project.pbxproj | 10 +- .../UserInterfaceState.xcuserstate | Bin 0 -> 48890 bytes .../xcschemes/MetalParticles.xcscheme | 101 ++++++++++ .../xcschemes/xcschememanagement.plist | 27 +++ MetalParticles/AppDelegate.swift | 12 +- MetalParticles/MarkerWidget.swift | 8 +- MetalParticles/ParticleLab.swift | 174 +++++++++--------- MetalParticles/ViewController.swift | 108 +++++------ MetalParticlesTests/MetalParticlesTests.swift | 2 +- 9 files changed, 289 insertions(+), 153 deletions(-) create mode 100644 MetalParticles.xcodeproj/project.xcworkspace/xcuserdata/FumiyaYamanaka.xcuserdatad/UserInterfaceState.xcuserstate create mode 100644 MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/MetalParticles.xcscheme create mode 100644 MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/xcschememanagement.plist diff --git a/MetalParticles.xcodeproj/project.pbxproj b/MetalParticles.xcodeproj/project.pbxproj index 21c5694..45a94ac 100644 --- a/MetalParticles.xcodeproj/project.pbxproj +++ b/MetalParticles.xcodeproj/project.pbxproj @@ -206,10 +206,12 @@ TargetAttributes = { BE75EE8B1A6A2CC000B20D49 = { CreatedOnToolsVersion = 6.1.1; - DevelopmentTeam = ZBFYF9JG5V; + DevelopmentTeam = GCXLS66975; + LastSwiftMigration = 0830; }; BE75EEA01A6A2CC000B20D49 = { CreatedOnToolsVersion = 6.1.1; + LastSwiftMigration = 0830; TestTargetID = BE75EE8B1A6A2CC000B20D49; }; }; @@ -397,6 +399,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = GCXLS66975; INFOPLIST_FILE = MetalParticles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -406,6 +409,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "uk.co.flexmonkey.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -415,6 +419,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = GCXLS66975; INFOPLIST_FILE = MetalParticles/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -424,6 +429,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "uk.co.flexmonkey.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -443,6 +449,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "uk.co.flexmonkey.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MetalParticles.app/MetalParticles"; }; name = Debug; @@ -459,6 +466,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "uk.co.flexmonkey.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MetalParticles.app/MetalParticles"; }; name = Release; diff --git a/MetalParticles.xcodeproj/project.xcworkspace/xcuserdata/FumiyaYamanaka.xcuserdatad/UserInterfaceState.xcuserstate b/MetalParticles.xcodeproj/project.xcworkspace/xcuserdata/FumiyaYamanaka.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000000000000000000000000000000000000..47b63bebedec79e757dcf40ac3f967a73a01d3b1 GIT binary patch literal 48890 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 WAykO{pMcQif4A4z|1TgEs{RWl+K0mc literal 0 HcmV?d00001 diff --git a/MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/MetalParticles.xcscheme b/MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/MetalParticles.xcscheme new file mode 100644 index 0000000..1a10228 --- /dev/null +++ b/MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/MetalParticles.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/xcschememanagement.plist b/MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..da92f67 --- /dev/null +++ b/MetalParticles.xcodeproj/xcuserdata/FumiyaYamanaka.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,27 @@ + + + + + SchemeUserState + + MetalParticles.xcscheme + + orderHint + 0 + + + SuppressBuildableAutocreation + + BE75EE8B1A6A2CC000B20D49 + + primary + + + BE75EEA01A6A2CC000B20D49 + + primary + + + + + diff --git a/MetalParticles/AppDelegate.swift b/MetalParticles/AppDelegate.swift index b3751fc..37391a9 100644 --- a/MetalParticles/AppDelegate.swift +++ b/MetalParticles/AppDelegate.swift @@ -14,30 +14,30 @@ class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? - func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true } - func applicationWillResignActive(application: UIApplication) { + func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } - func applicationDidEnterBackground(application: UIApplication) { + func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } - func applicationWillEnterForeground(application: UIApplication) { + func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } - func applicationDidBecomeActive(application: UIApplication) { + func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. } - func applicationWillTerminate(application: UIApplication) { + func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } diff --git a/MetalParticles/MarkerWidget.swift b/MetalParticles/MarkerWidget.swift index d511f66..909666a 100644 --- a/MetalParticles/MarkerWidget.swift +++ b/MetalParticles/MarkerWidget.swift @@ -24,11 +24,11 @@ class Circle: CAShapeLayer { func draw() { - fillColor = UIColor.lightGrayColor().CGColor + fillColor = UIColor.lightGray.cgColor let ballRect = CGRect(x: -10, y: -10, width: 20, height: 20) - let ballPath = UIBezierPath(ovalInRect: ballRect) + let ballPath = UIBezierPath(ovalIn: ballRect) - path = ballPath.CGPath + path = ballPath.cgPath } -} \ No newline at end of file +} diff --git a/MetalParticles/ParticleLab.swift b/MetalParticles/ParticleLab.swift index c775ace..8fc422a 100644 --- a/MetalParticles/ParticleLab.swift +++ b/MetalParticles/ParticleLab.swift @@ -28,38 +28,38 @@ class ParticleLab: MTKView let imageWidth: UInt let imageHeight: UInt - private var imageWidthFloatBuffer: MTLBuffer! - private var imageHeightFloatBuffer: MTLBuffer! + fileprivate var imageWidthFloatBuffer: MTLBuffer! + fileprivate var imageHeightFloatBuffer: MTLBuffer! let bytesPerRow: UInt let region: MTLRegion let blankBitmapRawData : [UInt8] - private var kernelFunction: MTLFunction! - private var pipelineState: MTLComputePipelineState! - private var defaultLibrary: MTLLibrary! = nil - private var commandQueue: MTLCommandQueue! = nil + fileprivate var kernelFunction: MTLFunction! + fileprivate var pipelineState: MTLComputePipelineState! + fileprivate var defaultLibrary: MTLLibrary! = nil + fileprivate var commandQueue: MTLCommandQueue! = nil - private var threadsPerThreadgroup:MTLSize! - private var threadgroupsPerGrid:MTLSize! + fileprivate var threadsPerThreadgroup:MTLSize! + fileprivate var threadgroupsPerGrid:MTLSize! let particleCount: Int let alignment:Int = 0x4000 let particlesMemoryByteSize:Int - private var particlesMemory:UnsafeMutablePointer = nil - private var particlesVoidPtr: COpaquePointer! - private var particlesParticlePtr: UnsafeMutablePointer! - private var particlesParticleBufferPtr: UnsafeMutableBufferPointer! + fileprivate var particlesMemory:UnsafeMutableRawPointer? = nil + fileprivate var particlesVoidPtr: OpaquePointer! + fileprivate var particlesParticlePtr: UnsafeMutablePointer! + fileprivate var particlesParticleBufferPtr: UnsafeMutableBufferPointer! - private var gravityWellParticle = Particle(A: Vector4(x: 0, y: 0, z: 0, w: 0), + fileprivate var gravityWellParticle = Particle(A: Vector4(x: 0, y: 0, z: 0, w: 0), B: Vector4(x: 0, y: 0, z: 0, w: 0), C: Vector4(x: 0, y: 0, z: 0, w: 0), D: Vector4(x: 0, y: 0, z: 0, w: 0)) - private var frameStartTime: CFAbsoluteTime! - private var frameNumber = 0 - let particleSize = sizeof(Particle) + fileprivate var frameStartTime: CFAbsoluteTime! + fileprivate var frameNumber = 0 + let particleSize = MemoryLayout.size weak var particleLabDelegate: ParticleLabDelegate? @@ -94,17 +94,17 @@ class ParticleLab: MTKView bytesPerRow = 4 * imageWidth region = MTLRegionMake2D(0, 0, Int(imageWidth), Int(imageHeight)) - blankBitmapRawData = [UInt8](count: Int(imageWidth * imageHeight * 4), repeatedValue: 0) - particlesMemoryByteSize = particleCount * sizeof(Particle) + blankBitmapRawData = [UInt8](repeating: 0, count: Int(imageWidth * imageHeight * 4)) + particlesMemoryByteSize = particleCount * MemoryLayout.size - let formatter = NSNumberFormatter() + let formatter = NumberFormatter() formatter.usesGroupingSeparator = true - formatter.numberStyle = NSNumberFormatterStyle.DecimalStyle + formatter.numberStyle = NumberFormatter.Style.decimal - statusPrefix = formatter.stringFromNumber(numParticles.rawValue * 4)! + " Particles" + statusPrefix = formatter.string(from: NSNumber(value: numParticles.rawValue * 4))! + " Particles" - let frameWidth = hiDPI ? width / UInt(UIScreen.mainScreen().scale) : width - let frameHeight = hiDPI ? height / UInt(UIScreen.mainScreen().scale) : height + let frameWidth = hiDPI ? width / UInt(UIScreen.main.scale) : width + let frameHeight = hiDPI ? height / UInt(UIScreen.main.scale) : height super.init(frame: CGRect(x: 0, y: 0, width: Int(frameWidth), height: Int(frameHeight)), device: MTLCreateSystemDefaultDevice()) @@ -115,7 +115,7 @@ class ParticleLab: MTKView setUpMetal() - multipleTouchEnabled = true + isMultipleTouchEnabled = true } required init(coder: NSCoder) @@ -129,11 +129,11 @@ class ParticleLab: MTKView free(particlesMemory) } - private func setUpParticles() + fileprivate func setUpParticles() { posix_memalign(&particlesMemory, alignment, particlesMemoryByteSize) - particlesVoidPtr = COpaquePointer(particlesMemory) + particlesVoidPtr = OpaquePointer(particlesMemory) particlesParticlePtr = UnsafeMutablePointer(particlesVoidPtr) particlesParticleBufferPtr = UnsafeMutableBufferPointer(start: particlesParticlePtr, count: particleCount) @@ -142,13 +142,13 @@ class ParticleLab: MTKView func resetGravityWells() { - setGravityWellProperties(gravityWell: .One, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) - setGravityWellProperties(gravityWell: .Two, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) - setGravityWellProperties(gravityWell: .Three, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) - setGravityWellProperties(gravityWell: .Four, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) + setGravityWellProperties(gravityWell: .one, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) + setGravityWellProperties(gravityWell: .two, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) + setGravityWellProperties(gravityWell: .three, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) + setGravityWellProperties(gravityWell: .four, normalisedPositionX: 0.5, normalisedPositionY: 0.5, mass: 0, spin: 0) } - func resetParticles(edgesOnly: Bool = false) + func resetParticles(_ edgesOnly: Bool = false) { func rand() -> Float32 { @@ -215,7 +215,7 @@ class ParticleLab: MTKView } } - private func setUpMetal() + fileprivate func setUpMetal() { device = MTLCreateSystemDefaultDevice() @@ -227,13 +227,13 @@ class ParticleLab: MTKView } defaultLibrary = device.newDefaultLibrary() - commandQueue = device.newCommandQueue() + commandQueue = device.makeCommandQueue() - kernelFunction = defaultLibrary.newFunctionWithName("particleRendererShader") + kernelFunction = defaultLibrary.makeFunction(name: "particleRendererShader") do { - try pipelineState = device.newComputePipelineStateWithFunction(kernelFunction!) + try pipelineState = device.makeComputePipelineState(function: kernelFunction!) } catch { @@ -250,12 +250,12 @@ class ParticleLab: MTKView var imageWidthFloat = Float(imageWidth) var imageHeightFloat = Float(imageHeight) - imageWidthFloatBuffer = device.newBufferWithBytes(&imageWidthFloat, length: sizeof(Float), options: MTLResourceOptions.CPUCacheModeDefaultCache) + imageWidthFloatBuffer = device.makeBuffer(bytes: &imageWidthFloat, length: MemoryLayout.size, options: MTLResourceOptions()) - imageHeightFloatBuffer = device.newBufferWithBytes(&imageHeightFloat, length: sizeof(Float), options: MTLResourceOptions.CPUCacheModeDefaultCache) + imageHeightFloatBuffer = device.makeBuffer(bytes: &imageHeightFloat, length: MemoryLayout.size, options: MTLResourceOptions()) } - override func drawRect(dirtyRect: CGRect) + override func draw(_ dirtyRect: CGRect) { guard let device = device else { @@ -277,31 +277,31 @@ class ParticleLab: MTKView frameNumber = 0 } - let commandBuffer = commandQueue.commandBuffer() - let commandEncoder = commandBuffer.computeCommandEncoder() + let commandBuffer = commandQueue.makeCommandBuffer() + let commandEncoder = commandBuffer.makeComputeCommandEncoder() commandEncoder.setComputePipelineState(pipelineState) - let particlesBufferNoCopy = device.newBufferWithBytesNoCopy(particlesMemory, length: Int(particlesMemoryByteSize), - options: MTLResourceOptions.CPUCacheModeDefaultCache, deallocator: nil) + let particlesBufferNoCopy = device.makeBuffer(bytesNoCopy: particlesMemory!, length: Int(particlesMemoryByteSize), + options: MTLResourceOptions(), deallocator: nil) - commandEncoder.setBuffer(particlesBufferNoCopy, offset: 0, atIndex: 0) - commandEncoder.setBuffer(particlesBufferNoCopy, offset: 0, atIndex: 1) + commandEncoder.setBuffer(particlesBufferNoCopy, offset: 0, at: 0) + commandEncoder.setBuffer(particlesBufferNoCopy, offset: 0, at: 1) - let inGravityWell = device.newBufferWithBytes(&gravityWellParticle, length: particleSize, options: MTLResourceOptions.CPUCacheModeDefaultCache) - commandEncoder.setBuffer(inGravityWell, offset: 0, atIndex: 2) + let inGravityWell = device.makeBuffer(bytes: &gravityWellParticle, length: particleSize, options: MTLResourceOptions()) + commandEncoder.setBuffer(inGravityWell, offset: 0, at: 2) - let colorBuffer = device.newBufferWithBytes(&particleColor, length: sizeof(ParticleColor), options: MTLResourceOptions.CPUCacheModeDefaultCache) - commandEncoder.setBuffer(colorBuffer, offset: 0, atIndex: 3) + let colorBuffer = device.makeBuffer(bytes: &particleColor, length: MemoryLayout.size, options: MTLResourceOptions()) + commandEncoder.setBuffer(colorBuffer, offset: 0, at: 3) - commandEncoder.setBuffer(imageWidthFloatBuffer, offset: 0, atIndex: 4) - commandEncoder.setBuffer(imageHeightFloatBuffer, offset: 0, atIndex: 5) + commandEncoder.setBuffer(imageWidthFloatBuffer, offset: 0, at: 4) + commandEncoder.setBuffer(imageHeightFloatBuffer, offset: 0, at: 5) - let dragFactorBuffer = device.newBufferWithBytes(&dragFactor, length: sizeof(Float), options: MTLResourceOptions.CPUCacheModeDefaultCache) - commandEncoder.setBuffer(dragFactorBuffer, offset: 0, atIndex: 6) + let dragFactorBuffer = device.makeBuffer(bytes: &dragFactor, length: MemoryLayout.size, options: MTLResourceOptions()) + commandEncoder.setBuffer(dragFactorBuffer, offset: 0, at: 6) - let respawnOutOfBoundsParticlesBuffer = device.newBufferWithBytes(&respawnOutOfBoundsParticles, length: sizeof(Bool), options: MTLResourceOptions.CPUCacheModeDefaultCache) - commandEncoder.setBuffer(respawnOutOfBoundsParticlesBuffer, offset: 0, atIndex: 7) + let respawnOutOfBoundsParticlesBuffer = device.makeBuffer(bytes: &respawnOutOfBoundsParticles, length: MemoryLayout.size, options: MTLResourceOptions()) + commandEncoder.setBuffer(respawnOutOfBoundsParticlesBuffer, offset: 0, at: 7) guard let drawable = currentDrawable else { @@ -314,14 +314,14 @@ class ParticleLab: MTKView if clearOnStep { - drawable.texture.replaceRegion(self.region, + drawable.texture.replace(region: self.region, mipmapLevel: 0, withBytes: blankBitmapRawData, bytesPerRow: Int(bytesPerRow)) } - commandEncoder.setTexture(drawable.texture, atIndex: 0) + commandEncoder.setTexture(drawable.texture, at: 0) commandEncoder.dispatchThreadgroups(threadgroupsPerGrid, threadsPerThreadgroup: threadsPerThreadgroup) @@ -329,14 +329,14 @@ class ParticleLab: MTKView if !clearOnStep { - let inPlaceTexture = UnsafeMutablePointer.alloc(1) - inPlaceTexture.initialize(drawable.texture) + let inPlaceTexture = UnsafeMutablePointer.allocate(capacity: 1) + inPlaceTexture.initialize(to: drawable.texture) - blur.encodeToCommandBuffer(commandBuffer, + blur.encode(commandBuffer: commandBuffer, inPlaceTexture: inPlaceTexture, fallbackCopyAllocator: nil) - erode.encodeToCommandBuffer(commandBuffer, + erode.encode(commandBuffer: commandBuffer, inPlaceTexture: inPlaceTexture, fallbackCopyAllocator: nil) } @@ -348,7 +348,7 @@ class ParticleLab: MTKView particleLabDelegate?.particleLabDidUpdate(statusPrefix + statusPostix) } - final func getGravityWellNormalisedPosition(gravityWell gravityWell: GravityWell) -> (x: Float, y: Float) + final func getGravityWellNormalisedPosition(gravityWell: GravityWell) -> (x: Float, y: Float) { let returnPoint: (x: Float, y: Float) @@ -357,66 +357,66 @@ class ParticleLab: MTKView switch gravityWell { - case .One: + case .one: returnPoint = (x: gravityWellParticle.A.x / imageWidthFloat, y: gravityWellParticle.A.y / imageHeightFloat) - case .Two: + case .two: returnPoint = (x: gravityWellParticle.B.x / imageWidthFloat, y: gravityWellParticle.B.y / imageHeightFloat) - case .Three: + case .three: returnPoint = (x: gravityWellParticle.C.x / imageWidthFloat, y: gravityWellParticle.C.y / imageHeightFloat) - case .Four: + case .four: returnPoint = (x: gravityWellParticle.D.x / imageWidthFloat, y: gravityWellParticle.D.y / imageHeightFloat) } return returnPoint } - final func setGravityWellProperties(gravityWellIndex gravityWellIndex: Int, normalisedPositionX: Float, normalisedPositionY: Float, mass: Float, spin: Float) + final func setGravityWellProperties(gravityWellIndex: Int, normalisedPositionX: Float, normalisedPositionY: Float, mass: Float, spin: Float) { switch gravityWellIndex { case 1: - setGravityWellProperties(gravityWell: .Two, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) + setGravityWellProperties(gravityWell: .two, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) case 2: - setGravityWellProperties(gravityWell: .Three, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) + setGravityWellProperties(gravityWell: .three, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) case 3: - setGravityWellProperties(gravityWell: .Four, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) + setGravityWellProperties(gravityWell: .four, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) default: - setGravityWellProperties(gravityWell: .One, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) + setGravityWellProperties(gravityWell: .one, normalisedPositionX: normalisedPositionX, normalisedPositionY: normalisedPositionY, mass: mass, spin: spin) } } - final func setGravityWellProperties(gravityWell gravityWell: GravityWell, normalisedPositionX: Float, normalisedPositionY: Float, mass: Float, spin: Float) + final func setGravityWellProperties(gravityWell: GravityWell, normalisedPositionX: Float, normalisedPositionY: Float, mass: Float, spin: Float) { let imageWidthFloat = Float(imageWidth) let imageHeightFloat = Float(imageHeight) switch gravityWell { - case .One: + case .one: gravityWellParticle.A.x = imageWidthFloat * normalisedPositionX gravityWellParticle.A.y = imageHeightFloat * normalisedPositionY gravityWellParticle.A.z = mass gravityWellParticle.A.w = spin - case .Two: + case .two: gravityWellParticle.B.x = imageWidthFloat * normalisedPositionX gravityWellParticle.B.y = imageHeightFloat * normalisedPositionY gravityWellParticle.B.z = mass gravityWellParticle.B.w = spin - case .Three: + case .three: gravityWellParticle.C.x = imageWidthFloat * normalisedPositionX gravityWellParticle.C.y = imageHeightFloat * normalisedPositionY gravityWellParticle.C.z = mass gravityWellParticle.C.w = spin - case .Four: + case .four: gravityWellParticle.D.x = imageWidthFloat * normalisedPositionX gravityWellParticle.D.y = imageHeightFloat * normalisedPositionY gravityWellParticle.D.z = mass @@ -427,29 +427,29 @@ class ParticleLab: MTKView protocol ParticleLabDelegate: NSObjectProtocol { - func particleLabDidUpdate(status: String) + func particleLabDidUpdate(_ status: String) func particleLabMetalUnavailable() } enum GravityWell { - case One - case Two - case Three - case Four + case one + case two + case three + case four } // Since each Particle instance defines four particles, the visible particle count // in the API is four times the number we need to create. enum ParticleCount: Int { - case QtrMillion = 65_536 - case HalfMillion = 131_072 - case OneMillion = 262_144 - case TwoMillion = 524_288 - case FourMillion = 1_048_576 - case EightMillion = 2_097_152 - case SixteenMillion = 4_194_304 + case qtrMillion = 65_536 + case halfMillion = 131_072 + case oneMillion = 262_144 + case twoMillion = 524_288 + case fourMillion = 1_048_576 + case eightMillion = 2_097_152 + case sixteenMillion = 4_194_304 } // Paticles are split into three classes. The supplied particle color defines one diff --git a/MetalParticles/ViewController.swift b/MetalParticles/ViewController.swift index c078c8c..ebe0469 100644 --- a/MetalParticles/ViewController.swift +++ b/MetalParticles/ViewController.swift @@ -46,16 +46,16 @@ class ViewController: UIViewController, ParticleLabDelegate { super.viewDidLoad() - view.backgroundColor = UIColor.blackColor() + view.backgroundColor = UIColor.black - print(UIScreen.mainScreen().scale) + print(UIScreen.main.scale) - let numParticles = ParticleCount.EightMillion + let numParticles = ParticleCount.eightMillion if hiDPI { - particleLab = ParticleLab(width: UInt(view.frame.width * UIScreen.mainScreen().scale), - height: UInt(view.frame.height * UIScreen.mainScreen().scale), + particleLab = ParticleLab(width: UInt(view.frame.width * UIScreen.main.scale), + height: UInt(view.frame.height * UIScreen.main.scale), numParticles: numParticles, hiDPI: true) } @@ -79,19 +79,19 @@ class ViewController: UIViewController, ParticleLabDelegate view.addSubview(particleLab) - menuButton.layer.borderColor = UIColor.lightGrayColor().CGColor + menuButton.layer.borderColor = UIColor.lightGray.cgColor menuButton.layer.borderWidth = 1 menuButton.layer.cornerRadius = 5 - menuButton.layer.backgroundColor = UIColor.darkGrayColor().CGColor + menuButton.layer.backgroundColor = UIColor.darkGray.cgColor menuButton.showsTouchWhenHighlighted = true - menuButton.imageView?.contentMode = UIViewContentMode.ScaleAspectFit - menuButton.setImage(UIImage(named: "hamburger.png"), forState: UIControlState.Normal) - menuButton.addTarget(self, action: #selector(ViewController.displayCallout), forControlEvents: UIControlEvents.TouchDown) + menuButton.imageView?.contentMode = UIViewContentMode.scaleAspectFit + menuButton.setImage(UIImage(named: "hamburger.png"), for: UIControlState()) + menuButton.addTarget(self, action: #selector(ViewController.displayCallout), for: UIControlEvents.touchDown) view.addSubview(menuButton) statusLabel.text = "http://flexmonkey.blogspot.co.uk" - statusLabel.textColor = UIColor.darkGrayColor() + statusLabel.textColor = UIColor.darkGray view.addSubview(statusLabel) } @@ -99,9 +99,9 @@ class ViewController: UIViewController, ParticleLabDelegate override func viewDidLayoutSubviews() { statusLabel.frame = CGRect(x: 5, - y: view.frame.height - statusLabel.intrinsicContentSize().height, + y: view.frame.height - statusLabel.intrinsicContentSize.height, width: view.frame.width, - height: statusLabel.intrinsicContentSize().height) + height: statusLabel.intrinsicContentSize.height) menuButton.frame = CGRect(x: view.frame.width - 35, y: view.frame.height - 35, @@ -114,25 +114,25 @@ class ViewController: UIViewController, ParticleLabDelegate // handle metal unavailable here } - override func touchesBegan(touches: Set, withEvent event: UIEvent?) + override func touchesBegan(_ touches: Set, with event: UIEvent?) { currentTouches = currentTouches.union(touches) } - override func touchesEnded(touches: Set, withEvent event: UIEvent?) + override func touchesEnded(_ touches: Set, with event: UIEvent?) { - currentTouches = currentTouches.subtract(touches) + currentTouches = currentTouches.subtracting(touches) } func displayCallout() { - let alertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet) + let alertController = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertControllerStyle.actionSheet) - let cloudChamberAction = UIAlertAction(title: DemoModes.cloudChamber.rawValue, style: UIAlertActionStyle.Default, handler: calloutActionHandler) - let orbitsAction = UIAlertAction(title: DemoModes.orbits.rawValue, style: UIAlertActionStyle.Default, handler: calloutActionHandler) - let multiTouchAction = UIAlertAction(title: DemoModes.multiTouch.rawValue, style: UIAlertActionStyle.Default, handler: calloutActionHandler) - let respawnAction = UIAlertAction(title: DemoModes.respawn.rawValue, style: UIAlertActionStyle.Default, handler: calloutActionHandler) - let iPadProAction = UIAlertAction(title: DemoModes.iPadProDemo.rawValue, style: UIAlertActionStyle.Default, handler: calloutActionHandler) + let cloudChamberAction = UIAlertAction(title: DemoModes.cloudChamber.rawValue, style: UIAlertActionStyle.default, handler: calloutActionHandler) + let orbitsAction = UIAlertAction(title: DemoModes.orbits.rawValue, style: UIAlertActionStyle.default, handler: calloutActionHandler) + let multiTouchAction = UIAlertAction(title: DemoModes.multiTouch.rawValue, style: UIAlertActionStyle.default, handler: calloutActionHandler) + let respawnAction = UIAlertAction(title: DemoModes.respawn.rawValue, style: UIAlertActionStyle.default, handler: calloutActionHandler) + let iPadProAction = UIAlertAction(title: DemoModes.iPadProDemo.rawValue, style: UIAlertActionStyle.default, handler: calloutActionHandler) alertController.addAction(cloudChamberAction) alertController.addAction(orbitsAction) @@ -149,12 +149,12 @@ class ViewController: UIViewController, ParticleLabDelegate popoverPresentationController.sourceView = view } - particleLab.paused = true + particleLab.isPaused = true - presentViewController(alertController, animated: true, completion: {self.particleLab.paused = false}) + present(alertController, animated: true, completion: {self.particleLab.isPaused = false}) } - func calloutActionHandler(value: UIAlertAction!) -> Void + func calloutActionHandler(_ value: UIAlertAction!) -> Void { demoMode = DemoModes(rawValue: value.title!) ?? DemoModes.iPadProDemo @@ -192,7 +192,7 @@ class ViewController: UIViewController, ParticleLabDelegate } } - func particleLabDidUpdate(status: String) + func particleLabDidUpdate(_ status: String) { statusLabel.text = "http://flexmonkey.blogspot.co.uk | " + status @@ -221,13 +221,13 @@ class ViewController: UIViewController, ParticleLabDelegate { gravityWellAngle = gravityWellAngle + 0.02 - particleLab.setGravityWellProperties(gravityWell: .One, + particleLab.setGravityWellProperties(gravityWell: .one, normalisedPositionX: 0.5 + 0.45 * sin(gravityWellAngle), normalisedPositionY: 0.5 + 0.15 * cos(gravityWellAngle), mass: 14, spin: 16) - particleLab.setGravityWellProperties(gravityWell: .Two, + particleLab.setGravityWellProperties(gravityWell: .two, normalisedPositionX: 0.5 + 0.25 * cos(gravityWellAngle * 1.3), normalisedPositionY: 0.5 + 0.6 * sin(gravityWellAngle * 1.3), mass: 8, @@ -239,15 +239,15 @@ class ViewController: UIViewController, ParticleLabDelegate { let currentTouchesArray = Array(currentTouches) - for (i, currentTouch) in currentTouchesArray.enumerate() where i < 4 + for (i, currentTouch) in currentTouchesArray.enumerated() where i < 4 { let touchMultiplier = currentTouch.force == 0 && currentTouch.maximumPossibleForce == 0 ? 1 : Float(currentTouch.force / currentTouch.maximumPossibleForce) particleLab.setGravityWellProperties(gravityWellIndex: i, - normalisedPositionX: Float(currentTouch.locationInView(view).x / view.frame.width) , - normalisedPositionY: Float(currentTouch.locationInView(view).y / view.frame.height), + normalisedPositionX: Float(currentTouch.location(in: view).x / view.frame.width) , + normalisedPositionY: Float(currentTouch.location(in: view).y / view.frame.height), mass: 40 * touchMultiplier, spin: 20 * touchMultiplier) } @@ -267,28 +267,28 @@ class ViewController: UIViewController, ParticleLabDelegate { gravityWellAngle = gravityWellAngle + 0.004 - particleLab.setGravityWellProperties(gravityWell: .One, + particleLab.setGravityWellProperties(gravityWell: .one, normalisedPositionX: 0.5 + 0.1 * sin(gravityWellAngle + floatPi * 0.5), normalisedPositionY: 0.5 + 0.1 * cos(gravityWellAngle + floatPi * 0.5), mass: 11 * sin(gravityWellAngle / 1.8), spin: 23 * cos(gravityWellAngle / 2.1)) - particleLab.setGravityWellProperties(gravityWell: .Two, + particleLab.setGravityWellProperties(gravityWell: .two, normalisedPositionX: 0.5 + 0.1 * sin(gravityWellAngle + floatPi * 1.5), normalisedPositionY: 0.5 + 0.1 * cos(gravityWellAngle + floatPi * 1.5), mass: 11 * sin(gravityWellAngle / 0.9), spin: 23 * cos(gravityWellAngle / 1.05)) - particleLab.setGravityWellProperties(gravityWell: .Three, + particleLab.setGravityWellProperties(gravityWell: .three, normalisedPositionX: 0.5 + (0.35 + sin(gravityWellAngle * 2.7)) * cos(gravityWellAngle / 1.3), normalisedPositionY: 0.5 + (0.35 + sin(gravityWellAngle * 2.7)) * sin(gravityWellAngle / 1.3), mass: 13, spin: 19 * sin(gravityWellAngle * 1.75)) - let particleOnePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .One) - let particleTwoPosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .Two) - let particleThreePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .Three) + let particleOnePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .one) + let particleTwoPosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .two) + let particleThreePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .three) - particleLab.setGravityWellProperties(gravityWell: .Four, + particleLab.setGravityWellProperties(gravityWell: .four, normalisedPositionX: (particleOnePosition.x + particleTwoPosition.x + particleThreePosition.x) / 3 + 0.03 * sin(gravityWellAngle), normalisedPositionY: (particleOnePosition.y + particleTwoPosition.y + particleThreePosition.y) / 3 + 0.03 * cos(gravityWellAngle), mass: 8 , @@ -299,31 +299,31 @@ class ViewController: UIViewController, ParticleLabDelegate { gravityWellAngle = gravityWellAngle + 0.0015 - particleLab.setGravityWellProperties(gravityWell: .One, + particleLab.setGravityWellProperties(gravityWell: .one, normalisedPositionX: 0.5 + 0.006 * cos(gravityWellAngle * 43), normalisedPositionY: 0.5 + 0.006 * sin(gravityWellAngle * 43), mass: 10, spin: 24) - let particleOnePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .One) + let particleOnePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .one) - particleLab.setGravityWellProperties(gravityWell: .Two, + particleLab.setGravityWellProperties(gravityWell: .two, normalisedPositionX: particleOnePosition.x + 0.3 * sin(gravityWellAngle * 5), normalisedPositionY: particleOnePosition.y + 0.3 * cos(gravityWellAngle * 5), mass: 4, spin: 18) - let particleTwoPosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .Two) + let particleTwoPosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .two) - particleLab.setGravityWellProperties(gravityWell: .Three, + particleLab.setGravityWellProperties(gravityWell: .three, normalisedPositionX: particleTwoPosition.x + 0.1 * cos(gravityWellAngle * 23), normalisedPositionY: particleTwoPosition.y + 0.1 * sin(gravityWellAngle * 23), mass: 6, spin: 17) - let particleThreePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .Three) + let particleThreePosition = particleLab.getGravityWellNormalisedPosition(gravityWell: .three) - particleLab.setGravityWellProperties(gravityWell: .Four, + particleLab.setGravityWellProperties(gravityWell: .four, normalisedPositionX: particleThreePosition.x + 0.03 * sin(gravityWellAngle * 37), normalisedPositionY: particleThreePosition.y + 0.03 * cos(gravityWellAngle * 37), mass: 8, @@ -334,39 +334,39 @@ class ViewController: UIViewController, ParticleLabDelegate { gravityWellAngle = gravityWellAngle + 0.02 - particleLab.setGravityWellProperties(gravityWell: .One, + particleLab.setGravityWellProperties(gravityWell: .one, normalisedPositionX: 0.5 + 0.1 * sin(gravityWellAngle + floatPi * 0.5), normalisedPositionY: 0.5 + 0.1 * cos(gravityWellAngle + floatPi * 0.5), mass: 11 * sin(gravityWellAngle / 1.9), spin: 23 * cos(gravityWellAngle / 2.1)) - particleLab.setGravityWellProperties(gravityWell: .Four, + particleLab.setGravityWellProperties(gravityWell: .four, normalisedPositionX: 0.5 + 0.1 * sin(gravityWellAngle + floatPi * 1.5), normalisedPositionY: 0.5 + 0.1 * cos(gravityWellAngle + floatPi * 1.5), mass: 11 * sin(gravityWellAngle / 1.9), spin: 23 * cos(gravityWellAngle / 2.1)) - particleLab.setGravityWellProperties(gravityWell: .Two, + particleLab.setGravityWellProperties(gravityWell: .two, normalisedPositionX: 0.5 + (0.35 + sin(gravityWellAngle * 2.7)) * cos(gravityWellAngle / 1.3), normalisedPositionY: 0.5 + (0.35 + sin(gravityWellAngle * 2.7)) * sin(gravityWellAngle / 1.3), mass: 26, spin: -19 * sin(gravityWellAngle * 1.5)) - particleLab.setGravityWellProperties(gravityWell: .Three, + particleLab.setGravityWellProperties(gravityWell: .three, normalisedPositionX: 0.5 + (0.35 + sin(gravityWellAngle * 2.7)) * cos(gravityWellAngle / 1.3 + floatPi), normalisedPositionY: 0.5 + (0.35 + sin(gravityWellAngle * 2.7)) * sin(gravityWellAngle / 1.3 + floatPi), mass: 26, spin: -19 * sin(gravityWellAngle * 1.5)) } - override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask + override var supportedInterfaceOrientations : UIInterfaceOrientationMask { - return UIInterfaceOrientationMask.Landscape + return UIInterfaceOrientationMask.landscape } - override func preferredStatusBarStyle() -> UIStatusBarStyle + override var preferredStatusBarStyle : UIStatusBarStyle { - return UIStatusBarStyle.LightContent + return UIStatusBarStyle.lightContent } override func didReceiveMemoryWarning() @@ -375,7 +375,7 @@ class ViewController: UIViewController, ParticleLabDelegate // Dispose of any resources that can be recreated. } - override func prefersStatusBarHidden() -> Bool + override var prefersStatusBarHidden : Bool { return true } diff --git a/MetalParticlesTests/MetalParticlesTests.swift b/MetalParticlesTests/MetalParticlesTests.swift index 2c67dd4..c893803 100644 --- a/MetalParticlesTests/MetalParticlesTests.swift +++ b/MetalParticlesTests/MetalParticlesTests.swift @@ -28,7 +28,7 @@ class MetalParticlesTests: XCTestCase { func testPerformanceExample() { // This is an example of a performance test case. - self.measureBlock() { + self.measure() { // Put the code you want to measure the time of here. } }