does setup and draw function run parallel in processing - processing

Does the fileselected function in this code complete its execution even before while loop execution?
void setup()
{
size(800, 600);
selectInput("Select a file to process:", "fileSelected");
while(data==null)
{
delay(1000);
}
}
void fileselected()
{
*
*
*
*
}
How do I make the draw function wait until it receives the necessary arguments to run?

does setup and draw function run parallel in processing
No. First the setup() function is called and completes, then the draw() function is called 60 times per second.
does the fileselected function completes its execution even before while loop execution.
The fileSelected() function will be called when the user selects a file. You really shouldn't call the delay() function in a loop like that.
How do I make the draw function to wait until it receives the necessary arguments to run.
Something like this:
boolean fileLoaded = false;
void setup(){
size(800, 600);
selectInput("Select a file to process:", "fileSelected");
}
void fileSelected(File selection){
fileLoaded = true;
}
void draw(){
if(!fileLoaded){
//short-circuit and stop the function
return;
}
}
You could go a step further and use the noLoop() and loop() functions. More info can be found in the reference.

Related

Processing: running draw cycle into an independent thread

QUESTION
I've noticed that draw() cycle is interrupted by events elaboration.
In the following example the circle animation will stop at mouse click until the elaborating_function() ends.
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");
}
Of course, a simple solution to run the elaboration without stopping the animation could be to thread("elaborating_function");
But my question is: if it is possible to run the draw cycle into an independent thread instead?
SOLUTION
I've found a possible solution inverting my problem and creating an "independent cycle" parallel to the draw one. Within this cycle is possible to run any function and it will not interfere with the draw execution. Every event triggered by the user needs only to set a specific variable in order to activate (once or more time) the function within the cycle.
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");
}
As far as I know Processing has it's own AnimationThread.
Your proposed solution to thread elaborating_function() is great.
You could have a basic class that implements Runnable if you need a bit more control. With this thread running in parallel, Processing's main animation thread should run along side it just fine without pausing rendering.
This options sounds much simpler than trying to mess with Processing's AnimationThread and potentially have to deal with unexpected behaviour.
What is the actual goal you're trying achieve ?

How to wait in p5.js

I'm trying to create a program that does something, waits for a set amount of time does another thing, then waits again. However, what actually happens is the program waits at the beginning then does both things without any delay between them.
var start, current
function setup() {
createCanvas(500, 550);
}
function draw() {
background(220);
print('a');
wait(500);
print('b');
wait(500);
}
function wait(time)
{
start = millis()
do
{
current = millis();
}
while(current < start + time)
}
The draw() function is executed several times per seconds (around 60 times per second, see framerate in the doc). This is also what we call a "draw loop".
Your logic seems to be very sequential (do this, then wait and to that, then wait and do another thing...), and maybe you should consider an other flow for your program than the draw loop.
If you want animation, the easy answer would be to stick to the answer provided by Rabbid76.
(read and compare elapsed time millis every time the draw loop executes).
If you want one-time events (things that happen only once when a wanted duration is reached), you should look into Promises (or async-await functions), also known as asynchronicity.
This subject can be confusing for beginners, but is very important in javascript.
Here is an example:
(link with p5 editor)
// notice we are NOT using the draw() loop here
function setup()
{
createCanvas(400, 400);
background('tomato')
// try commenting-out one of these:
doScheduleThings();
doAsyncAwaitThings();
}
// you can wait for a Promise to return with the javascript 'then' keyword
// the function execution's is not stopped but each '.then(...)' schedules a function for when the Promise 'sleep(...)' is resolved
function doScheduleThings()
{
sleep(2000).then(function() {
fill('orange')
ellipse(30,30, 50, 50)
})
sleep(1000).then(function() {
fill('yellow')
ellipse(130,30, 50, 50)
})
}
// you can also wait for a Promise to return with an async-await function
// the function's execution is stopped while waiting for each Promise to resolve
async function doAsyncAwaitThings()
{
await sleep(4000)
fill('blue')
rect(200,200, 50, 50)
await sleep(1000)
fill('cyan')
rect(300,200, 50, 50)
}
// a custom 'sleep' or wait' function, that returns a Promise that resolves only after a timeout
function sleep(millisecondsDuration)
{
return new Promise((resolve) => {
setTimeout(resolve, millisecondsDuration);
})
}
You cannot wait in the draw callback. The canvas is just updated when after draw was executed. You must evaluate the time in draw:
function draw() {
background(220);
let ms = millis()
if (ms < 500) {
// [...]
}
else if (ms < 1000) {
// [...]
}
else {
// [...]
}
}
As mentioned, the problem in your attempt is that you're waiting inside the draw() loop. This doesn't work, because draw() is going to be called continually.
A simple way to do it is the following:
function setup() {
//...
}
let task_done = false;
let last_done = 0;
function draw() {
const delay = 1000 //ms
if(!task_done) {
/* do something */
doSomething();
task_done = true;
last_done = millis();
}
else {
if(millis() - last_done > delay) {
task_done = false;
}
}
}
function doSomething() {
//...
}
It only executes something every delay ms.

