Skip to content

Commit

Permalink
Optimize settings
Browse files Browse the repository at this point in the history
  • Loading branch information
BarredEwe committed Dec 9, 2024
1 parent 706b96a commit 3d4b82a
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 63 deletions.
35 changes: 20 additions & 15 deletions SnowfallApp/Common/MenuBarSettings.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import SwiftUI

struct MenuBarSettings: View {
@State var speed: ClosedRange<Float> = Settings.snowflakeSpeedRange
@State var size: ClosedRange<Float> = Settings.snowflakeSizeRange
@State var maxSnowflakes: Float = Float(Settings.maxSnowflakes)
@State var windowInteraction: Bool = Settings.windowInteraction
@State var windStrength: Float = Settings.windStrength * 1000
@State var speed: ClosedRange<Float> = Settings.shared.snowflakeSpeedRange
@State var size: ClosedRange<Float> = Settings.shared.snowflakeSizeRange
@State var maxSnowflakes: Float = Float(Settings.shared.maxSnowflakes)
@State var windowInteraction: Bool = Settings.shared.windowInteraction
@State var windStrength: Float = Settings.shared.windStrength * 1000

var body: some View {
VStack(alignment: .leading, spacing: 12) {
Expand Down Expand Up @@ -45,30 +45,35 @@ struct MenuBarSettings: View {

Button("Reset", role: .destructive) {
Settings.reset()
speed = Settings.snowflakeSpeedRange
size = Settings.snowflakeSizeRange
maxSnowflakes = Float(Settings.maxSnowflakes)
windowInteraction = Settings.windowInteraction
windStrength = Settings.windStrength * 1000
speed = Settings.shared.snowflakeSpeedRange
size = Settings.shared.snowflakeSizeRange
maxSnowflakes = Float(Settings.shared.maxSnowflakes)
windowInteraction = Settings.shared.windowInteraction
windStrength = Settings.shared.windStrength * 1000
}
}
}
.frame(maxWidth: 250)
.padding()
.onChange(of: speed) { _, newValue in
Settings.snowflakeSpeedRange = newValue
Settings.shared.snowflakeSpeedRange = newValue
Settings.save()
}
.onChange(of: size) { _, newValue in
Settings.snowflakeSizeRange = newValue
Settings.shared.snowflakeSizeRange = newValue
Settings.save()
}
.onChange(of: maxSnowflakes) { _, newValue in
Settings.maxSnowflakes = Int(newValue)
Settings.shared.maxSnowflakes = Int(newValue)
Settings.save()
}
.onChange(of: windowInteraction) { _, newValue in
Settings.windowInteraction = newValue
Settings.shared.windowInteraction = newValue
Settings.save()
}
.onChange(of: windStrength) { _, newValue in
Settings.windStrength = newValue / 1000
Settings.shared.windStrength = newValue / 1000
Settings.save()
}
}
}
Expand Down
54 changes: 20 additions & 34 deletions SnowfallApp/Common/Settings.swift
Original file line number Diff line number Diff line change
@@ -1,47 +1,33 @@
import Cocoa
import SwiftUI

struct Settings {
@AppStorage("snowflakeSizeRange")
static var snowflakeSizeRange: ClosedRange<Float> = 3...13
@AppStorage("maxSnowflakes")
static var maxSnowflakes = 1000
@AppStorage("snowflakeSpeedRange")
static var snowflakeSpeedRange: ClosedRange<Float> = 1...3
@AppStorage("windStrength")
static var windStrength: Float = 2.5
@AppStorage("semltingSpeed")
static var semltingSpeed: Float = 0.05
@AppStorage("windowInteraction")
static var windowInteraction: Bool = true
class Settings: Codable {

static func reset() {
UserDefaults.standard.dictionaryRepresentation().keys.forEach({ UserDefaults.standard.removeObject(forKey: $0) })
}
}
static var shared = Settings()

var snowflakeSizeRange: ClosedRange<Float> = 3...13
var maxSnowflakes = 1000
var snowflakeSpeedRange: ClosedRange<Float> = 1...3
var windStrength: Float = 2.5
var semltingSpeed: Float = 0.05
var windowInteraction: Bool = true

// MARK: - Extensions
private init() {}

extension Float: @retroactive RawRepresentable {
public var rawValue: String {
String(self)
static func reset() {
UserDefaults.standard.dictionaryRepresentation().keys.forEach({ UserDefaults.standard.removeObject(forKey: $0) })
load()
}

public typealias RawValue = String

public init?(rawValue: String) {
self = Float(rawValue)!
static func save() {
if let data = try? JSONEncoder().encode(shared) {
UserDefaults().set(data, forKey: "settings")
}
}
}

extension ClosedRange: @retroactive RawRepresentable where Bound == Float {
public init?(rawValue: String) {
let split = rawValue.split(separator: "...")
static func load() {
let settings = UserDefaults().data(forKey: "settings").flatMap({ try? JSONDecoder().decode(Settings.self, from: $0) })
shared = settings ?? Settings()

self.init(uncheckedBounds: (lower: Float(split[0])!, upper: Float(split[1])!))
}

public var rawValue: String {
return String(lowerBound) + "..." + String(upperBound)
}
}
18 changes: 9 additions & 9 deletions SnowfallApp/Common/SnowRenderer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class SnowRenderer: NSObject, MTKViewDelegate {
renderEncoder.setVertexBytes(&screenSize, length: MemoryLayout<SIMD2<Float>>.stride, index: 1)
renderEncoder.setFragmentBytes(&screenSize, length: MemoryLayout<SIMD2<Float>>.stride, index: 1)

renderEncoder.drawPrimitives(type: .point, vertexStart: 0, vertexCount: Settings.maxSnowflakes)
renderEncoder.drawPrimitives(type: .point, vertexStart: 0, vertexCount: Settings.shared.maxSnowflakes)
renderEncoder.endEncoding()

commandBuffer.present(drawable)
Expand All @@ -105,11 +105,11 @@ class SnowRenderer: NSObject, MTKViewDelegate {
let radius = influenceRadius
var activeWindowRect: CGRect?

if Settings.windowInteraction {
if Settings.shared.windowInteraction {
activeWindowRect = WindowInfo().getActiveWindowRect()
}

for i in 0..<Settings.maxSnowflakes {
for i in 0..<Settings.shared.maxSnowflakes {
var snowflake = snowflakes[i]
let dx = mousePosition.x - snowflake.position.x
let dy = mousePosition.y - snowflake.position.y
Expand All @@ -125,24 +125,24 @@ class SnowRenderer: NSObject, MTKViewDelegate {
}

snowflake.position.y += snowflake.velocity.y
snowflake.position.x += Float.random(in: 0.1...0.5) * Settings.windStrength
snowflake.position.x += Float.random(in: 0.1...0.5) * Settings.shared.windStrength

if Settings.windowInteraction,
if Settings.shared.windowInteraction,
let activeWindowRect,
activeWindowRect.contains(CGPoint(x: CGFloat(snowflake.position.x), y: CGFloat(snowflake.position.y))) {
snowflake.position.y = Float(activeWindowRect.origin.y)
snowflake.size -= Settings.semltingSpeed
snowflake.size -= Settings.shared.semltingSpeed
}

if (snowflake.position.y - snowflake.size > screenSize.y) || !(snowflake.size > Settings.snowflakeSizeRange.lowerBound - 1) {
if (snowflake.position.y - snowflake.size > screenSize.y) || !(snowflake.size > Settings.shared.snowflakeSizeRange.lowerBound - 1) {
snowflake.clear(for: screenSize)
}

snowflakes[i] = snowflake
}

let pointer = particleBuffer.contents().bindMemory(to: Snowflake.self, capacity: Settings.maxSnowflakes)
for i in 0..<Settings.maxSnowflakes {
let pointer = particleBuffer.contents().bindMemory(to: Snowflake.self, capacity: Settings.shared.maxSnowflakes)
for i in 0..<Settings.shared.maxSnowflakes {
pointer[i] = snowflakes[i]
}
}
Expand Down
10 changes: 5 additions & 5 deletions SnowfallApp/Common/Snowflake.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ struct Snowflake {
size = .size
color = .color(for: size)

position = simd_float2(Float.random(in: -(200 * Settings.windStrength)...screenSize.x), Float.random(in: 0...screenSize.y))
position = simd_float2(Float.random(in: -(200 * Settings.shared.windStrength)...screenSize.x), Float.random(in: 0...screenSize.y))
}

mutating func clear(for screenSize: simd_float2) {
Expand All @@ -21,27 +21,27 @@ struct Snowflake {
color = .color(for: size)

position.y = -size
position.x = Float.random(in: -(200 * Settings.windStrength)...screenSize.x)
position.x = Float.random(in: -(200 * Settings.shared.windStrength)...screenSize.x)
}
}

// MARK: Extensions

extension simd_float2 {
static var velocity: simd_float2 {
simd_float2(Float.random(in: -1...1), Float.random(in: Settings.snowflakeSpeedRange))
simd_float2(Float.random(in: -1...1), Float.random(in: Settings.shared.snowflakeSpeedRange))
}
}

extension Float {
static var size: Float {
Float.random(in: Settings.snowflakeSizeRange)
Float.random(in: Settings.shared.snowflakeSizeRange)
}
}

extension simd_float4 {
static func color(for size: Float) -> simd_float4 {
let normalizedSize = (size - Settings.snowflakeSizeRange.lowerBound) / (Settings.snowflakeSizeRange.upperBound - Settings.snowflakeSizeRange.lowerBound)
let normalizedSize = (size - Settings.shared.snowflakeSizeRange.lowerBound) / (Settings.shared.snowflakeSizeRange.upperBound - Settings.shared.snowflakeSizeRange.lowerBound)
let opacity = Swift.max(0.1, 1.0 - normalizedSize * 0.8)
return simd_float4(1.0, 1.0, 1.0, opacity)
}
Expand Down
4 changes: 4 additions & 0 deletions SnowfallApp/SnowfallApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import SwiftUI
struct SnowfallAppApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

init() {
Settings.load()
}

var body: some Scene {
WindowGroup {
SnowFallMetalView()
Expand Down

0 comments on commit 3d4b82a

Please sign in to comment.