I would like to know if there is any way to execute something with a short time without freeze the code

Hello,

I would like to know if there is any way to execute something after some time without using delay() because it’s freezing the code while using this delay.
If anyone can help me !!
Thanks :wink:

Hi @Benjamin21,

you can do something like this …

Cheers
— mnse

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

volatile color col = color(255);

void setup() {
  size(250, 250);
  textAlign(CENTER, CENTER);
  textSize(50);

  ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();    
  // Processing 4 can do
  // Runnable dummyTask = () -> {
  //    println("Hello from dummyTask :)");
  //    col = color(255, 0, 0);
  // };  

  // Processing 3 version
  Runnable dummyTask = new Runnable() {
    public void run() {
      println("Hello from dummyTask :)");
      col = color(255, 0, 0);
    }
  };
  // dummyTask will be triggered after 10 secs
  ses.schedule(dummyTask, 10, TimeUnit.SECONDS);
  println("Here we are without waiting ...");
}

void draw() {
  background(0);
  fill(col);
  text(millis()/1000, width/2, height/2);
}
2 Likes

Thanks a lot for your answer sir.

I will work on it.

It seems to be what I needed thanks again !

Cheers :slight_smile:

color(), along w/ any function that depends on it such as background(), fill(), stroke(), etc., is the most thread-unfriendly method in Processing!

If the color() from Executor by chance happens to be invoked at the same time as background() or fill() from draw() the color math result from both threads is compromised!

Easiest fix is to completely abandon color() and just stick w/ #RGB literals: col = #FF0000;

Otherwise each extra thread needs its own PGraphics so it’s safe to invoke method color() from it:

// https://Discourse.Processing.org/t/i-would-like-to-know-if-there-is-any-way-
// to-execute-something-with-a-short-time-without-freeze-the-code/40445/4

// (2023/Jan/04)

import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import java.lang.reflect.Method;

color colour = -1; // white

void setup() {
  size(200, 200);

  textAlign(CENTER, CENTER);
  textSize(0100);

  final Runnable dummyTask = new Runnable() {
    final PGraphics stub = createGraphics(1, 1);
    final Method colorMethod;

    {
      stub.beginDraw();
      stub.endDraw();

      try {
        colorMethod = PGraphics.class.getMethod(
          "color", int.class, int.class, int.class);

        println(colorMethod);
      }
      catch (final NoSuchMethodException e) {
        throw new RuntimeException(e);
      }
    }

    public void run() {
      println("Hello from dummyTask ;-)");

      //colour = #FF0000; // Easiest & most performant approach!

      //colour = stub.color(255, 0, 0); // Fails on P3! Maybe got fixed on P4?

      try {
        colour = (color) colorMethod.invoke(stub, 255, 0, 0); // red
      }
      catch (final ReflectiveOperationException e) {
        System.err.println(e);
      }

      println('#' + hex(colour, 6)); // #FF0000
    }
  };

  final ScheduledExecutorService executor = newSingleThreadScheduledExecutor();
  executor.schedule(dummyTask, 10, TimeUnit.SECONDS); // 10 seconds delay
}

void draw() {
  background(0); // black
  fill(colour); // either white or red
  text(millis()/1000, width >> 1, height >> 1); // running time in seconds
}
3 Likes

Hi @GoToLoop,

Thanks for digging deeper and work out more detail.

The usage of color was only for a quick demonstration in this case not the target solution. It should only show that the execution is delayed for a specific time without waiting …

Cheers
— mnse

1 Like

You can also just use a timer with millis() for this