"Variable in variable"/putting a variable in the name behind void / calling methods by name

Hey everyone,

Does anyone know how to put a variable in the name behind void, also does the method work with regular variables, not implementing an array?
an example to explain this question:

int Mode=0;
void draw(){
  Test(); //How to make it go to Test 1, implementing Mode inside "Test", without using if/case commands?
}
void Test1(){
  Mode=2;

}
void Test2(){
  Mode=4;
}
void Test3(){
  Mode=1;
}
void Test4(){
  Mode=3;
}
//etc.

I personally believe using variables is faster than using if expressions, but I can’t find a way to make it practical funtioning! Could anyone help me?

Thanks in advance!

1 Like

May be wrong but I dont think this isn’t possible. To my understanding all your methods, void or otherwise need to be defined before you start the sketch otherwise the interpreter/compiler won’t know what to do.

however you can call a method using a variable name.

1 Like

It looks a bit verbose, but here an example:

import java.lang.reflect.Method;

// we will store the method to call in the variable method
Method method;

void setup() {
  size(400, 400);
  // when the program starts set the method you want called
  setMethod("DrawCircle");
}
// this function sets the method by it's name as a String
void setMethod(String name) {
  try {    
    method = this.getClass().getDeclaredMethod(name);
  } 
  catch(Exception e) {
    e.printStackTrace();
  }
}
// here we try to call the Method method
void draw() {
  try {
    method.invoke(this);
  } 
  catch(Exception e) {
    print("err.");
  }
  
  // set the method to be called to a new one
  // on frame 150. You could do it on key press,
  // on mouse press, or when something else happens
  if(frameCount == 150) {
    setMethod("DrawRect");
  }
}
void DrawCircle() {
  fill(random(255));
  ellipse(random(width), random(height), 50, 50);
}
void DrawRect() {
  fill(random(255), random(255), random(255));
  rect(random(width), random(height), 50, 5);
}

The program draws circles, then switches to rectangles at frame 150. Notice that the call never changes. It’s always method.invoke(this);.

2020-01-07-181512_400x400_scrot

ps. I’m not sure this is any faster than a switch/case. Maybe it depends on how many options you have in the switch. But compilers, the java runtime and the CPU are smart and do a lot of optimizations, so even an if/else looks not ideal it may be very fast. I wouldn’t do this just for optimizing, specially without measuring if it has any positive effect.

1 Like

You are talking about is calling methods by name and the suggestions so far use Java Reflection - this is generally much slower than a switch statement.

Sorry you are wrong here.
Either you

  1. select action by variable value
  2. select action by method name

either way you need to perform a selection e.g. if, switch statements or a hashmap with reflection

1 Like

When working in Idea I’ve used something like this:

Runnable method;

void setup() {
  size(400, 400);
  method = this::DrawCircle;
}
void draw() {

  method.run();
  
  if(frameCount == 150) {
    method = this::DrawRect;
  }
}
void DrawCircle() {
  fill(random(255));
  ellipse(random(width), random(height), 50, 50);
}
void DrawRect() {
  fill(random(255), random(255), random(255));
  rect(random(width), random(height), 50, 5);
}

which doesn’t work in the PDE because it requires Java 1.8 or higher.

Do you think that’s also slower? (no time to test atm)

I have no idea, I assume it is using the Kotlin language which I have not used myself. I doubt very much whether any difference is significant even it it could be measured accurately.

Runnable is actually there since Java 7. I use it as a simple way to store callbacks. For instance

myButton.setCallback(this::changeColor);

and inside button:

void setCallback(Runnable callback) { 
  // store callback locally for later invocation using theCallback.run()
}

ps. sorry for going off-topic!

Java can access its members by String using an advanced technique called reflection:

But it’s reasonably a bit slower compared to normal vanilla access though.

BtW, Processing got a method called method() which does the whole reflection thing internally so we can invoke void top methods by String very easily:

Take a look at this sketch example from the link below:

We can also watch it running online from this link:

In that sketch, top methods page0(), page1() & page2() are selected by this very simple statement call: method("page" + page);.

1 Like

Interesting :slight_smile:

method() makes it super simple, although it’s undocumented which means it could potentially be removed. But then you wrote that 6 years ago and it’s still there :slight_smile:

If they remove method(), they’d also need to remove thread(), which invokes method() internally! :stuck_out_tongue: