Zum Inhalt

macos/Sources/PerlinLiveWallpaper/PresetStore.swift

import Foundation

/// Loads the bundled preset JSONs in a fixed order. Falls back to a single
/// built-in preset if the resources are missing, so the app never starts empty.
final class PresetStore {
    let presets: [Preset]

    // Fixed display order; also guarantees presence (a missing file is skipped).
    private static let order = ["default", "lava", "aurora", "clouds", "terrain", "circuit", "marble", "composite", "nebula", "flow"]

    init() {
        let decoder = JSONDecoder()
        var loaded: [Preset] = []
        for name in PresetStore.order {
#if SWIFT_PACKAGE
            guard let url = Bundle.module.url(forResource: name, withExtension: "json", subdirectory: "presets"),
                  let data = try? Data(contentsOf: url) else { continue }
#else
            guard let url = Bundle.main.url(forResource: name, withExtension: "json"),
                  let data = try? Data(contentsOf: url) else { continue }
#endif
            do {
                loaded.append(try decoder.decode(Preset.self, from: data))
            } catch {
                FileHandle.standardError.write(Data("preset decode failed for \(name): \(error)\n".utf8))
            }
        }
        presets = loaded.isEmpty ? [PresetStore.fallback] : loaded
    }

    static let fallback = Preset(
        name: "default", width: 256, height: 256,
        scaleX: 0.011, scaleY: 0.011, scaleT: 0.15,
        octaves: 5, persistence: 0.62, lacunarity: 2.1, base: 0,
        colorMode: "gradient",
        gradient: [
            GradientStop(pos: 0.0, color: [68, 1, 84]),
            GradientStop(pos: 0.5, color: [33, 145, 140]),
            GradientStop(pos: 1.0, color: [253, 231, 37]),
        ],
        warpStrength: 0, warpScale: 1, posterizeSteps: nil,
        hsvHueShift: nil, hsvHueRange: nil, hsvSat: nil, hsvVal: nil,
        rgbMultiChannel: nil, rScale: nil, gScale: nil, bScale: nil,
        rInvert: nil, gInvert: nil, bInvert: nil,
        flowHueShift: nil, flowSat: nil, flowGain: nil, flowFloor: nil, flowEps: nil,
        layer2On: nil, layer2ScaleX: nil, layer2ScaleY: nil, layer2Octaves: nil,
        layer2Base: nil, layer2BlendMode: nil, layer2Mix: nil
    )
}