Не перегружает ли моя заставка движок экранной заставки Mac OSX Catalina?

#swift #macos #screensaver

#swift #macos #заставка

Вопрос:

Я разработал то, что, по моему мнению, было аккуратной маленькой программой для обработки. Он настраивает некоторые ГСЧ, а затем отображает количество выходных данных каждого гсч. Вот код обработки. Я не думаю, что есть какие-либо проблемы с этой стороны, потому что она отлично работает при обработке:

 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 не указывает на ошибки. Однако, когда я устанавливаю заставку в системных настройках, предварительный просмотр становится просто черным и перестает функционировать даже для других заставок, и фактически запуск заставки невозможен. Кажется, что он где-то застрял, что не позволяет ему фактически работать в движке.
Вот мой код 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()
    }

}

  

Извините за длинный код, я действительно понятия не имею, что я делаю не так. Я скопировал большую часть своих сценариев из этого руководства, которое работает отлично.

Ответ №1:

Вы должны установить needsDisplay в animateOneFrame, например:

 override func animateOneFrame(){
    needsDisplay = true
}
  

Ответ №2:

Эта строка

 private var randomCounts: [Int] = [500]
  

не эквивалентно

 randomCounts = new int[500];
  

Первый создает массив с одним числом 500 внутри, тогда как последний создает массив из 500 целых чисел (я не специалист по обработке / Java, но я предполагаю, что они инициализированы в 0). Таким образом, ваша программа будет аварийно завершать работу, когда randIndex , gaussIndex , и т.д. больше 0, потому что индекс будет вне пределов.

Вместо этого вы, вероятно, хотели использовать init(повторение: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() .

Комментарии:

1. Спасибо за вашу помощь. Я немного разобрался с проблемой с массивами, прежде чем увидел ваш ответ, так что это больше не сбой, но он все еще не отображается.

2. Вам следует отредактировать свой вопрос, включив в него обновленный код и больше информации о том, что вы пробовали для отладки, иначе трудно помочь с небольшим количеством информации.