digitalRead() Arduino, will it wait for a key to be pressed?

This is my Arduino code:
void loop()
{
state=digitalRead(2);
if(state==HIGH)
{
update();
}
}
I want the function update() to be called if the button in pin2 is pressed.
Will 'state=digitalRead(2)' this statement wait for the key press? If no, what do you suggest?
Of course not. This function will return the current state of that pin immediately.
This code can replace all your code through your function loop()
void setup()
{
attachInterrupt(2, update, RISING);
}
void loop()
{
}
void update()
{
...
}
Try to create a while loop to wait for a button press:
while (!digitalRead(2)) {
delay(100);
}
So your script gets stuck in a loop and waits for a button press.

Processing 'It looks like you're mixing "active" and "static" modes.'

Processing keeps giving me this error when I run it even though it is just a print command. When I delete the comment block it works fine. Here's the code:
/*
float[] cortToPolar(int xcorr, int ycorr) {
float returns[] = new float[2];
returns[0]= degrees(tan(ycorr/xcorr));
returns[1]= sqrt(pow(xcorr,2)+pow(ycorr,2));
return returns;
}
float lawCos(int a, int b, int c) {
return degrees(
acos(
(pow(a,2)+pow(b,2)-pow(c,2))/
(2*a*b)
)
);
}
*/
print(0);
Why doesn't it like my comment?
Processing runs in two separate modes: static or active
Static mode simply means it's a list of instructions/calls to existing functions (e.g. draw a bunch of lines then exit)
Active mode uses the setup() and draw() calls and runs continuously (gets updated every 'frame').
Only in active mode you are allowed to define own functions like cortToPolar and lawCos (regardless of the fact they are commented - this could be a Processing editor bug).
Use the setup() call to print because using setup will bring Processing into active mode.
/*
float[] cortToPolar(int xcorr, int ycorr) {
float returns[] = new float[2];
returns[0]= degrees(tan(ycorr/xcorr));
returns[1]= sqrt(pow(xcorr,2)+pow(ycorr,2));
return returns;
}
float lawCos(int a, int b, int c) {
return degrees(
acos(
(pow(a,2)+pow(b,2)-pow(c,2))/
(2*a*b)
)
);
}
*/
void setup(){
print(0);
}
(Should you need to use active mode and control how draw() is called you can use noLoop() and loop().)
The message could be shown when the actual problem is a syntax error. I encountered this error with the following (silly) code:
boolean state = false;
setup() {
size(200, 800);
}
void draw() {
}
It is missing the 'void' modifier for the setup function. This is a syntax error (at least, it should be). But the Processing IDE gives you this "active vs. static" message instead.
So in this case, it should be void setup() { } rather than just setup() { }.

Can mousePressed be defined within a class?

I am trying to create a class called InputManager to handle mouse events. This requires that mousePressed be contained within the InputManager class.
like so
class InputManager{
void mousePressed(){
print(hit);
}
}
problem is, that doesn't work. mousePressed() only seems to work when it's outside the class.
How can I get these functions nicely contained in a class?
Try this:
in main sketch:
InputManager im;
void setup() {
im = new InputManager(this);
registerMethod("mouseEvent", im);
}
in InputManager Class:
class InputManager {
void mousePressed(MouseEvent e) {
// mousepressed handling code here...
}
void mouseEvent(MouseEvent e) {
switch(e.getAction()) {
case (MouseEvent.PRESS) :
mousePressed();
break;
case (MouseEvent.CLICK) :
mouseClicked();
break;
// other mouse events cases here...
}
}
}
Once you registered InputManger mouseEvent in PApplet you don't need to call it and it will be called each loop at the end of draw().
Most certainly, but you are responsible for ensuring it gets called:
interface P5EventClass {
void mousePressed();
void mouseMoved();
// ...
}
class InputManager implements P5EventClass {
// we MUST implement mousePressed, and any other interface method
void mousePressed() {
// do things here
}
}
// we're going to hand off all events to things in this list
ArrayList<P5EventClass> eventlisteners = new ArrayList<P5EventClass>();
void setup() {
// bind at least one input manager, but maybe more later on.
eventlisteners.add(new InputManager());
}
void draw() {
// ...
}
void mousePressed() {
// instead of handling input globally, we let
// the event handling obejct(s) take care of it
for(P5EventClass p5ec: eventlisteners) {
p5ec.mousePressed();
}
}
I would personally make it a bit tighter by also passing the event variables explicitly, so "void mousePressed(int x, int y);" in the interface and then calling "p5ec.mousePressed(mouseX, mouseY);" in the sketch body, simply because relying on globals rather than local variables makes your code prone to concurrency bugs.
The easiest way to do so would be:
class InputManager{
void mousePressed(){
print(hit);
}
}
InputManager im = new InputManager();
void setup() {
// ...
}
void draw() {
// ...
}
void mousePressed() {
im.mousePressed();
}
This should solve any problems you were having with variable scoping in your class.
Note: In the class, it doesn't even have to be named mousePressed, you can name it anything you wish, as long as you call it inside of the main mousePressed method.

Resources