我的屏幕保护程序是否超载了Mac OSX Catalina屏幕保护程序引擎



我在处理过程中开发了一个我觉得很整洁的小程序。它设置一些rng,然后绘制每个rng的每个输出的计数。这是处理代码。我不认为这方面有任何问题,因为它在处理中运行良好:

int [] randomCounts;
int [] gaussianCounts;
int [] monteCarloCounts;
int [] invMonteCarloCounts;
void setup(){
size(1000,700);
randomCounts = new int[500];
gaussianCounts = new int[500];
monteCarloCounts = new int[500];
invMonteCarloCounts = new int[500];
}
float invMonteCarlo(){
while (true){
float r1 = random(1);
float r2 = random(1);
if (r2>r1){
return r1;
}
}
}
float monteCarlo(){
while (true){
float r1 = random(1);
float r2 = random(1);
if (r2<r1){
return r1;
}
}
}
void draw(){
background(255);
int randIndex = int(random(randomCounts.length));
int gaussIndex = int(randomGaussian()*20+250);
int monteIndex = int(monteCarlo()*monteCarloCounts.length);
int invMonteIndex = int(invMonteCarlo()*invMonteCarloCounts.length);
randomCounts[randIndex]++;
gaussianCounts[gaussIndex]++;
monteCarloCounts[monteIndex]++;
invMonteCarloCounts[invMonteIndex]++;

noStroke();
int w = width/randomCounts.length;
fill(0,255,0,150);
for (int x = 0; x < gaussianCounts.length;x++){
rect(x*w,height-gaussianCounts[x],w-1,gaussianCounts[x]);
}
fill(0,0,255,150);
for (int x = 0;x < monteCarloCounts.length;x++){
rect(x*w,height-monteCarloCounts[x],w-1,monteCarloCounts[x]);
}
fill(255,255,0,150);
for (int x = 0;x < invMonteCarloCounts.length;x++){
rect(x*w,height-invMonteCarloCounts[x],w-1,invMonteCarloCounts[x]);
}
fill(255,0,0,150);
for (int x = 0; x < randomCounts.length; x++){
rect(x*w,height-randomCounts[x],w-1,randomCounts[x]);
}
}
void mousePressed(){
for (int x = 0; x < randomCounts.length; x++){
randomCounts[x] = 0;
gaussianCounts[x] = 0;
monteCarloCounts[x] = 0;
invMonteCarloCounts[x] = 0;
}
}

同样,这个代码运行良好。我尝试在swift中做基本上相同的事情(这有点疯狂(,XCode没有指出错误。然而,当我在系统首选项中安装Saver时,预览只是黑色的,并且停止运行,甚至对于其他屏幕保护程序来说,实际上运行屏幕保护程序是不可能的。它似乎卡在了某个地方,这使它无法在发动机中实际运行。这是我的swift代码:

import Foundation
import ScreenSaver
import GameplayKit
class RandomGraphView: ScreenSaverView {
private var randomCounts: [Int] = [500]
private var gaussianCounts: [Int] = [500]
private var shuffledCounts: [Int] = [500]
private var monteCarloCounts: [Int] = [500]
private var invMonteCarloCounts: [Int] = [500]

private func MonteCarlo() -> Int{
while true {
let r1 = Int.random(in: 1...360)
let r2 = Int.random(in: 1...360)
if r2<r1 {
return r1
}
}
}
private func invMonteCarlo() -> Int{
while true {
let r1 = Int.random(in: 1...360)
let r2 = Int.random(in: 1...360)
if r2>r1 {
return r1
}
}
}
private func gaussian() -> Int{
let gaussianD6 = GKGaussianDistribution(lowestValue: 1, highestValue: 360)
return gaussianD6.nextInt()
}
private func shuffled() -> Int{
let shuffledD6 = GKShuffledDistribution(lowestValue: 1, highestValue: 360)
return shuffledD6.nextInt()
}
private func pullNumbers(){
let randIndex = Int.random(in: 1...360)
let gaussIndex = gaussian()
let shuffIndex = shuffled()
let monteCarloIndex = MonteCarlo()
let invMonteCarloIndex = invMonteCarlo()
randomCounts[randIndex]+=1
gaussianCounts[gaussIndex]+=1
shuffledCounts[shuffIndex]+=1
monteCarloCounts[monteCarloIndex]+=1
invMonteCarloCounts[invMonteCarloIndex]+=1
}
private func drawRandomBars(){
for n in 1...360{
let countBarRect = NSRect(x:(n-1)*4,y: 900, width:4, height: randomCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.red.setFill()
countBar.fill()
}
}

private func drawGaussianBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: gaussianCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.green.setFill()
countBar.fill()
}
}

private func drawShuffledBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: shuffledCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.systemBrown.setFill()
countBar.fill()
}
}

private func drawMonteCarloBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: monteCarloCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.magenta.setFill()
countBar.fill()
}
}

private func drawInverseMonteCarloBars(){
for n in 1...360{
let countBarRect = NSRect(x: (n-1)*4, y: 900, width: 4, height: invMonteCarloCounts[n])
let countBar = NSBezierPath(rect: countBarRect)
NSColor.systemIndigo.setFill()
countBar.fill()
}
}
private func drawBackground(_ color:NSColor){
let background = NSBezierPath(rect: bounds)
color.setFill()
background.fill()
}
override init?(frame: NSRect, isPreview: Bool){
super.init(frame: frame, isPreview: isPreview)
}
@available(*, unavailable)
required init?(coder decoder: NSCoder){
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: NSRect){
drawBackground(.white)
pullNumbers()
drawRandomBars()
drawGaussianBars()
drawShuffledBars()
drawMonteCarloBars()
drawInverseMonteCarloBars()
}

override func animateOneFrame(){
super.animateOneFrame()
}
}

抱歉代码太长了,我真的不知道自己做错了什么。我从本教程中复制了我的大部分脚本,它非常有效。

您必须设置需要在animateOneFrame中显示,如下所示:

override func animateOneFrame(){
needsDisplay = true
}

此行

private var randomCounts: [Int] = [500]

不等同于

randomCounts = new int[500];

前者创建一个内部只有一个数字500的数组,而后者创建一个500个整数的数组(我不是处理/Java专家,但我认为它们初始化为0(。因此,当randIndexgaussIndex等大于0时,您的程序将崩溃,因为索引将超出范围。

相反,您可能希望使用init(重复:count:(:private var randomCounts: [Int] = Array(repeating: 0, count: 500)

一般来说,为了避免这种问题,您可以改进代码,方法是不到处写1...360,而是使用randomCounts.count来引用数组的长度。类似地,使用类似for (n, height) in monteCarloCounts.enumerated()的内容来代替for n in 1...360

最新更新