#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) Хорошая работа!