static variable equivalent in processing

When programming in the arduino IDE i find it very useful being abe to create static variables. I can use them to create variables which are only changed when i tell them to be instead of repeatedly throughout the loop. for example

{
  static long timer = millis();
  if (millis() - timer > 1000) {
    timer = millis();
    println("hithere");
  }
}

if i do this within the loop without using static then the timer is constantly updated and doesnt hold its time. is there an equivalent in Processing as this approach does not seem to work....

Thanks!

Tagged:

Answers

  • I doubt this will work in arduino as you advertise it. If you define your variables within the loop, then they will always be created every time the "definition" line (Line 2 in your code) is encountered.

    Maybe these next approaches do what you want?

    TRY #1

    int timer;
    void setup(){   timer=millis();}
    void draw(){  println("A timer that will never change: "+ timer);}
    

    TRY #2

    int timer;
    void setup(){ mousePressed();  }
    void draw(){  println("A timer that changes with a mouse event: "+ timer);}
    void mousePressed(){timer=millis();}
    

    If you provide a better example, then it will clarify your question.

    Kf

  • Unfortunately neither Java nor JS (although there's a proposal for it for the latter) have static local variables. :o3

    A static local variable is created & initialized only once, when its function is invoked for the 1st time.

    When its function finishes, the current value stored in the static local variable is retained! :)>-

    So when its function is eventually re-invoked, it remembers its last value! \m/

  • edited June 2017

    Even though Java doesn't have such C feature, you can simply use a private field in its place. :ar!

    It's not locally scoped as an actual static local variable (it can be accessed by all methods within its class), but it works nonetheless: :-\"

    public class StaticLocalVarHack {
      public static final int TIMER = 1000;
      private int timer = millis();
    
      public boolean checkMillis() {
        if (millis() - timer >= TIMER) {
          timer = millis();
          println("Hit Here!");
          return true;
        }
    
        return false;
      }
    }
    
  • edited June 2017

    However there's a subtle bug in the "hack" solution above! :-SS
    Field timer is initialized when its class is instantiated, not when method checkMillis() is 1st called!

    For the absolutely majority of cases, it doesn't matter whether a variable is initialized earlier or later.
    However, given timer receives the current time in milliseconds, in this case it does matter when that happens!

    Check this example below to see that bug happening: #-o

    // forum.processing.org/two/discussion/22874/
    // static-variable-equivalent-in-processing#Item_4
    
    // GoToLoop (2017-Jun-02)
    
    void setup() {
      StaticLocalVar t = new StaticLocalVar();
      delay(StaticLocalVar.TIMER);
      t.checkMillis();
      exit();
    }
    
    public class StaticLocalVar {
      public static final int TIMER = 1000;
      private int timer = millis();
    
      public boolean checkMillis() {
        if (millis() - timer >= TIMER) {
          timer = millis();
          println("Hit Here!");
          return true;
        }
    
        return false;
      }
    }
    

    B/c there was a delay() of TIMER between the moment the class is instantiated and when checkMillis() is 1st invoked, we see "Hit Here!" printed on console. @-)

  • edited June 2017

    In order to correct that, we need to move timer initialization to method checkMillis(), and check whether that initialization happened all the time: :(

    // forum.processing.org/two/discussion/22874/
    // static-variable-equivalent-in-processing#Item_5
    
    // GoToLoop (2017-Jun-02)
    
    void setup() {
      StaticLocalVar t = new StaticLocalVar();
      delay(StaticLocalVar.TIMER);
      t.checkMillis();
      exit();
    }
    
    public class StaticLocalVar {
      public static final int TIMER = 1000;
      private int timer;
    
      public boolean checkMillis() {
        if (timer == 0)  timer = millis();
    
        if (millis() - timer >= TIMER) {
          timer = millis();
          println("Hit Here!");
          return true;
        }
    
        return false;
      }
    }
    

    Indeed, not as good as an actual static local variable as in C! 8-X

  • damn, this all looks rather complicated, i think i need my morning caffeine to kick in! Thanks very much for such a detailed reply goToLoop, its very much appreciated. Would it be possible to create a 'library' which allowed the use of a declaration which causes variables to be treated in the same was as a static one does in arduino? i love the simplicity of it and it works so well for making timed events quickly an easily!

  • edited June 2017

    Without a larger code context or a sample sketch I am having trouble understanding what you are trying to do.

    Logically, starting a time is one thing, ending it is another. Why are you trying to include a start-the-timer line that runs every time your timer loops? It works fine without the static line, and is less code:

    int timer;
    void setup() {
      timer = millis();
    }
    void draw() {
      if (millis() - timer > 1000) {
        timer = millis();
        println("hithere");
      }
    }
    

    Or, for external control of a timer that isn't constantly self-restarting:

    int timer;
    boolean running;
    void draw() {
      if (running && millis() - timer > 1000) {
        running = false;
        println("hithere");
      }
    }
    void keyPressed() {
      timer = millis();
      running = true;
    }
    
  • Logically, starting a time is one thing, ending it is another. Why are you trying to include a start-the-timer line that runs every time your timer loops? It works fine without the static line, and is less code:

    its all about it being self contained. once the program starts getting big (as mine is) it becomes tedious to have to declare the timer variables globally under new names. much nicer to be able to do it with a static variable. the name can stay the same and it simply works. but it appears that it aint possible lie that in java which is no problem, just suprising is all. thanks!

Sign In or Register to comment.