我的屏幕保护程序是否使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,150);
  for (int x = 0; x < gaussianCounts.length;x++){
    rect(x*w,height-gaussianCounts[x],w-1,gaussianCounts[x]);
  }
  fill(0,150);
  for (int x = 0;x < monteCarloCounts.length;x++){
    rect(x*w,height-monteCarloCounts[x],monteCarloCounts[x]);
  }
  fill(255,150);
  for (int x = 0;x < invMonteCarloCounts.length;x++){
    rect(x*w,height-invMonteCarloCounts[x],invMonteCarloCounts[x]);
  }
  fill(255,150);
  for (int x = 0; x < randomCounts.length; x++){
    rect(x*w,height-randomCounts[x],randomCounts[x]);
  }
}
void mousepressed(){
  for (int x = 0; x < randomCounts.length; x++){
    randomCounts[x] = 0;
    gaussianCounts[x] = 0;
    monteCarloCounts[x] = 0;
    invMonteCarloCounts[x] = 0;
  }
}

再次,此代码可以正常工作。我试图快速地做基本上相同的事情(有点疯狂),并且XCode指出没有错误。但是,当我在“系统偏好设置”中安装“保护程序”时,即使是其他屏幕保护程序,预览也只是黑色并且无法正常运行,并且实际上无法运行该屏幕保护程序。它似乎卡在了某处,从而使其无法在引擎中实际运行。 这是我的快速代码

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,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,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,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,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()
    }

}

很抱歉,冗长的代码,我真的不知道我在做什么错。我从this tutorial复制了大部分脚本,效果很好。

解决方法

您必须在animateOneFrame中设置needsDisplay,如下所示:

override func animateOneFrame(){
    needsDisplay = true
}
,

此行

private var randomCounts: [Int] = [500]

不等于

randomCounts = new int[500];

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

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

一般来说,为了避免这种问题,您可以通过不在各处编写1...360而不是使用randomCounts.count来引用数组的长度来改进代码。同样,使用for n in 1...360之类的字词代替for (n,height) in monteCarloCounts.enumerated()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...