Triggering events with certain delays without interrupting the program flow

edited November 2014 in How To...

Hi there, Anyone has an idea on how do I trigger events with a certain delay while the rest of the program continues running?

I have a event (beat) triggered at certain intervals with the help of the Clock class of the the beads library. At each of this event (beat) I trigger some new events with certain small delays. For instance the beat comes every second and should trigger 6 short events 50ms apart. The problem is that the "short" delays add to the "long" delay. So the main timer (the one second interval) is affected by the 6 50ms delay, which means the main timer event (beat) would be then 1,3seonds apart.

Is there any way how I can implement the short delay without affecting the main timer?

Thank you

Answers

  • edited May 2014 Answer ✓

    For starters, I've got this thread and this example below:

    http://forum.processing.org/two/discussion/1725/millis-and-timer

    /** 
     * TimerTask (v1.3)
     * by GoToLoop (2013/Dec)
     * 
     * forum.processing.org/two/discussion/1725/millis-and-timer
     */
    
    import java.util.Timer;
    import java.util.TimerTask;
    
    final Timer t = new Timer();
    boolean hasFinished = true;
    
    void draw() {
      if (hasFinished) {
        final float waitTime = random(10);
        createScheduleTimer(waitTime);
    
        println("\n\nTimer scheduled for "
          + nf(waitTime, 0, 2) + " secs.\n");
      }
    
      if ((frameCount & 0xF) == 0)   print('.');
    }
    
    void createScheduleTimer(final float sec) {
      hasFinished = false;
    
      t.schedule(new TimerTask() {
        public void run() {
          print(" " + nf(sec, 0, 2));
          hasFinished = true;
        }
      }
      , (long) (sec*1e3));
    }
    
  • edited May 2014

    Thanks for the fast reply. This pretty much answered my question. But I have one more problem. I need a couple of timer, so I'm using a for loop to create all the tasks. But the task should depend on the index i of the for loop. But as the index i is a non final variable, I can't really use the index i in the run() function. It looks like this:

          for(int i=0;i < 6; i++){
            t.schedule(new TimerTask() {
              public void run() {
                call_a_function_which_depends_on_the_index(i);
              }
            }
            , (long) (10*i));
    }
    

    Is there a way to "finalize" the i by creating a new final variable?

    Thanks

  • edited May 2014

    Is there a way to "finalize" the i by creating a new final variable?

    Surprisingly there is! Merely declare a final variable inside the loop block.
    Then assign the current iterator value to it! :ar!

    for (int i = 0; i != 6;) {
      final int ii = i++;
    
      t.schedule(new TimerTask() {
        public void run() {
          myClosureTimedFunction(ii);
        }
      }
      , 10*ii);
    }
    
  • Just for amusement, here's my 1st clunky attempt before realizing a mere final variable would do it! :O)
    I've extended the TimerTask abstract class as TimerTasked.
    The new constructor accepted a parameter as id for the instance:

    void createScheduleTimer(float sec) {
      hasFinished = false;
    
      t.schedule(new TimerTasked(sec) {
        public void run() {
          hasFinished = true;
          print(nf(id, 0, 2));
        }
      }
      , (long) (sec*1e3));
    }
    
    abstract class TimerTasked extends TimerTask {
      final float id;
    
      TimerTasked(float num) {
        id = num;
      }
    }
    
  • edited May 2014

    P.S.: Bumped my original v1.22 to v1.3! Now it declares parameter sec as final. And accesses it inside run()! \m/

    void createScheduleTimer(final float sec) {
      hasFinished = false;
    
      t.schedule(new TimerTask() {
        public void run() {
          print(" " + nf(sec, 0, 2));
          hasFinished = true;
        }
      }
      , (long) (sec*1e3));
    }
    
Sign In or Register to comment.