Skip to content

Commit

Permalink
Merge pull request #14 from yuzawa-san/fps-adjust
Browse files Browse the repository at this point in the history
Adjust FPS on power source + make dims dynamic
  • Loading branch information
yuzawa-san authored Dec 23, 2022
2 parents 4d1219d + 354f6f5 commit 034a88b
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Polyhedra/Polyhedra.swift
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ struct Polyhedron: Codable {
color: NSColor?) -> ContiguousArray<CachedRendering> {
var renderedPolygons = [CachedRendering]()
// precompute all of the rotations
for degrees in 0 ..< 360 {
for degrees in 0 ..< PolyhedraFullLayer.degrees {
let effectiveColor = color ?? PolyhedraRegistry.colors[degrees]
let cachedRendering = generateCachedRendering(degrees: degrees, color: effectiveColor.cgColor,
radius: radius, lineWidth: lineWidth)
Expand Down
23 changes: 18 additions & 5 deletions Polyhedra/PolyhedraFullLayer.swift
Original file line number Diff line number Diff line change
@@ -1,23 +1,31 @@
import AppKit

class PolyhedraFullLayer: CALayer {
static let fpsSlow: Int = 24
static let fpsFast: Int = 48
static let rotationSeconds: Int = 15
static let degrees: Int = 360

private let polyhedraLayer: CALayer
private let cachedRenderings: ContiguousArray<CachedRendering>
private let radius: Int
private let maxX: Int
private let maxY: Int
private let framesPerDegree: Int
private var positionX: Int = .zero
private var positionY: Int = .zero
private var velocityX: Int = .zero
private var velocityY: Int = .zero
private var rotation: Int = .zero
private var frameNumber: Int = .zero

public init(size: CGSize, isPreview: Bool) {
public init(size: CGSize, fps: Int) {
let settings = PolyhedraSettings()
self.polyhedraLayer = CALayer()
self.polyhedraLayer.isOpaque = true
self.radius = isPreview ? 25 : 150
self.velocityX = isPreview ? 6 : 12
self.framesPerDegree = fps * PolyhedraFullLayer.rotationSeconds / PolyhedraFullLayer.degrees
self.radius = Int(min(size.width, size.height) * 0.15)
self.velocityX = max(1, radius / fps * 2)
self.velocityY = velocityX
// make sure polyhedron (2 * radius in width) does not got off screen
self.maxX = Int(size.width) - 2 * radius
Expand All @@ -34,7 +42,7 @@ class PolyhedraFullLayer: CALayer {
self.isOpaque = true
addSublayer(polyhedraLayer)
if settings.shouldShowPolyhedronName() {
let fontSize: CGFloat = isPreview ? 5 : 24
let fontSize: CGFloat = CGFloat(radius) * 0.15
// configure text
let font = NSFont.systemFont(ofSize: fontSize)
let textLayer = CATextLayer()
Expand Down Expand Up @@ -62,6 +70,7 @@ class PolyhedraFullLayer: CALayer {

func animateOneFrame() {
// update object position
let rotation = self.rotation
let rendering = cachedRenderings[rotation]
let boundingBox = rendering.boundingBox
var positionX = self.positionX
Expand All @@ -86,7 +95,11 @@ class PolyhedraFullLayer: CALayer {
}
positionY += velocityY
self.positionY = positionY
rotation = (rotation + 1) % 360
let frameNumber = (self.frameNumber + 1) % framesPerDegree
if frameNumber == 0 {
self.rotation = (rotation + 1) % PolyhedraFullLayer.degrees
}
self.frameNumber = frameNumber
CATransaction.begin()
CATransaction.setDisableActions(true)
polyhedraLayer.sublayers = rendering.layer
Expand Down
22 changes: 20 additions & 2 deletions Polyhedra/PolyhedraScreenSaverView.swift
Original file line number Diff line number Diff line change
@@ -1,17 +1,35 @@
import ScreenSaver
import Foundation
import IOKit.ps

class PolyhedraScreenSaverView: ScreenSaverView {
private lazy var sheetController = ConfigSheetController()
private var polyhedronScreenSaverLayer: PolyhedraFullLayer?

override init?(frame: NSRect, isPreview: Bool) {
super.init(frame: frame, isPreview: isPreview)
animationTimeInterval = 1.0 / 25
wantsLayer = true
}

// if we're on battery let's lower the FPS
static func calculateFramesPerSecond() -> Int {
let snapshot = IOPSCopyPowerSourcesInfo().takeRetainedValue()
let sources = IOPSCopyPowerSourcesList(snapshot).takeRetainedValue() as Array
for source in sources {
if let info = IOPSGetPowerSourceDescription(snapshot, source).takeUnretainedValue() as? [String: AnyObject],
let state = info[kIOPSPowerSourceStateKey] as? String {
if state == kIOPSBatteryPowerValue {
return PolyhedraFullLayer.fpsSlow
}
}
}
return PolyhedraFullLayer.fpsFast
}

override func startAnimation() {
let polyhedronScreenSaverLayer = PolyhedraFullLayer(size: frame.size, isPreview: isPreview)
let fps = PolyhedraScreenSaverView.calculateFramesPerSecond()
animationTimeInterval = 1.0 / Double(fps)
let polyhedronScreenSaverLayer = PolyhedraFullLayer(size: frame.size, fps: fps)
layer?.drawsAsynchronously = true
layer?.isOpaque = true
layer?.addSublayer(polyhedronScreenSaverLayer)
Expand Down

0 comments on commit 034a88b

Please sign in to comment.