Обработка: запуск цикла рисования в независимый поток

#processing #java-threads

Вопрос:

вопрос

Я заметил, что draw() цикл прерывается развитием событий. В следующем примере анимация круга будет останавливаться при щелчке мыши до elaborating_function() конца.

 void setup(){
  
  size(800, 600);
  background(#818B95);
  frameRate(30);
}

void draw(){  
  
    background(#818B95);  
    
    //simple animation 
    fill(0,116,217);  
    circle(circle_x, 200, 50);
    
    circle_x  = animation_speed;
    if(circle_x>800){ circle_x = 0; }
}

void mouseClicked() {
  
  elaborating_function();
}

void elaborating_function(){
  println("elaboration start");
  delay(1000);
  println("elaboration end");
}
 

Конечно, простым решением для запуска разработки без остановки анимации может быть thread("elaborating_function");

Но мой вопрос в следующем: можно ли вместо этого запустить цикл рисования в независимый поток?

решение

Я нашел возможное решение, инвертирующее мою проблему и создающее «независимый цикл«, параллельный draw первому. В рамках этого цикла можно запустить любую функцию, и это не будет мешать выполнению розыгрыша. Каждое событие, инициируемое пользователем, должно только задать определенную переменную, чтобы активировать (один или несколько раз) функцию в цикле.

 int circle_x = 0;
int animation_speed = 5;

boolean call_elaborating_function = false;

void setup(){
  
  size(800, 600);
  background(#818B95);
  frameRate(30);
  
  IndependentCycle independentCycle = new IndependentCycle();
  independentCycle.setFrequency(1);
  new Thread(independentCycle).start();
}

void draw(){  
  
    background(#818B95);  
    
    //simple animation 
    fill(0,116,217);  
    circle(circle_x, 200, 50);
    
    circle_x  = animation_speed;
    if(circle_x>800){ circle_x = 0; }
}

public class IndependentCycle implements Runnable{
  
  private int frequency; //execution per seconds
  
  public IndependentCycle(){
    
    frequency = 0;
  }
  
  public void setFrequency(int frequency){
    this.frequency = 1000/frequency;
    println(this.frequency);
  }
  
  public void run(){
    
    while(true){
      print(".");
      delay(this.frequency);
          
      //DO STUFF HERE
      //WITH IF EVENT == ture IN ORDER TO RUN JUST ONCE !!
      if(call_elaborating_function){
        call_elaborating_function = false;
        elaborating_function();
      }
    }
  }
}

void mouseClicked() {
  
  call_elaborating_function = true;
}

void elaborating_function(){
  println("elaboration start");
  delay(1000);
  println("elaboration end");
}
 

Ответ №1:

Насколько я знаю, обработка имеет свой собственный поток анимации.

Ваше предлагаемое решение для потока elaborating_function() великолепно. У вас может быть базовый класс, который implements Runnable , если вам нужно немного больше контроля. При параллельном выполнении этого потока основной поток анимации обработки должен работать параллельно с ним без остановки рендеринга.

Этот вариант звучит намного проще, чем пытаться возиться с обработкой AnimationThread и, возможно, иметь дело с неожиданным поведением. Какова реальная цель, которую вы пытаетесь достичь ?

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

1. Я попытался реализовать выполняемый класс для запуска моей функции разработки (), как вы предложили, но он ведет себя так же, прерывая цикл рисования. Я полагаю, что это связано с тем, как событие пользователя вызывает некоторые прерывания в ходе выполнения программы. В любом случае, я решил проблему, запустив другой независимый цикл потоков и оставив события единственной задачей для обновления логической переменной-триггера для действий в этом цикле. Это немного запутанно, но работает.

2. Это звучит как разумное решение (использование логического значения для «отмены» состояния для запуска функции). (Одна незначительная вещь, на которую я хотел бы обратить внимание, заключается в следующем: frequency = 0; . Возможно, вам понадобится другое значение по умолчанию, чтобы избежать деления на ноль в случае случайного вызова экземпляра без установки частоты > 0) Хорошая работа!